1
0
Fork 0
mirror of https://github.com/graphhopper/jsprit.git synced 2020-01-24 07:45:05 +01:00

relax API

This commit is contained in:
Stefan Schroeder 2013-10-23 18:08:35 +02:00
parent fb78d60a36
commit b991aac12e
65 changed files with 294 additions and 689 deletions

View file

@ -50,6 +50,6 @@ public interface ActivityInsertionCostsCalculator {
}
public ActivityInsertionCosts calculate(InsertionContext iContext, TourActivity prevAct, TourActivity nextAct, TourActivity newAct, double depTimeAtPrevAct);
public ActivityInsertionCosts getCosts(InsertionContext iContext, TourActivity prevAct, TourActivity nextAct, TourActivity newAct, double depTimeAtPrevAct);
}

View file

@ -78,7 +78,7 @@ final class BestInsertion implements InsertionStrategy{
private Inserter inserter;
private JobInsertionCalculator bestInsertionCostCalculator;
private JobInsertionCostsCalculator bestInsertionCostCalculator;
private boolean minVehiclesFirst = false;
@ -86,7 +86,7 @@ final class BestInsertion implements InsertionStrategy{
this.random = random;
}
public BestInsertion(JobInsertionCalculator jobInsertionCalculator) {
public BestInsertion(JobInsertionCostsCalculator jobInsertionCalculator) {
super();
this.insertionsListeners = new InsertionListeners();
inserter = new Inserter(insertionsListeners);
@ -108,7 +108,7 @@ final class BestInsertion implements InsertionStrategy{
Insertion bestInsertion = null;
double bestInsertionCost = Double.MAX_VALUE;
for(VehicleRoute vehicleRoute : vehicleRoutes){
InsertionData iData = bestInsertionCostCalculator.calculate(vehicleRoute, unassignedJob, NO_NEW_VEHICLE_YET, NO_NEW_DEPARTURE_TIME_YET, NO_NEW_DRIVER_YET, bestInsertionCost);
InsertionData iData = bestInsertionCostCalculator.getInsertionData(vehicleRoute, unassignedJob, NO_NEW_VEHICLE_YET, NO_NEW_DEPARTURE_TIME_YET, NO_NEW_DRIVER_YET, bestInsertionCost);
if(iData instanceof NoInsertionFound) {
continue;
}
@ -119,7 +119,7 @@ final class BestInsertion implements InsertionStrategy{
}
if(!minVehiclesFirst){
VehicleRoute newRoute = VehicleRoute.emptyRoute();
InsertionData newIData = bestInsertionCostCalculator.calculate(newRoute, unassignedJob, NO_NEW_VEHICLE_YET, NO_NEW_DEPARTURE_TIME_YET, NO_NEW_DRIVER_YET, bestInsertionCost);
InsertionData newIData = bestInsertionCostCalculator.getInsertionData(newRoute, unassignedJob, NO_NEW_VEHICLE_YET, NO_NEW_DEPARTURE_TIME_YET, NO_NEW_DRIVER_YET, bestInsertionCost);
if(newIData.getInsertionCost() < bestInsertionCost){
bestInsertion = new Insertion(newRoute,newIData);
bestInsertionCost = newIData.getInsertionCost();
@ -128,7 +128,7 @@ final class BestInsertion implements InsertionStrategy{
}
if(bestInsertion == null){
VehicleRoute newRoute = VehicleRoute.emptyRoute();
InsertionData bestI = bestInsertionCostCalculator.calculate(newRoute, unassignedJob, NO_NEW_VEHICLE_YET, NO_NEW_DEPARTURE_TIME_YET, NO_NEW_DRIVER_YET, Double.MAX_VALUE);
InsertionData bestI = bestInsertionCostCalculator.getInsertionData(newRoute, unassignedJob, NO_NEW_VEHICLE_YET, NO_NEW_DEPARTURE_TIME_YET, NO_NEW_DRIVER_YET, Double.MAX_VALUE);
if(bestI instanceof InsertionData.NoInsertionFound){
throw new IllegalStateException(getErrorMsg(unassignedJob));
}

View file

@ -7,6 +7,7 @@ import basics.VehicleRoutingProblem;
import basics.VehicleRoutingProblem.Constraint;
import basics.algo.InsertionListener;
import basics.algo.VehicleRoutingAlgorithmListeners.PrioritizedVRAListener;
import basics.route.VehicleFleetManager;
public class BestInsertionBuilder implements InsertionStrategyBuilder{
@ -25,6 +26,10 @@ public class BestInsertionBuilder implements InsertionStrategyBuilder{
private boolean considerFixedCosts = false;
private ActivityInsertionCostsCalculator actInsertionCostsCalculator = null;
private int forwaredLooking;
private int memory;
public BestInsertionBuilder(VehicleRoutingProblem vrp, VehicleFleetManager vehicleFleetManager, StateManager stateManager) {
super();
@ -75,7 +80,11 @@ public class BestInsertionBuilder implements InsertionStrategyBuilder{
return this;
};
//public void setRouteLevel(int forwardLooking, int memory){};
public void setRouteLevel(int forwardLooking, int memory){
local = false;
this.forwaredLooking = forwardLooking;
this.memory = memory;
};
public BestInsertionBuilder setLocalLevel(){
local = true;
@ -101,11 +110,8 @@ public class BestInsertionBuilder implements InsertionStrategyBuilder{
calcBuilder.setLocalLevel();
}
else {
//add CostsUpdater
calcBuilder.setRouteLevel(forwaredLooking, memory);
}
// calcBuilder.setRouteLevel(forwardLooking, memory);
// }
calcBuilder.setConstraintManager(constraintManager);
calcBuilder.setStates(stateManager);
calcBuilder.setVehicleRoutingProblem(vrp);
@ -114,7 +120,7 @@ public class BestInsertionBuilder implements InsertionStrategyBuilder{
if(considerFixedCosts) {
calcBuilder.considerFixedCosts(weightOfFixedCosts);
}
JobInsertionCalculator jobInsertions = calcBuilder.build();
JobInsertionCostsCalculator jobInsertions = calcBuilder.build();
BestInsertion bestInsertion = new BestInsertion(jobInsertions);
for(InsertionListener l : iListeners) bestInsertion.addListener(l);
return bestInsertion;

View file

@ -0,0 +1,19 @@
package algorithms;
import basics.VehicleRoutingProblem;
public class BestInsertionStrategyFactory implements InsertionStrategyFactory{
private JobInsertionCostsCalculator jobInsertionCalculator;
public BestInsertionStrategyFactory(JobInsertionCostsCalculator jobInsertionCalculator) {
super();
this.jobInsertionCalculator = jobInsertionCalculator;
}
@Override
public InsertionStrategy createStrategy(VehicleRoutingProblem vrp) {
return new BestInsertion(jobInsertionCalculator);
}
}

View file

@ -27,11 +27,11 @@ import basics.route.Driver;
import basics.route.Vehicle;
import basics.route.VehicleRoute;
class CalculatesServiceInsertionWithTimeScheduling implements JobInsertionCalculator{
class CalculatesServiceInsertionWithTimeScheduling implements JobInsertionCostsCalculator{
private static Logger log = Logger.getLogger(CalculatesServiceInsertionWithTimeScheduling.class);
private JobInsertionCalculator jic;
private JobInsertionCostsCalculator jic;
private Random random = new Random();
@ -39,7 +39,7 @@ class CalculatesServiceInsertionWithTimeScheduling implements JobInsertionCalcul
private double timeSlice = 900.0;
public CalculatesServiceInsertionWithTimeScheduling(JobInsertionCalculator jic, double timeSlice, int neighbors) {
public CalculatesServiceInsertionWithTimeScheduling(JobInsertionCostsCalculator jic, double timeSlice, int neighbors) {
super();
this.jic = jic;
this.timeSlice = timeSlice;
@ -53,7 +53,7 @@ class CalculatesServiceInsertionWithTimeScheduling implements JobInsertionCalcul
}
@Override
public InsertionData calculate(VehicleRoute currentRoute, Job jobToInsert, Vehicle newVehicle, double newVehicleDepartureTime, Driver newDriver, double bestKnownScore) {
public InsertionData getInsertionData(VehicleRoute currentRoute, Job jobToInsert, Vehicle newVehicle, double newVehicleDepartureTime, Driver newDriver, double bestKnownScore) {
List<Double> vehicleDepartureTimes = new ArrayList<Double>();
double currentStart;
if(currentRoute.getStart() == null){
@ -74,7 +74,7 @@ class CalculatesServiceInsertionWithTimeScheduling implements JobInsertionCalcul
InsertionData bestIData = null;
for(Double departureTime : vehicleDepartureTimes){
InsertionData iData = jic.calculate(currentRoute, jobToInsert, newVehicle, departureTime, newDriver, bestKnownScore);
InsertionData iData = jic.getInsertionData(currentRoute, jobToInsert, newVehicle, departureTime, newDriver, bestKnownScore);
if(bestIData == null) bestIData = iData;
else if(iData.getInsertionCost() < bestIData.getInsertionCost()){
iData.setVehicleDepartureTime(departureTime);

View file

@ -22,6 +22,7 @@ import java.util.List;
import basics.VehicleRoutingProblem;
import basics.algo.InsertionListener;
import basics.algo.VehicleRoutingAlgorithmListeners.PrioritizedVRAListener;
import basics.route.VehicleFleetManager;
@ -29,16 +30,16 @@ class CalculatorBuilder {
private static class CalculatorPlusListeners {
private JobInsertionCalculator calculator;
private JobInsertionCostsCalculator calculator;
public JobInsertionCalculator getCalculator() {
public JobInsertionCostsCalculator getCalculator() {
return calculator;
}
private List<PrioritizedVRAListener> algorithmListener = new ArrayList<PrioritizedVRAListener>();
private List<InsertionListener> insertionListener = new ArrayList<InsertionListener>();
public CalculatorPlusListeners(JobInsertionCalculator calculator) {
public CalculatorPlusListeners(JobInsertionCostsCalculator calculator) {
super();
this.calculator = calculator;
}
@ -178,11 +179,11 @@ class CalculatorBuilder {
* @return jobInsertionCalculator.
* @throws IllegalStateException if vrp == null or activityStates == null or fleetManager == null.
*/
public JobInsertionCalculator build(){
public JobInsertionCostsCalculator build(){
if(vrp == null) throw new IllegalStateException("vehicle-routing-problem is null, but it must be set (this.setVehicleRoutingProblem(vrp))");
if(states == null) throw new IllegalStateException("states is null, but is must be set (this.setStates(states))");
if(fleetManager == null) throw new IllegalStateException("fleetManager is null, but it must be set (this.setVehicleFleetManager(fleetManager))");
JobInsertionCalculator baseCalculator = null;
JobInsertionCostsCalculator baseCalculator = null;
CalculatorPlusListeners standardLocal = null;
if(local){
standardLocal = createStandardLocal(vrp, states);
@ -228,14 +229,14 @@ class CalculatorBuilder {
actInsertionCalc = activityInsertionCostCalculator;
}
JobInsertionCalculator standardServiceInsertion = new ServiceInsertionCalculator(vrp.getTransportCosts(), actInsertionCalc, constraintManager, constraintManager);
JobInsertionCostsCalculator standardServiceInsertion = new ServiceInsertionCalculator(vrp.getTransportCosts(), actInsertionCalc, constraintManager, constraintManager);
((ServiceInsertionCalculator) standardServiceInsertion).setNeighborhood(vrp.getNeighborhood());
CalculatorPlusListeners calcPlusListeners = new CalculatorPlusListeners(standardServiceInsertion);
return calcPlusListeners;
}
private CalculatorPlusListeners createCalculatorConsideringFixedCosts(VehicleRoutingProblem vrp, JobInsertionCalculator baseCalculator, StateGetter activityStates2, double weightOfFixedCosts){
private CalculatorPlusListeners createCalculatorConsideringFixedCosts(VehicleRoutingProblem vrp, JobInsertionCostsCalculator baseCalculator, StateGetter activityStates2, double weightOfFixedCosts){
final JobInsertionConsideringFixCostsCalculator withFixCost = new JobInsertionConsideringFixCostsCalculator(baseCalculator, activityStates2);
withFixCost.setWeightOfFixCost(weightOfFixedCosts);
CalculatorPlusListeners calcPlusListeners = new CalculatorPlusListeners(withFixCost);
@ -252,7 +253,7 @@ class CalculatorBuilder {
else{
routeLevelCostEstimator = activityInsertionCostCalculator;
}
JobInsertionCalculator jobInsertionCalculator = new ServiceInsertionOnRouteLevelCalculator(vrp.getTransportCosts(), vrp.getActivityCosts(), routeLevelCostEstimator, constraintManager, constraintManager);
JobInsertionCostsCalculator jobInsertionCalculator = new ServiceInsertionOnRouteLevelCalculator(vrp.getTransportCosts(), vrp.getActivityCosts(), routeLevelCostEstimator, constraintManager, constraintManager);
((ServiceInsertionOnRouteLevelCalculator)jobInsertionCalculator).setNuOfActsForwardLooking(after);
((ServiceInsertionOnRouteLevelCalculator)jobInsertionCalculator).setMemorySize(solutionMemory);
((ServiceInsertionOnRouteLevelCalculator)jobInsertionCalculator).setNeighborhood(vrp.getNeighborhood());
@ -261,7 +262,7 @@ class CalculatorBuilder {
return calcPlusListener;
}
private JobInsertionCalculator createFinalInsertion(VehicleFleetManager fleetManager, JobInsertionCalculator baseCalc, StateGetter activityStates2){
private JobInsertionCostsCalculator createFinalInsertion(VehicleFleetManager fleetManager, JobInsertionCostsCalculator baseCalc, StateGetter activityStates2){
return new VehicleTypeDependentJobInsertionCalculator(fleetManager, baseCalc);
}

View file

@ -1,97 +0,0 @@
/*******************************************************************************
* Copyright (C) 2013 Stefan Schroeder
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
/* *********************************************************************** *
* project: org.matsim.*
* IniSolution.java
* *
* *********************************************************************** *
* *
* copyright : (C) 2011 by the members listed in the COPYING, *
* LICENSE and WARRANTY file. *
* email : info at matsim dot org *
* *
* *********************************************************************** *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* See also COPYING, LICENSE and WARRANTY file *
* *
* *********************************************************************** */
package algorithms;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
import basics.Job;
import basics.VehicleRoutingProblem;
import basics.VehicleRoutingProblemSolution;
import basics.algo.SolutionCostCalculator;
import basics.route.DriverImpl;
import basics.route.TourActivities;
import basics.route.Vehicle;
import basics.route.VehicleRoute;
final class CreateInitialSolution implements InitialSolutionFactory {
private static final Logger logger = Logger.getLogger(CreateInitialSolution.class);
private final InsertionStrategy insertion;
private SolutionCostCalculator solutionCostCalculator;
private boolean generateAsMuchAsRoutesAsVehiclesExist = false;
public void setGenerateAsMuchAsRoutesAsVehiclesExist(boolean generateAsMuchAsRoutesAsVehiclesExist) {
this.generateAsMuchAsRoutesAsVehiclesExist = generateAsMuchAsRoutesAsVehiclesExist;
}
public CreateInitialSolution(InsertionStrategy insertionStrategy, SolutionCostCalculator solutionCostCalculator) {
super();
this.insertion = insertionStrategy;
this.solutionCostCalculator = solutionCostCalculator;
}
@Override
public VehicleRoutingProblemSolution createSolution(final VehicleRoutingProblem vrp) {
logger.info("create initial solution.");
List<VehicleRoute> vehicleRoutes = new ArrayList<VehicleRoute>();
if(generateAsMuchAsRoutesAsVehiclesExist){
for(Vehicle vehicle : vrp.getVehicles()){
vehicleRoutes.add(VehicleRoute.newInstance(TourActivities.emptyTour(), DriverImpl.noDriver(), vehicle));
}
}
insertion.insertJobs(vehicleRoutes, getUnassignedJobs(vrp));
// double totalCost = getTotalCost(vehicleRoutes);
logger.info("creation done");
VehicleRoutingProblemSolution vehicleRoutingProblemSolution = new VehicleRoutingProblemSolution(vehicleRoutes, 0.0);
solutionCostCalculator.calculateCosts(vehicleRoutingProblemSolution);
return vehicleRoutingProblemSolution;
}
private List<Job> getUnassignedJobs(VehicleRoutingProblem vrp) {
List<Job> jobs = new ArrayList<Job>(vrp.getJobs().values());
return jobs;
}
}

View file

@ -24,6 +24,7 @@ import org.apache.log4j.Logger;
import basics.route.TourActivities;
import basics.route.TourActivity;
import basics.route.Vehicle;
import basics.route.VehicleFleetManager;
import basics.route.VehicleImpl.NoVehicle;
import basics.route.VehicleRoute;

View file

@ -36,6 +36,7 @@ import basics.algo.RuinListener;
import basics.algo.SearchStrategyModule;
import basics.algo.SearchStrategyModuleListener;
import basics.route.TourActivity;
import basics.route.VehicleFleetManager;
import basics.route.TourActivity.JobActivity;
import basics.route.VehicleRoute;

View file

@ -19,9 +19,14 @@ package algorithms;
import basics.route.Driver;
import basics.route.Vehicle;
class InsertionData {
/**
* Data object that collects insertion information. It collects insertionCosts, insertionIndeces, vehicle and driver to be employed
* and departureTime of vehicle at vehicle's start location (e.g. depot).
*
* @author stefan
*
*/
public class InsertionData {
static class NoInsertionFound extends InsertionData{
@ -33,7 +38,15 @@ class InsertionData {
private static InsertionData noInsertion = new NoInsertionFound();
public static InsertionData noInsertionFound(){
/**
* Returns an instance of InsertionData that represents an EmptyInsertionData (which might indicate
* that no insertion has been found). It is internally instantiated as follows:<br>
* <code>new InsertionData(Double.MAX_VALUE, NO_INDEX, NO_INDEX, null, null);</code><br>
* where NO_INDEX=-1.
*
* @return
*/
public static InsertionData createEmptyInsertionData(){
return noInsertion;
}
@ -80,22 +93,47 @@ class InsertionData {
return "[iCost="+insertionCost+"][iIndex="+deliveryInsertionIndex+"][depTime="+departureTime+"][vehicle="+selectedVehicle+"][driver="+selectedDriver+"]";
}
/**
* Returns insertionIndex of deliveryActivity. If no insertionPosition is found, it returns NO_INDEX (=-1).
*
* @return
*/
public int getDeliveryInsertionIndex(){
return deliveryInsertionIndex;
}
/**
* Returns insertionIndex of pickkupActivity. If no insertionPosition is found, it returns NO_INDEX (=-1).
*
* @return
*/
public int getPickupInsertionIndex(){
return pickupInsertionIndex;
}
/**
* Returns insertion costs (which might be the additional costs of inserting the corresponding job).
*
* @return
*/
public double getInsertionCost() {
return insertionCost;
}
/**
* Returns the vehicle to be employed.
*
* @return
*/
public Vehicle getSelectedVehicle() {
return selectedVehicle;
}
/**
* Returns the vehicle to be employed.
*
* @return
*/
public Driver getSelectedDriver(){
return selectedDriver;
}

View file

@ -26,6 +26,7 @@ import org.apache.log4j.Logger;
import basics.VehicleRoutingProblem;
import basics.algo.InsertionListener;
import basics.algo.VehicleRoutingAlgorithmListeners.PrioritizedVRAListener;
import basics.route.VehicleFleetManager;
class InsertionFactory {
@ -87,7 +88,7 @@ class InsertionFactory {
calcBuilder.experimentalTimeScheduler(Double.parseDouble(timeSliceString),Integer.parseInt(neighbors));
}
JobInsertionCalculator jic = calcBuilder.build();
JobInsertionCostsCalculator jic = calcBuilder.build();
if(insertionName.equals("bestInsertion")){

View file

@ -40,51 +40,35 @@ import org.apache.log4j.Logger;
import basics.Job;
import basics.VehicleRoutingProblem;
import basics.VehicleRoutingProblemSolution;
import basics.route.DriverImpl;
import basics.route.TourActivities;
import basics.route.Vehicle;
import basics.algo.SolutionCostCalculator;
import basics.route.VehicleRoute;
public final class BestInsertionInitialSolutionFactory implements InitialSolutionFactory {
public final class InsertionInitialSolutionFactory implements InitialSolutionFactory {
private static final Logger logger = Logger.getLogger(BestInsertionInitialSolutionFactory.class);
private static final Logger logger = Logger.getLogger(InsertionInitialSolutionFactory.class);
private final InsertionStrategy insertion;
private boolean generateAsMuchAsRoutesAsVehiclesExist = false;
public void setGenerateAsMuchAsRoutesAsVehiclesExist(boolean generateAsMuchAsRoutesAsVehiclesExist) {
this.generateAsMuchAsRoutesAsVehiclesExist = generateAsMuchAsRoutesAsVehiclesExist;
}
public BestInsertionInitialSolutionFactory(InsertionStrategy insertionStrategy) {
private SolutionCostCalculator solutionCostsCalculator;
public InsertionInitialSolutionFactory(InsertionStrategy insertionStrategy, SolutionCostCalculator solutionCostCalculator) {
super();
this.insertion = insertionStrategy;
this.solutionCostsCalculator = solutionCostCalculator;
}
@Override
public VehicleRoutingProblemSolution createSolution(final VehicleRoutingProblem vrp) {
logger.info("create initial solution.");
List<VehicleRoute> vehicleRoutes = new ArrayList<VehicleRoute>();
if(generateAsMuchAsRoutesAsVehiclesExist){
for(Vehicle vehicle : vrp.getVehicles()){
vehicleRoutes.add(VehicleRoute.newInstance(TourActivities.emptyTour(), DriverImpl.noDriver(), vehicle));
}
}
insertion.insertJobs(vehicleRoutes, getUnassignedJobs(vrp));
double totalCost = getTotalCost(vehicleRoutes);
VehicleRoutingProblemSolution solution = new VehicleRoutingProblemSolution(vehicleRoutes, Double.MAX_VALUE);
double costs = solutionCostsCalculator.getCosts(solution);
solution.setCost(costs);
logger.info("creation done");
return new VehicleRoutingProblemSolution(vehicleRoutes, totalCost);
}
private double getTotalCost(List<VehicleRoute> serviceProviders) {
double c = 0.0;
for(VehicleRoute a : serviceProviders){
c += a.getCost();
}
return c;
return solution;
}
private List<Job> getUnassignedJobs(VehicleRoutingProblem vrp) {

View file

@ -1,82 +0,0 @@
/*******************************************************************************
* Copyright (C) 2013 Stefan Schroeder
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
package algorithms;
import java.util.Iterator;
import org.apache.log4j.Logger;
import algorithms.BackwardInTimeListeners.BackwardInTimeListener;
import basics.costs.BackwardTransportTime;
import basics.route.TourActivity;
import basics.route.VehicleRoute;
/**
*
* @author stefan schroeder
*
*/
class IterateRouteBackwardInTime implements VehicleRouteUpdater{
private static Logger log = Logger.getLogger(IterateRouteBackwardInTime.class);
private BackwardTransportTime transportTime;
private BackwardInTimeListeners listeners;
public IterateRouteBackwardInTime(BackwardTransportTime transportTime) {
super();
this.transportTime = transportTime;
listeners = new BackwardInTimeListeners();
}
/*
*
*/
public void iterate(VehicleRoute vehicleRoute) {
if(listeners.isEmpty()) return;
if(vehicleRoute.isEmpty()) return;
listeners.start(vehicleRoute, vehicleRoute.getEnd(), vehicleRoute.getEnd().getTheoreticalLatestOperationStartTime());
Iterator<TourActivity> reverseActIter = vehicleRoute.getTourActivities().reverseActivityIterator();
TourActivity prevAct;
prevAct = vehicleRoute.getEnd();
double latestArrivalTimeAtPrevAct = prevAct.getTheoreticalLatestOperationStartTime();
while(reverseActIter.hasNext()){
TourActivity currAct = reverseActIter.next();
double latestDepTimeAtCurrAct = latestArrivalTimeAtPrevAct - transportTime.getBackwardTransportTime(currAct.getLocationId(), prevAct.getLocationId(), latestArrivalTimeAtPrevAct, vehicleRoute.getDriver(),vehicleRoute.getVehicle());
double potentialLatestArrivalTimeAtCurrAct = latestDepTimeAtCurrAct - currAct.getOperationTime();
double latestArrivalTime = Math.min(currAct.getTheoreticalLatestOperationStartTime(), potentialLatestArrivalTimeAtCurrAct);
listeners.prevActivity(currAct, latestDepTimeAtCurrAct, latestArrivalTime);
prevAct = currAct;
latestArrivalTimeAtPrevAct = latestArrivalTime;
}
TourActivity currAct = vehicleRoute.getStart();
double latestDepTimeAtCurrAct = latestArrivalTimeAtPrevAct - transportTime.getBackwardTransportTime(currAct.getLocationId(), prevAct.getLocationId(), latestArrivalTimeAtPrevAct, vehicleRoute.getDriver(),vehicleRoute.getVehicle());
listeners.end(vehicleRoute.getStart(), latestDepTimeAtCurrAct);
}
public void addListener(BackwardInTimeListener l){ listeners.addListener(l); }
}

View file

@ -1,87 +0,0 @@
/*******************************************************************************
* Copyright (C) 2013 Stefan Schroeder
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
package algorithms;
import org.apache.log4j.Logger;
import algorithms.ForwardInTimeListeners.ForwardInTimeListener;
import basics.costs.ForwardTransportTime;
import basics.route.Driver;
import basics.route.End;
import basics.route.TourActivity;
import basics.route.Vehicle;
import basics.route.VehicleRoute;
/**
*
* @author sschroeder
*
*/
class IterateRouteForwardInTime implements VehicleRouteUpdater{
private static Logger log = Logger.getLogger(IterateRouteForwardInTime.class);
private ForwardTransportTime transportTime;
private ForwardInTimeListeners listeners;
public IterateRouteForwardInTime(ForwardTransportTime transportTime) {
super();
this.transportTime = transportTime;
listeners = new ForwardInTimeListeners();
}
/**
*
*
*/
public void iterate(VehicleRoute vehicleRoute) {
if(listeners.isEmpty()) return;
if(vehicleRoute.isEmpty()) return;
listeners.start(vehicleRoute, vehicleRoute.getStart(), vehicleRoute.getStart().getEndTime());
Vehicle vehicle = vehicleRoute.getVehicle();
Driver driver = vehicleRoute.getDriver();
TourActivity prevAct = vehicleRoute.getStart();
double startAtPrevAct = prevAct.getEndTime();
for(TourActivity currentAct : vehicleRoute.getTourActivities().getActivities()){
double transportTime = this.transportTime.getTransportTime(prevAct.getLocationId(), currentAct.getLocationId(), startAtPrevAct, driver, vehicle);
double arrivalTimeAtCurrAct = startAtPrevAct + transportTime;
double operationStartTime = Math.max(currentAct.getTheoreticalEarliestOperationStartTime(), arrivalTimeAtCurrAct);
double operationEndTime = operationStartTime + currentAct.getOperationTime();
listeners.nextActivity(currentAct,arrivalTimeAtCurrAct,operationEndTime);
prevAct = currentAct;
startAtPrevAct = operationEndTime;
}
End currentAct = vehicleRoute.getEnd();
double transportTime = this.transportTime.getTransportTime(prevAct.getLocationId(), currentAct.getLocationId(), startAtPrevAct, driver, vehicle);
double arrivalTimeAtCurrAct = startAtPrevAct + transportTime;
listeners.end(vehicleRoute.getEnd(), arrivalTimeAtCurrAct);
}
public void addListener(ForwardInTimeListener l){
listeners.addListener(l);
}
}

View file

@ -27,11 +27,11 @@ import basics.route.VehicleRoute;
final class JobInsertionConsideringFixCostsCalculator implements JobInsertionCalculator{
final class JobInsertionConsideringFixCostsCalculator implements JobInsertionCostsCalculator{
private static final Logger logger = Logger.getLogger(JobInsertionConsideringFixCostsCalculator.class);
private final JobInsertionCalculator standardServiceInsertion;
private final JobInsertionCostsCalculator standardServiceInsertion;
private double weight_deltaFixCost = 0.5;
@ -39,7 +39,7 @@ final class JobInsertionConsideringFixCostsCalculator implements JobInsertionCal
private StateGetter stateGetter;
public JobInsertionConsideringFixCostsCalculator(final JobInsertionCalculator standardInsertionCalculator, StateGetter stateGetter) {
public JobInsertionConsideringFixCostsCalculator(final JobInsertionCostsCalculator standardInsertionCalculator, StateGetter stateGetter) {
super();
this.standardServiceInsertion = standardInsertionCalculator;
this.stateGetter = stateGetter;
@ -47,15 +47,15 @@ final class JobInsertionConsideringFixCostsCalculator implements JobInsertionCal
}
@Override
public InsertionData calculate(final VehicleRoute currentRoute, final Job jobToInsert, final Vehicle newVehicle, double newVehicleDepartureTime, final Driver newDriver, final double bestKnownPrice) {
public InsertionData getInsertionData(final VehicleRoute currentRoute, final Job jobToInsert, final Vehicle newVehicle, double newVehicleDepartureTime, final Driver newDriver, final double bestKnownPrice) {
double relFixCost = getDeltaRelativeFixCost(currentRoute, newVehicle, jobToInsert);
double absFixCost = getDeltaAbsoluteFixCost(currentRoute, newVehicle, jobToInsert);
double deltaFixCost = (1-solution_completeness_ratio)*relFixCost + solution_completeness_ratio*absFixCost;
double fixcost_contribution = weight_deltaFixCost*solution_completeness_ratio*deltaFixCost;
if(fixcost_contribution > bestKnownPrice){
return InsertionData.noInsertionFound();
return InsertionData.createEmptyInsertionData();
}
InsertionData iData = standardServiceInsertion.calculate(currentRoute, jobToInsert, newVehicle, newVehicleDepartureTime, newDriver, bestKnownPrice);
InsertionData iData = standardServiceInsertion.getInsertionData(currentRoute, jobToInsert, newVehicle, newVehicleDepartureTime, newDriver, bestKnownPrice);
if(iData instanceof NoInsertionFound){
return iData;
}

View file

@ -22,8 +22,8 @@ import basics.route.Vehicle;
import basics.route.VehicleRoute;
interface JobInsertionCalculator {
public interface JobInsertionCostsCalculator {
public InsertionData calculate(VehicleRoute currentRoute, Job jobToInsert, Vehicle newVehicle, double newVehicleDepartureTime, Driver newDriver, double bestKnownScore);
public InsertionData getInsertionData(VehicleRoute currentRoute, Job newJob, Vehicle newVehicle, double newVehicleDepartureTime, Driver newDriver, double bestKnownCosts);
}

View file

@ -47,7 +47,7 @@ class LocalActivityInsertionCostsCalculator implements ActivityInsertionCostsCal
}
@Override
public ActivityInsertionCosts calculate(InsertionContext iFacts, TourActivity prevAct, TourActivity nextAct, TourActivity newAct, double depTimeAtPrevAct) {
public ActivityInsertionCosts getCosts(InsertionContext iFacts, TourActivity prevAct, TourActivity nextAct, TourActivity newAct, double depTimeAtPrevAct) {
double tp_costs_prevAct_newAct = routingCosts.getTransportCost(prevAct.getLocationId(), newAct.getLocationId(), depTimeAtPrevAct, iFacts.getNewDriver(), iFacts.getNewVehicle());
double tp_time_prevAct_newAct = routingCosts.getTransportTime(prevAct.getLocationId(), newAct.getLocationId(), depTimeAtPrevAct, iFacts.getNewDriver(), iFacts.getNewVehicle());

View file

@ -23,9 +23,10 @@ import java.util.List;
import org.apache.log4j.Logger;
import basics.algo.InsertionEndsListener;
import basics.route.VehicleFleetManager;
import basics.route.VehicleRoute;
public class RemoveEmptyVehicles implements InsertionEndsListener{
class RemoveEmptyVehicles implements InsertionEndsListener{
private static Logger log = Logger.getLogger(RemoveEmptyVehicles.class);

View file

@ -23,6 +23,7 @@ import org.apache.log4j.Logger;
import basics.Job;
import basics.algo.InsertionStartsListener;
import basics.route.VehicleFleetManager;
import basics.route.VehicleRoute;
class ResetAndIniFleetManager implements InsertionStartsListener{

View file

@ -48,7 +48,7 @@ class RouteLevelActivityInsertionCostsEstimator implements ActivityInsertionCost
}
@Override
public ActivityInsertionCosts calculate(InsertionContext iFacts, TourActivity prevAct, TourActivity nextAct, TourActivity newAct, double depTimeAtPrevAct) {
public ActivityInsertionCosts getCosts(InsertionContext iFacts, TourActivity prevAct, TourActivity nextAct, TourActivity newAct, double depTimeAtPrevAct) {
List<TourActivity> path = new ArrayList<TourActivity>();
path.add(prevAct); path.add(newAct); path.add(nextAct);
int actIndex;

View file

@ -36,7 +36,7 @@ import basics.route.VehicleRoute;
final class ServiceInsertionCalculator implements JobInsertionCalculator{
final class ServiceInsertionCalculator implements JobInsertionCostsCalculator{
private static final Logger logger = Logger.getLogger(ServiceInsertionCalculator.class);
@ -85,13 +85,13 @@ final class ServiceInsertionCalculator implements JobInsertionCalculator{
*
*/
@Override
public InsertionData calculate(final VehicleRoute currentRoute, final Job jobToInsert, final Vehicle newVehicle, double newVehicleDepartureTime, final Driver newDriver, final double bestKnownCosts) {
public InsertionData getInsertionData(final VehicleRoute currentRoute, final Job jobToInsert, final Vehicle newVehicle, double newVehicleDepartureTime, final Driver newDriver, final double bestKnownCosts) {
if(jobToInsert == null) throw new IllegalStateException("jobToInsert is missing.");
if(newVehicle == null || newVehicle instanceof NoVehicle) throw new IllegalStateException("newVehicle is missing.");
InsertionContext insertionContext = new InsertionContext(currentRoute, jobToInsert, newVehicle, newDriver, newVehicleDepartureTime);
if(!hardRouteLevelConstraint.fulfilled(insertionContext)){
return InsertionData.noInsertionFound();
return InsertionData.createEmptyInsertionData();
}
double bestCost = bestKnownCosts;
@ -146,7 +146,7 @@ final class ServiceInsertionCalculator implements JobInsertionCalculator{
}
if(insertionIndex == InsertionData.NO_INDEX) {
return InsertionData.noInsertionFound();
return InsertionData.createEmptyInsertionData();
}
InsertionData insertionData = new InsertionData(bestCost, InsertionData.NO_INDEX, insertionIndex, newVehicle, newDriver);
insertionData.setVehicleDepartureTime(newVehicleDepartureTime);
@ -155,7 +155,7 @@ final class ServiceInsertionCalculator implements JobInsertionCalculator{
}
public ActivityInsertionCosts calculate(InsertionContext iFacts, TourActivity prevAct, TourActivity nextAct, TourActivity newAct, double departureTimeAtPrevAct) {
return activityInsertionCostsCalculator.calculate(iFacts, prevAct, nextAct, newAct, departureTimeAtPrevAct);
return activityInsertionCostsCalculator.getCosts(iFacts, prevAct, nextAct, newAct, departureTimeAtPrevAct);
}
}

View file

@ -45,7 +45,7 @@ import basics.route.VehicleRoute;
final class ServiceInsertionOnRouteLevelCalculator implements JobInsertionCalculator{
final class ServiceInsertionOnRouteLevelCalculator implements JobInsertionCostsCalculator{
private static final Logger logger = Logger.getLogger(ServiceInsertionOnRouteLevelCalculator.class);
@ -131,13 +131,13 @@ final class ServiceInsertionOnRouteLevelCalculator implements JobInsertionCalcul
*
*/
@Override
public InsertionData calculate(final VehicleRoute currentRoute, final Job jobToInsert, final Vehicle newVehicle, double newVehicleDepartureTime, final Driver newDriver, final double best_known_insertion_costs) {
public InsertionData getInsertionData(final VehicleRoute currentRoute, final Job jobToInsert, final Vehicle newVehicle, double newVehicleDepartureTime, final Driver newDriver, final double best_known_insertion_costs) {
if(jobToInsert == null) throw new IllegalStateException("job is null. cannot calculate the insertion of a null-job.");
if(newVehicle == null || newVehicle instanceof NoVehicle) throw new IllegalStateException("no vehicle given. set para vehicle!");
InsertionContext insertionContext = new InsertionContext(currentRoute, jobToInsert, newVehicle, newDriver, newVehicleDepartureTime);
if(!hardRouteLevelConstraint.fulfilled(insertionContext)){
return InsertionData.noInsertionFound();
return InsertionData.createEmptyInsertionData();
}
/**
@ -182,7 +182,7 @@ final class ServiceInsertionOnRouteLevelCalculator implements JobInsertionCalcul
/**
* builds a path on this route forwardPath={i,k,j,j+1,j+2,...,j+nuOfActsForwardLooking}
*/
ActivityInsertionCosts actInsertionCosts = activityInsertionCostsCalculator.calculate(insertionContext, prevAct, nextAct, serviceAct2Insert, prevActDepTime_newVehicle);
ActivityInsertionCosts actInsertionCosts = activityInsertionCostsCalculator.getCosts(insertionContext, prevAct, nextAct, serviceAct2Insert, prevActDepTime_newVehicle);
/**
* insertion_cost_approximation = c({0,1,...,i},newVehicle) + c({i,k,j,j+1,j+2,...,j+nuOfActsForwardLooking},newVehicle) - c({0,1,...,i,j,j+1,...,j+nuOfActsForwardLooking},oldVehicle)
@ -234,7 +234,7 @@ final class ServiceInsertionOnRouteLevelCalculator implements JobInsertionCalcul
if(neighborhood.areNeighbors(serviceAct2Insert.getLocationId(), prevAct.getLocationId()) && neighborhood.areNeighbors(serviceAct2Insert.getLocationId(), nextAct.getLocationId())){
ConstraintsStatus status = hardActivityLevelConstraint.fulfilled(insertionContext, prevAct, serviceAct2Insert, nextAct, prevActDepTime_newVehicle);
if(status.equals(ConstraintsStatus.FULFILLED)){
ActivityInsertionCosts actInsertionCosts = activityInsertionCostsCalculator.calculate(insertionContext, prevAct, nextAct, serviceAct2Insert, prevActDepTime_newVehicle);
ActivityInsertionCosts actInsertionCosts = activityInsertionCostsCalculator.getCosts(insertionContext, prevAct, nextAct, serviceAct2Insert, prevActDepTime_newVehicle);
if(actInsertionCosts != null){
/**
* insertion_cost_approximation = c({0,1,...,i},newVehicle) + c({i,k,j,j+1,j+2,...,j+nuOfActsForwardLooking},newVehicle) - c({0,1,...,i,j,j+1,...,j+nuOfActsForwardLooking},oldVehicle)
@ -296,7 +296,7 @@ final class ServiceInsertionOnRouteLevelCalculator implements JobInsertionCalcul
}
}
}
if(best_insertion_index == InsertionData.NO_INDEX) return InsertionData.noInsertionFound();
if(best_insertion_index == InsertionData.NO_INDEX) return InsertionData.createEmptyInsertionData();
return new InsertionData(best_insertion_costs, InsertionData.NO_INDEX, best_insertion_index, newVehicle, newDriver);
}

View file

@ -33,6 +33,11 @@ import basics.algo.IterationStartsListener;
import basics.algo.JobInsertedListener;
import basics.algo.RuinListener;
import basics.algo.RuinListeners;
import basics.route.ActivityVisitor;
import basics.route.ReverseActivityVisitor;
import basics.route.ReverseRouteActivityVisitor;
import basics.route.RouteActivityVisitor;
import basics.route.RouteVisitor;
import basics.route.TourActivity;
import basics.route.VehicleRoute;

View file

@ -2,7 +2,10 @@ package algorithms;
import org.apache.log4j.Logger;
import util.ActivityTimeTracker;
import basics.costs.ForwardTransportTime;
import basics.route.ActivityVisitor;
import basics.route.TourActivity;
import basics.route.VehicleRoute;

View file

@ -2,10 +2,13 @@ package algorithms;
import org.apache.log4j.Logger;
import util.ActivityTimeTracker;
import algorithms.StateManager.StateImpl;
import basics.costs.ForwardTransportCost;
import basics.costs.VehicleRoutingActivityCosts;
import basics.costs.VehicleRoutingTransportCosts;
import basics.route.ActivityVisitor;
import basics.route.TourActivity;
import basics.route.Vehicle;
import basics.route.VehicleRoute;

View file

@ -9,6 +9,7 @@ import basics.algo.InsertionStartsListener;
import basics.algo.JobInsertedListener;
import basics.costs.VehicleRoutingActivityCosts;
import basics.costs.VehicleRoutingTransportCosts;
import basics.route.RouteActivityVisitor;
import basics.route.VehicleRoute;
class UpdateCostsAtRouteLevel implements StateUpdater,JobInsertedListener, InsertionStartsListener, InsertionEndsListener{

View file

@ -1,7 +1,9 @@
package algorithms;
import util.ActivityTimeTracker;
import algorithms.StateManager.StateImpl;
import basics.costs.VehicleRoutingTransportCosts;
import basics.route.ActivityVisitor;
import basics.route.TourActivity;
import basics.route.VehicleRoute;

View file

@ -1,6 +1,7 @@
package algorithms;
import basics.route.PickupActivity;
import basics.route.ReverseActivityVisitor;
import basics.route.ServiceActivity;
import basics.route.TourActivity;
import basics.route.VehicleRoute;

View file

@ -4,6 +4,7 @@ import org.apache.log4j.Logger;
import algorithms.StateManager.StateImpl;
import basics.costs.VehicleRoutingTransportCosts;
import basics.route.ReverseActivityVisitor;
import basics.route.TourActivity;
import basics.route.VehicleRoute;

View file

@ -1,6 +1,7 @@
package algorithms;
import algorithms.StateManager.StateImpl;
import basics.route.ActivityVisitor;
import basics.route.TourActivity;
import basics.route.VehicleRoute;

View file

@ -1,6 +1,7 @@
package algorithms;
import algorithms.StateManager.StateImpl;
import basics.route.ActivityVisitor;
import basics.route.TourActivity;
import basics.route.VehicleRoute;

View file

@ -1,5 +1,6 @@
package algorithms;
import basics.route.ActivityVisitor;
import basics.route.TourActivity;
import basics.route.VehicleRoute;

View file

@ -1,6 +1,7 @@
package algorithms;
import algorithms.StateManager.StateImpl;
import basics.route.ActivityVisitor;
import basics.route.DeliveryActivity;
import basics.route.TourActivity;
import basics.route.VehicleRoute;

View file

@ -4,11 +4,11 @@ import basics.VehicleRoutingProblemSolution;
import basics.algo.SolutionCostCalculator;
import basics.route.VehicleRoute;
public class SolutionCostCalculatorFactory {
public class VariablePlusFixedSolutionCostCalculatorFactory {
private StateManager stateManager;
public SolutionCostCalculatorFactory(StateManager stateManager) {
public VariablePlusFixedSolutionCostCalculatorFactory(StateManager stateManager) {
super();
this.stateManager = stateManager;
}
@ -17,13 +17,13 @@ public class SolutionCostCalculatorFactory {
return new SolutionCostCalculator() {
@Override
public void calculateCosts(VehicleRoutingProblemSolution solution) {
public double getCosts(VehicleRoutingProblemSolution solution) {
double c = 0.0;
for(VehicleRoute r : solution.getRoutes()){
c += stateManager.getRouteState(r, StateFactory.COSTS).toDouble();
c += r.getVehicle().getType().getVehicleCostParams().fix;
}
solution.setCost(c);
return c;
}
};
}

View file

@ -7,6 +7,7 @@ import basics.VehicleRoutingAlgorithm;
import basics.VehicleRoutingProblem;
import basics.algo.SearchStrategyManager;
import basics.algo.VehicleRoutingAlgorithmListener;
import basics.route.VehicleFleetManager;
public class VehicleRoutingAlgorithmBuilder {
@ -17,12 +18,15 @@ public class VehicleRoutingAlgorithmBuilder {
private StateManager stateManager;
private Collection<VehicleRoutingAlgorithmListener> listeners = new ArrayList<VehicleRoutingAlgorithmListener>();
private VehicleFleetManager fleetManager;
public VehicleRoutingAlgorithmBuilder(VehicleRoutingProblem vrp, SearchStrategyManager searchStrategyManager, StateManager stateManager) {
public VehicleRoutingAlgorithmBuilder(VehicleRoutingProblem vrp, SearchStrategyManager searchStrategyManager, StateManager stateManager, VehicleFleetManager vehicleFleetManager) {
super();
this.vrp = vrp;
this.searchStrategyManager = searchStrategyManager;
this.stateManager = stateManager;
this.fleetManager = vehicleFleetManager;
}
public void addListener(VehicleRoutingAlgorithmListener listener){
@ -33,6 +37,7 @@ public class VehicleRoutingAlgorithmBuilder {
VehicleRoutingAlgorithm algorithm = new VehicleRoutingAlgorithm(vrp, searchStrategyManager);
algorithm.getAlgorithmListeners().addListener(stateManager);
algorithm.getSearchStrategyManager().addSearchStrategyModuleListener(stateManager);
algorithm.getSearchStrategyManager().addSearchStrategyModuleListener(new RemoveEmptyVehicles(fleetManager));
return algorithm;
}

View file

@ -31,8 +31,6 @@ import org.apache.commons.configuration.HierarchicalConfiguration;
import org.apache.commons.configuration.XMLConfiguration;
import org.apache.log4j.Logger;
import algorithms.VehicleRoutingAlgorithms.TypedMap.AbstractKey;
import algorithms.VehicleRoutingAlgorithms.TypedMap.AcceptorKey;
import algorithms.VehicleRoutingAlgorithms.TypedMap.InsertionStrategyKey;
@ -66,7 +64,10 @@ import basics.algo.VehicleRoutingAlgorithmListeners.PrioritizedVRAListener;
import basics.algo.VehicleRoutingAlgorithmListeners.Priority;
import basics.io.AlgorithmConfig;
import basics.io.AlgorithmConfigXmlReader;
import basics.route.FiniteFleetManagerFactory;
import basics.route.InfiniteFleetManagerFactory;
import basics.route.Vehicle;
import basics.route.VehicleFleetManager;
import basics.route.VehicleRoute;
@ -492,23 +493,6 @@ public class VehicleRoutingAlgorithms {
* define stateUpdates
*/
//reset stateManager
// algorithmListeners.add(new PrioritizedVRAListener(Priority.LOW, new StateUpdates.ResetStateManager(stateManager)));
//update states
// metaAlgorithm.getSearchStrategyManager().addSearchStrategyModuleListener(new UpdateStates(stateManager, vrp.getTransportCosts(), vrp.getActivityCosts()));
// UpdateRouteStatesOnceTheRouteHasBeenChanged routeChangedListener = new StateUpdates.UpdateRouteStatesOnceTheRouteHasBeenChanged(vrp.getTransportCosts());
//
// routeChangedListener.addInsertionStartsListener(new InitializeLoadsAtStartAndEndOfRouteWhenInsertionStarts.UpdateLoadsAtStartAndEndOfRouteWhenInsertionStarts(stateManager));
// routeChangedListener.addJobInsertedListener(new UpdateLoadsAtStartAndEndOfRouteWhenJobHasBeenInserted(stateManager));
//
// routeChangedListener.addVisitor(new StateUpdates.UpdateActivityTimes(vrp.getTransportCosts()));
// routeChangedListener.addVisitor(new StateUpdates.UpdateLoadAtActivityLevel(stateManager));
// routeChangedListener.addVisitor(new StateUpdates.UpdateCostsAtAllLevels(vrp.getActivityCosts(), vrp.getTransportCosts(), stateManager));
//
// routeChangedListener.addVisitor(new StateUpdates.UpdateOccuredDeliveriesAtActivityLevel(stateManager));
// routeChangedListener.addVisitor(new StateUpdates.UpdateLatestOperationStartTimeAtActLocations(stateManager, vrp.getTransportCosts()));
// routeChangedListener.addVisitor(new StateUpdates.UpdateFuturePickupsAtActivityLevel(stateManager));
stateManager.addListener(new UpdateLoadsAtStartAndEndOfRouteWhenInsertionStarts(stateManager));
stateManager.addListener(new UpdateLoadsAtStartAndEndOfRouteWhenJobHasBeenInserted(stateManager));
@ -546,14 +530,12 @@ public class VehicleRoutingAlgorithms {
SolutionCostCalculator calc = new SolutionCostCalculator() {
@Override
public void calculateCosts(VehicleRoutingProblemSolution solution) {
public double getCosts(VehicleRoutingProblemSolution solution) {
double costs = 0.0;
for(VehicleRoute route : solution.getRoutes()){
costs += stateManager.getRouteState(route, StateFactory.COSTS).toDouble() + getFixedCosts(route.getVehicle());
}
solution.setCost(costs);
return costs;
}
private double getFixedCosts(Vehicle vehicle) {
@ -567,11 +549,11 @@ public class VehicleRoutingAlgorithms {
private static VehicleFleetManager createFleetManager(final VehicleRoutingProblem vrp) {
if(vrp.getFleetSize().equals(FleetSize.INFINITE)){
return new InfiniteVehicles(vrp.getVehicles());
return new InfiniteFleetManagerFactory(vrp.getVehicles()).createFleetManager();
}
else if(vrp.getFleetSize().equals(FleetSize.FINITE)){
return new VehicleFleetManagerImpl(vrp.getVehicles());
return new FiniteFleetManagerFactory(vrp.getVehicles()).createFleetManager();
}
throw new IllegalStateException("fleet size can only be infinite or finite. " +
"makes sure your config file contains one of these options");
@ -669,11 +651,11 @@ public class VehicleRoutingAlgorithms {
@Override
public void informAlgorithmStarts(VehicleRoutingProblem problem, VehicleRoutingAlgorithm algorithm, Collection<VehicleRoutingProblemSolution> solutions) {
CreateInitialSolution createInitialSolution = new CreateInitialSolution(finalInsertionStrategy, getCostCalculator(routeStates));
createInitialSolution.setGenerateAsMuchAsRoutesAsVehiclesExist(false);
VehicleRoutingProblemSolution vrpSol = createInitialSolution.createSolution(vrp);
InsertionInitialSolutionFactory insertionInitialSolutionFactory = new InsertionInitialSolutionFactory(finalInsertionStrategy, getCostCalculator(routeStates));
// CreateInitialSolution createInitialSolution = new CreateInitialSolution(finalInsertionStrategy, getCostCalculator(routeStates));
//
// createInitialSolution.setGenerateAsMuchAsRoutesAsVehiclesExist(false);
VehicleRoutingProblemSolution vrpSol = insertionInitialSolutionFactory.createSolution(vrp);
solutions.add(vrpSol);
}
};

View file

@ -17,6 +17,7 @@
package algorithms;
import basics.route.Vehicle;
import basics.route.VehicleFleetManager;
import basics.route.VehicleRoute;

View file

@ -25,20 +25,21 @@ import algorithms.InsertionData.NoInsertionFound;
import basics.Job;
import basics.route.Driver;
import basics.route.Vehicle;
import basics.route.VehicleFleetManager;
import basics.route.VehicleImpl.NoVehicle;
import basics.route.VehicleRoute;
final class VehicleTypeDependentJobInsertionCalculator implements JobInsertionCalculator{
final class VehicleTypeDependentJobInsertionCalculator implements JobInsertionCostsCalculator{
private Logger logger = Logger.getLogger(VehicleTypeDependentJobInsertionCalculator.class);
private final VehicleFleetManager fleetManager;
private final JobInsertionCalculator insertionCalculator;
private final JobInsertionCostsCalculator insertionCalculator;
public VehicleTypeDependentJobInsertionCalculator(final VehicleFleetManager fleetManager, final JobInsertionCalculator jobInsertionCalc) {
public VehicleTypeDependentJobInsertionCalculator(final VehicleFleetManager fleetManager, final JobInsertionCostsCalculator jobInsertionCalc) {
this.fleetManager = fleetManager;
this.insertionCalculator = jobInsertionCalc;
logger.info("inialise " + this);
@ -49,10 +50,10 @@ final class VehicleTypeDependentJobInsertionCalculator implements JobInsertionCa
return "[name=vehicleTypeDependentServiceInsertion]";
}
public InsertionData calculate(final VehicleRoute currentRoute, final Job jobToInsert, final Vehicle vehicle, double newVehicleDepartureTime, final Driver driver, final double bestKnownCost) {
public InsertionData getInsertionData(final VehicleRoute currentRoute, final Job jobToInsert, final Vehicle vehicle, double newVehicleDepartureTime, final Driver driver, final double bestKnownCost) {
Vehicle selectedVehicle = currentRoute.getVehicle();
Driver selectedDriver = currentRoute.getDriver();
InsertionData bestIData = InsertionData.noInsertionFound();
InsertionData bestIData = InsertionData.createEmptyInsertionData();
double bestKnownCost_ = bestKnownCost;
Collection<Vehicle> relevantVehicles = new ArrayList<Vehicle>();
if(!(selectedVehicle instanceof NoVehicle)) {
@ -65,7 +66,7 @@ final class VehicleTypeDependentJobInsertionCalculator implements JobInsertionCa
for(Vehicle v : relevantVehicles){
double depTime = v.getEarliestDeparture();
InsertionData iData = insertionCalculator.calculate(currentRoute, jobToInsert, v, depTime, selectedDriver, bestKnownCost_);
InsertionData iData = insertionCalculator.getInsertionData(currentRoute, jobToInsert, v, depTime, selectedDriver, bestKnownCost_);
if(iData instanceof NoInsertionFound) {
if(bestIData instanceof NoInsertionFound) bestIData = iData;
continue;

View file

@ -125,7 +125,8 @@ public class SearchStrategy {
VehicleRoutingProblemSolution newSolution = module.runAndGetSolution(lastSolution);
lastSolution = newSolution;
}
solutionCostCalculator.calculateCosts(lastSolution);
double costs = solutionCostCalculator.getCosts(lastSolution);
lastSolution.setCost(costs);
boolean solutionAccepted = solutionAcceptor.acceptSolution(solutions, lastSolution);
DiscoveredSolution discoveredSolution = new DiscoveredSolution(lastSolution, solutionAccepted, getName());
return discoveredSolution;

View file

@ -21,10 +21,11 @@ import basics.VehicleRoutingProblemSolution;
public interface SolutionCostCalculator {
/**
* This assumes that the solution is modified by setting its costs <br>
* <code>solution.setCost(costs);</code>
* Returns costs of solution.
*
* @param solution
* @return TODO
*/
public void calculateCosts(VehicleRoutingProblemSolution solution);
public double getCosts(VehicleRoutingProblemSolution solution);
}

View file

@ -14,10 +14,8 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
package algorithms;
package basics.route;
import basics.route.TourActivity;
import basics.route.VehicleRoute;
public interface ActivityVisitor {

View file

@ -1,8 +1,7 @@
package algorithms;
package basics.route;
import java.util.Collection;
import basics.route.Vehicle;
public class FiniteFleetManagerFactory implements VehicleFleetManagerFactory{

View file

@ -1,8 +1,7 @@
package algorithms;
package basics.route;
import java.util.Collection;
import basics.route.Vehicle;
public class InfiniteFleetManagerFactory implements VehicleFleetManagerFactory{

View file

@ -14,7 +14,7 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
package algorithms;
package basics.route;
import java.util.ArrayList;
import java.util.Collection;
@ -24,20 +24,8 @@ import java.util.Map;
import org.apache.log4j.Logger;
import basics.route.Vehicle;
class InfiniteVehicles implements VehicleFleetManager{
// static class TypeKeyComparator implements Comparator<TypeKey>{
//
// @Override
// public int compare(TypeKey k1, TypeKey k2) {
// double k1_fix = k1.type.getVehicleCostParams().fix;
// double k2_fix = k2.type.getVehicleCostParams().fix;
// return (int)(k1_fix - k2_fix);
// }
//
// }
private static Logger logger = Logger.getLogger(InfiniteVehicles.class);
@ -62,7 +50,6 @@ class InfiniteVehicles implements VehicleFleetManager{
sortedTypes.add(typeKey);
}
// Collections.sort(sortedTypes, new TypeKeyComparator());
}

View file

@ -14,10 +14,8 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
package algorithms;
package basics.route;
import basics.route.TourActivity;
import basics.route.VehicleRoute;
public interface ReverseActivityVisitor {

View file

@ -14,14 +14,12 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
package algorithms;
package basics.route;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import basics.route.TourActivity;
import basics.route.VehicleRoute;
public class ReverseRouteActivityVisitor implements RouteVisitor{

View file

@ -14,13 +14,11 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
package algorithms;
package basics.route;
import java.util.ArrayList;
import java.util.Collection;
import basics.route.TourActivity;
import basics.route.VehicleRoute;
public class RouteActivityVisitor implements RouteVisitor{

View file

@ -14,9 +14,8 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
package algorithms;
package basics.route;
import basics.route.VehicleRoute;
public interface RouteVisitor {

View file

@ -113,6 +113,12 @@ public class TourActivities {
return Collections.unmodifiableSet(jobs);
}
/**
* Returns true if job is in jobList, otherwise false.
*
* @param job
* @return
*/
public boolean servesJob(Job job) {
return jobs.contains(job);
}
@ -152,12 +158,22 @@ public class TourActivities {
}
}
}
if(jobRemoved != activityRemoved) throw new IllegalStateException("job removed, but belonging activity not.");
assert jobRemoved == activityRemoved : "job removed, but belonging activity not.";
return activityRemoved;
}
/**
* Inserts the specified activity add the specified insertionIndex. Shifts the element currently at that position (if any) and
* any subsequent elements to the right (adds one to their indices).
* <p>If specified activity instanceof JobActivity, it adds job to jobList.
* <p>If insertionIndex > tourActivitiies.size(), it just adds the specified act at the end.
*
* @param insertionIndex
* @param act
* @throws IndexOutOfBoundsException if insertionIndex < 0;
*/
public void addActivity(int insertionIndex, TourActivity act) {
assert insertionIndex >= 0 : "insertionIndex == 0, this cannot be";
assert insertionIndex >= 0 : "insertionIndex < 0, this cannot be";
/*
* if 1 --> between start and act(0) --> act(0)
* if 2 && 2 <= acts.size --> between act(0) and act(1) --> act(1)
@ -170,6 +186,12 @@ public class TourActivities {
addJob(act);
}
/**
* Adds specified activity at the end of activity-list.
* <p>If act instanceof JobActivity, it adds underlying job also.
* @throws IllegalStateException if activity-list already contains act.
* @param act
*/
public void addActivity(TourActivity act){
if(tourActivities.contains(act)) throw new IllegalStateException("act " + act + " already in tour. cannot add act twice.");
tourActivities.add(act);
@ -177,7 +199,6 @@ public class TourActivities {
}
private void addJob(TourActivity act) {
if(act instanceof JobActivity){
Job job = ((JobActivity) act).getJob();
jobs.add(job);
@ -187,6 +208,11 @@ public class TourActivities {
}
}
/**
* Returns number of jobs.
*
* @return
*/
public int jobSize() {
return jobs.size();
}

View file

@ -14,11 +14,10 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
package algorithms;
package basics.route;
import java.util.Collection;
import basics.route.Vehicle;
public interface VehicleFleetManager {

View file

@ -1,4 +1,4 @@
package algorithms;
package basics.route;
public interface VehicleFleetManagerFactory {

View file

@ -14,7 +14,7 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
package algorithms;
package basics.route;
import java.util.ArrayList;
import java.util.Collection;
@ -27,12 +27,11 @@ import java.util.Set;
import org.apache.log4j.Logger;
import basics.route.PenaltyVehicleType;
import basics.route.Vehicle;
import basics.route.VehicleImpl.NoVehicle;
class VehicleFleetManagerImpl implements VehicleFleetManager {
public VehicleFleetManagerImpl newInstance(Collection<Vehicle> vehicles){

View file

@ -1,4 +1,4 @@
package algorithms;
package basics.route;
class VehicleTypeKey {

View file

@ -14,9 +14,10 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
package algorithms;
package util;
import basics.costs.ForwardTransportTime;
import basics.route.ActivityVisitor;
import basics.route.TourActivity;
import basics.route.VehicleRoute;