mirror of
https://github.com/graphhopper/jsprit.git
synced 2020-01-24 07:45:05 +01:00
relax API
This commit is contained in:
parent
fb78d60a36
commit
b991aac12e
65 changed files with 294 additions and 689 deletions
|
|
@ -118,8 +118,10 @@ public class AlgorithmSearchProgressChartListener implements IterationEndsListen
|
||||||
XYPlot plot = chart.getXYPlot();
|
XYPlot plot = chart.getXYPlot();
|
||||||
|
|
||||||
NumberAxis yAxis = (NumberAxis) plot.getRangeAxis();
|
NumberAxis yAxis = (NumberAxis) plot.getRangeAxis();
|
||||||
Range rangeY = new Range(minValue-0.05*minValue,maxValue + 0.05*maxValue);
|
Range rangeBounds = coll.getRangeBounds(true);
|
||||||
yAxis.setRange(rangeY);
|
double upper = Math.min(rangeBounds.getUpperBound(), rangeBounds.getLowerBound()*5);
|
||||||
|
if(upper == 0.0){ upper = 10000; }
|
||||||
|
yAxis.setRangeWithMargins(rangeBounds.getLowerBound(),upper);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ChartUtilities.saveChartAsJPEG(new File(filename), chart, 1000, 600);
|
ChartUtilities.saveChartAsJPEG(new File(filename), chart, 1000, 600);
|
||||||
|
|
@ -143,9 +145,9 @@ public class AlgorithmSearchProgressChartListener implements IterationEndsListen
|
||||||
double best = Double.MAX_VALUE;
|
double best = Double.MAX_VALUE;
|
||||||
double sum = 0.0;
|
double sum = 0.0;
|
||||||
for(VehicleRoutingProblemSolution sol : solutions){
|
for(VehicleRoutingProblemSolution sol : solutions){
|
||||||
if(sol.getCost() > worst) worst = sol.getCost();
|
if(sol.getCost() > worst) worst = Math.min(sol.getCost(),Double.MAX_VALUE);
|
||||||
if(sol.getCost() < best) best = sol.getCost();
|
if(sol.getCost() < best) best = sol.getCost();
|
||||||
sum += sol.getCost();
|
sum += Math.min(sol.getCost(),Double.MAX_VALUE);
|
||||||
}
|
}
|
||||||
bestResultList.add(best);
|
bestResultList.add(best);
|
||||||
worstResultList.add(worst);
|
worstResultList.add(worst);
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ final class BestInsertion implements InsertionStrategy{
|
||||||
|
|
||||||
private Inserter inserter;
|
private Inserter inserter;
|
||||||
|
|
||||||
private JobInsertionCalculator bestInsertionCostCalculator;
|
private JobInsertionCostsCalculator bestInsertionCostCalculator;
|
||||||
|
|
||||||
private boolean minVehiclesFirst = false;
|
private boolean minVehiclesFirst = false;
|
||||||
|
|
||||||
|
|
@ -86,7 +86,7 @@ final class BestInsertion implements InsertionStrategy{
|
||||||
this.random = random;
|
this.random = random;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BestInsertion(JobInsertionCalculator jobInsertionCalculator) {
|
public BestInsertion(JobInsertionCostsCalculator jobInsertionCalculator) {
|
||||||
super();
|
super();
|
||||||
this.insertionsListeners = new InsertionListeners();
|
this.insertionsListeners = new InsertionListeners();
|
||||||
inserter = new Inserter(insertionsListeners);
|
inserter = new Inserter(insertionsListeners);
|
||||||
|
|
@ -108,7 +108,7 @@ final class BestInsertion implements InsertionStrategy{
|
||||||
Insertion bestInsertion = null;
|
Insertion bestInsertion = null;
|
||||||
double bestInsertionCost = Double.MAX_VALUE;
|
double bestInsertionCost = Double.MAX_VALUE;
|
||||||
for(VehicleRoute vehicleRoute : vehicleRoutes){
|
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) {
|
if(iData instanceof NoInsertionFound) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -119,7 +119,7 @@ final class BestInsertion implements InsertionStrategy{
|
||||||
}
|
}
|
||||||
if(!minVehiclesFirst){
|
if(!minVehiclesFirst){
|
||||||
VehicleRoute newRoute = VehicleRoute.emptyRoute();
|
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){
|
if(newIData.getInsertionCost() < bestInsertionCost){
|
||||||
bestInsertion = new Insertion(newRoute,newIData);
|
bestInsertion = new Insertion(newRoute,newIData);
|
||||||
bestInsertionCost = newIData.getInsertionCost();
|
bestInsertionCost = newIData.getInsertionCost();
|
||||||
|
|
@ -128,7 +128,7 @@ final class BestInsertion implements InsertionStrategy{
|
||||||
}
|
}
|
||||||
if(bestInsertion == null){
|
if(bestInsertion == null){
|
||||||
VehicleRoute newRoute = VehicleRoute.emptyRoute();
|
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){
|
if(bestI instanceof InsertionData.NoInsertionFound){
|
||||||
throw new IllegalStateException(getErrorMsg(unassignedJob));
|
throw new IllegalStateException(getErrorMsg(unassignedJob));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import basics.VehicleRoutingProblem;
|
||||||
import basics.VehicleRoutingProblem.Constraint;
|
import basics.VehicleRoutingProblem.Constraint;
|
||||||
import basics.algo.InsertionListener;
|
import basics.algo.InsertionListener;
|
||||||
import basics.algo.VehicleRoutingAlgorithmListeners.PrioritizedVRAListener;
|
import basics.algo.VehicleRoutingAlgorithmListeners.PrioritizedVRAListener;
|
||||||
|
import basics.route.VehicleFleetManager;
|
||||||
|
|
||||||
public class BestInsertionBuilder implements InsertionStrategyBuilder{
|
public class BestInsertionBuilder implements InsertionStrategyBuilder{
|
||||||
|
|
||||||
|
|
@ -25,6 +26,10 @@ public class BestInsertionBuilder implements InsertionStrategyBuilder{
|
||||||
private boolean considerFixedCosts = false;
|
private boolean considerFixedCosts = false;
|
||||||
|
|
||||||
private ActivityInsertionCostsCalculator actInsertionCostsCalculator = null;
|
private ActivityInsertionCostsCalculator actInsertionCostsCalculator = null;
|
||||||
|
|
||||||
|
private int forwaredLooking;
|
||||||
|
|
||||||
|
private int memory;
|
||||||
|
|
||||||
public BestInsertionBuilder(VehicleRoutingProblem vrp, VehicleFleetManager vehicleFleetManager, StateManager stateManager) {
|
public BestInsertionBuilder(VehicleRoutingProblem vrp, VehicleFleetManager vehicleFleetManager, StateManager stateManager) {
|
||||||
super();
|
super();
|
||||||
|
|
@ -75,7 +80,11 @@ public class BestInsertionBuilder implements InsertionStrategyBuilder{
|
||||||
return this;
|
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(){
|
public BestInsertionBuilder setLocalLevel(){
|
||||||
local = true;
|
local = true;
|
||||||
|
|
@ -101,11 +110,8 @@ public class BestInsertionBuilder implements InsertionStrategyBuilder{
|
||||||
calcBuilder.setLocalLevel();
|
calcBuilder.setLocalLevel();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
//add CostsUpdater
|
calcBuilder.setRouteLevel(forwaredLooking, memory);
|
||||||
|
|
||||||
}
|
}
|
||||||
// calcBuilder.setRouteLevel(forwardLooking, memory);
|
|
||||||
// }
|
|
||||||
calcBuilder.setConstraintManager(constraintManager);
|
calcBuilder.setConstraintManager(constraintManager);
|
||||||
calcBuilder.setStates(stateManager);
|
calcBuilder.setStates(stateManager);
|
||||||
calcBuilder.setVehicleRoutingProblem(vrp);
|
calcBuilder.setVehicleRoutingProblem(vrp);
|
||||||
|
|
@ -114,7 +120,7 @@ public class BestInsertionBuilder implements InsertionStrategyBuilder{
|
||||||
if(considerFixedCosts) {
|
if(considerFixedCosts) {
|
||||||
calcBuilder.considerFixedCosts(weightOfFixedCosts);
|
calcBuilder.considerFixedCosts(weightOfFixedCosts);
|
||||||
}
|
}
|
||||||
JobInsertionCalculator jobInsertions = calcBuilder.build();
|
JobInsertionCostsCalculator jobInsertions = calcBuilder.build();
|
||||||
BestInsertion bestInsertion = new BestInsertion(jobInsertions);
|
BestInsertion bestInsertion = new BestInsertion(jobInsertions);
|
||||||
for(InsertionListener l : iListeners) bestInsertion.addListener(l);
|
for(InsertionListener l : iListeners) bestInsertion.addListener(l);
|
||||||
return bestInsertion;
|
return bestInsertion;
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -27,11 +27,11 @@ import basics.route.Driver;
|
||||||
import basics.route.Vehicle;
|
import basics.route.Vehicle;
|
||||||
import basics.route.VehicleRoute;
|
import basics.route.VehicleRoute;
|
||||||
|
|
||||||
class CalculatesServiceInsertionWithTimeScheduling implements JobInsertionCalculator{
|
class CalculatesServiceInsertionWithTimeScheduling implements JobInsertionCostsCalculator{
|
||||||
|
|
||||||
private static Logger log = Logger.getLogger(CalculatesServiceInsertionWithTimeScheduling.class);
|
private static Logger log = Logger.getLogger(CalculatesServiceInsertionWithTimeScheduling.class);
|
||||||
|
|
||||||
private JobInsertionCalculator jic;
|
private JobInsertionCostsCalculator jic;
|
||||||
|
|
||||||
private Random random = new Random();
|
private Random random = new Random();
|
||||||
|
|
||||||
|
|
@ -39,7 +39,7 @@ class CalculatesServiceInsertionWithTimeScheduling implements JobInsertionCalcul
|
||||||
|
|
||||||
private double timeSlice = 900.0;
|
private double timeSlice = 900.0;
|
||||||
|
|
||||||
public CalculatesServiceInsertionWithTimeScheduling(JobInsertionCalculator jic, double timeSlice, int neighbors) {
|
public CalculatesServiceInsertionWithTimeScheduling(JobInsertionCostsCalculator jic, double timeSlice, int neighbors) {
|
||||||
super();
|
super();
|
||||||
this.jic = jic;
|
this.jic = jic;
|
||||||
this.timeSlice = timeSlice;
|
this.timeSlice = timeSlice;
|
||||||
|
|
@ -53,7 +53,7 @@ class CalculatesServiceInsertionWithTimeScheduling implements JobInsertionCalcul
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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>();
|
List<Double> vehicleDepartureTimes = new ArrayList<Double>();
|
||||||
double currentStart;
|
double currentStart;
|
||||||
if(currentRoute.getStart() == null){
|
if(currentRoute.getStart() == null){
|
||||||
|
|
@ -74,7 +74,7 @@ class CalculatesServiceInsertionWithTimeScheduling implements JobInsertionCalcul
|
||||||
|
|
||||||
InsertionData bestIData = null;
|
InsertionData bestIData = null;
|
||||||
for(Double departureTime : vehicleDepartureTimes){
|
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;
|
if(bestIData == null) bestIData = iData;
|
||||||
else if(iData.getInsertionCost() < bestIData.getInsertionCost()){
|
else if(iData.getInsertionCost() < bestIData.getInsertionCost()){
|
||||||
iData.setVehicleDepartureTime(departureTime);
|
iData.setVehicleDepartureTime(departureTime);
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ import java.util.List;
|
||||||
import basics.VehicleRoutingProblem;
|
import basics.VehicleRoutingProblem;
|
||||||
import basics.algo.InsertionListener;
|
import basics.algo.InsertionListener;
|
||||||
import basics.algo.VehicleRoutingAlgorithmListeners.PrioritizedVRAListener;
|
import basics.algo.VehicleRoutingAlgorithmListeners.PrioritizedVRAListener;
|
||||||
|
import basics.route.VehicleFleetManager;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -29,16 +30,16 @@ class CalculatorBuilder {
|
||||||
|
|
||||||
private static class CalculatorPlusListeners {
|
private static class CalculatorPlusListeners {
|
||||||
|
|
||||||
private JobInsertionCalculator calculator;
|
private JobInsertionCostsCalculator calculator;
|
||||||
|
|
||||||
public JobInsertionCalculator getCalculator() {
|
public JobInsertionCostsCalculator getCalculator() {
|
||||||
return calculator;
|
return calculator;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<PrioritizedVRAListener> algorithmListener = new ArrayList<PrioritizedVRAListener>();
|
private List<PrioritizedVRAListener> algorithmListener = new ArrayList<PrioritizedVRAListener>();
|
||||||
private List<InsertionListener> insertionListener = new ArrayList<InsertionListener>();
|
private List<InsertionListener> insertionListener = new ArrayList<InsertionListener>();
|
||||||
|
|
||||||
public CalculatorPlusListeners(JobInsertionCalculator calculator) {
|
public CalculatorPlusListeners(JobInsertionCostsCalculator calculator) {
|
||||||
super();
|
super();
|
||||||
this.calculator = calculator;
|
this.calculator = calculator;
|
||||||
}
|
}
|
||||||
|
|
@ -178,11 +179,11 @@ class CalculatorBuilder {
|
||||||
* @return jobInsertionCalculator.
|
* @return jobInsertionCalculator.
|
||||||
* @throws IllegalStateException if vrp == null or activityStates == null or fleetManager == null.
|
* @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(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(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))");
|
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;
|
CalculatorPlusListeners standardLocal = null;
|
||||||
if(local){
|
if(local){
|
||||||
standardLocal = createStandardLocal(vrp, states);
|
standardLocal = createStandardLocal(vrp, states);
|
||||||
|
|
@ -228,14 +229,14 @@ class CalculatorBuilder {
|
||||||
actInsertionCalc = activityInsertionCostCalculator;
|
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());
|
((ServiceInsertionCalculator) standardServiceInsertion).setNeighborhood(vrp.getNeighborhood());
|
||||||
CalculatorPlusListeners calcPlusListeners = new CalculatorPlusListeners(standardServiceInsertion);
|
CalculatorPlusListeners calcPlusListeners = new CalculatorPlusListeners(standardServiceInsertion);
|
||||||
|
|
||||||
return calcPlusListeners;
|
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);
|
final JobInsertionConsideringFixCostsCalculator withFixCost = new JobInsertionConsideringFixCostsCalculator(baseCalculator, activityStates2);
|
||||||
withFixCost.setWeightOfFixCost(weightOfFixedCosts);
|
withFixCost.setWeightOfFixCost(weightOfFixedCosts);
|
||||||
CalculatorPlusListeners calcPlusListeners = new CalculatorPlusListeners(withFixCost);
|
CalculatorPlusListeners calcPlusListeners = new CalculatorPlusListeners(withFixCost);
|
||||||
|
|
@ -252,7 +253,7 @@ class CalculatorBuilder {
|
||||||
else{
|
else{
|
||||||
routeLevelCostEstimator = activityInsertionCostCalculator;
|
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).setNuOfActsForwardLooking(after);
|
||||||
((ServiceInsertionOnRouteLevelCalculator)jobInsertionCalculator).setMemorySize(solutionMemory);
|
((ServiceInsertionOnRouteLevelCalculator)jobInsertionCalculator).setMemorySize(solutionMemory);
|
||||||
((ServiceInsertionOnRouteLevelCalculator)jobInsertionCalculator).setNeighborhood(vrp.getNeighborhood());
|
((ServiceInsertionOnRouteLevelCalculator)jobInsertionCalculator).setNeighborhood(vrp.getNeighborhood());
|
||||||
|
|
@ -261,7 +262,7 @@ class CalculatorBuilder {
|
||||||
return calcPlusListener;
|
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);
|
return new VehicleTypeDependentJobInsertionCalculator(fleetManager, baseCalc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -24,6 +24,7 @@ import org.apache.log4j.Logger;
|
||||||
import basics.route.TourActivities;
|
import basics.route.TourActivities;
|
||||||
import basics.route.TourActivity;
|
import basics.route.TourActivity;
|
||||||
import basics.route.Vehicle;
|
import basics.route.Vehicle;
|
||||||
|
import basics.route.VehicleFleetManager;
|
||||||
import basics.route.VehicleImpl.NoVehicle;
|
import basics.route.VehicleImpl.NoVehicle;
|
||||||
import basics.route.VehicleRoute;
|
import basics.route.VehicleRoute;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ import basics.algo.RuinListener;
|
||||||
import basics.algo.SearchStrategyModule;
|
import basics.algo.SearchStrategyModule;
|
||||||
import basics.algo.SearchStrategyModuleListener;
|
import basics.algo.SearchStrategyModuleListener;
|
||||||
import basics.route.TourActivity;
|
import basics.route.TourActivity;
|
||||||
|
import basics.route.VehicleFleetManager;
|
||||||
import basics.route.TourActivity.JobActivity;
|
import basics.route.TourActivity.JobActivity;
|
||||||
import basics.route.VehicleRoute;
|
import basics.route.VehicleRoute;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,9 +19,14 @@ package algorithms;
|
||||||
import basics.route.Driver;
|
import basics.route.Driver;
|
||||||
import basics.route.Vehicle;
|
import basics.route.Vehicle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data object that collects insertion information. It collects insertionCosts, insertionIndeces, vehicle and driver to be employed
|
||||||
class InsertionData {
|
* and departureTime of vehicle at vehicle's start location (e.g. depot).
|
||||||
|
*
|
||||||
|
* @author stefan
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class InsertionData {
|
||||||
|
|
||||||
static class NoInsertionFound extends InsertionData{
|
static class NoInsertionFound extends InsertionData{
|
||||||
|
|
||||||
|
|
@ -33,7 +38,15 @@ class InsertionData {
|
||||||
|
|
||||||
private static InsertionData noInsertion = new NoInsertionFound();
|
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;
|
return noInsertion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -80,22 +93,47 @@ class InsertionData {
|
||||||
return "[iCost="+insertionCost+"][iIndex="+deliveryInsertionIndex+"][depTime="+departureTime+"][vehicle="+selectedVehicle+"][driver="+selectedDriver+"]";
|
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(){
|
public int getDeliveryInsertionIndex(){
|
||||||
return deliveryInsertionIndex;
|
return deliveryInsertionIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns insertionIndex of pickkupActivity. If no insertionPosition is found, it returns NO_INDEX (=-1).
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
public int getPickupInsertionIndex(){
|
public int getPickupInsertionIndex(){
|
||||||
return pickupInsertionIndex;
|
return pickupInsertionIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns insertion costs (which might be the additional costs of inserting the corresponding job).
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
public double getInsertionCost() {
|
public double getInsertionCost() {
|
||||||
return insertionCost;
|
return insertionCost;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the vehicle to be employed.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
public Vehicle getSelectedVehicle() {
|
public Vehicle getSelectedVehicle() {
|
||||||
return selectedVehicle;
|
return selectedVehicle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the vehicle to be employed.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
public Driver getSelectedDriver(){
|
public Driver getSelectedDriver(){
|
||||||
return selectedDriver;
|
return selectedDriver;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ import org.apache.log4j.Logger;
|
||||||
import basics.VehicleRoutingProblem;
|
import basics.VehicleRoutingProblem;
|
||||||
import basics.algo.InsertionListener;
|
import basics.algo.InsertionListener;
|
||||||
import basics.algo.VehicleRoutingAlgorithmListeners.PrioritizedVRAListener;
|
import basics.algo.VehicleRoutingAlgorithmListeners.PrioritizedVRAListener;
|
||||||
|
import basics.route.VehicleFleetManager;
|
||||||
|
|
||||||
class InsertionFactory {
|
class InsertionFactory {
|
||||||
|
|
||||||
|
|
@ -87,7 +88,7 @@ class InsertionFactory {
|
||||||
calcBuilder.experimentalTimeScheduler(Double.parseDouble(timeSliceString),Integer.parseInt(neighbors));
|
calcBuilder.experimentalTimeScheduler(Double.parseDouble(timeSliceString),Integer.parseInt(neighbors));
|
||||||
}
|
}
|
||||||
|
|
||||||
JobInsertionCalculator jic = calcBuilder.build();
|
JobInsertionCostsCalculator jic = calcBuilder.build();
|
||||||
|
|
||||||
|
|
||||||
if(insertionName.equals("bestInsertion")){
|
if(insertionName.equals("bestInsertion")){
|
||||||
|
|
|
||||||
|
|
@ -40,51 +40,35 @@ import org.apache.log4j.Logger;
|
||||||
import basics.Job;
|
import basics.Job;
|
||||||
import basics.VehicleRoutingProblem;
|
import basics.VehicleRoutingProblem;
|
||||||
import basics.VehicleRoutingProblemSolution;
|
import basics.VehicleRoutingProblemSolution;
|
||||||
import basics.route.DriverImpl;
|
import basics.algo.SolutionCostCalculator;
|
||||||
import basics.route.TourActivities;
|
|
||||||
import basics.route.Vehicle;
|
|
||||||
import basics.route.VehicleRoute;
|
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 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();
|
super();
|
||||||
this.insertion = insertionStrategy;
|
this.insertion = insertionStrategy;
|
||||||
|
this.solutionCostsCalculator = solutionCostCalculator;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VehicleRoutingProblemSolution createSolution(final VehicleRoutingProblem vrp) {
|
public VehicleRoutingProblemSolution createSolution(final VehicleRoutingProblem vrp) {
|
||||||
logger.info("create initial solution.");
|
logger.info("create initial solution.");
|
||||||
List<VehicleRoute> vehicleRoutes = new ArrayList<VehicleRoute>();
|
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));
|
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");
|
logger.info("creation done");
|
||||||
return new VehicleRoutingProblemSolution(vehicleRoutes, totalCost);
|
return solution;
|
||||||
}
|
|
||||||
|
|
||||||
private double getTotalCost(List<VehicleRoute> serviceProviders) {
|
|
||||||
double c = 0.0;
|
|
||||||
for(VehicleRoute a : serviceProviders){
|
|
||||||
c += a.getCost();
|
|
||||||
}
|
|
||||||
return c;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Job> getUnassignedJobs(VehicleRoutingProblem vrp) {
|
private List<Job> getUnassignedJobs(VehicleRoutingProblem vrp) {
|
||||||
|
|
@ -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); }
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -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 static final Logger logger = Logger.getLogger(JobInsertionConsideringFixCostsCalculator.class);
|
||||||
|
|
||||||
private final JobInsertionCalculator standardServiceInsertion;
|
private final JobInsertionCostsCalculator standardServiceInsertion;
|
||||||
|
|
||||||
private double weight_deltaFixCost = 0.5;
|
private double weight_deltaFixCost = 0.5;
|
||||||
|
|
||||||
|
|
@ -39,7 +39,7 @@ final class JobInsertionConsideringFixCostsCalculator implements JobInsertionCal
|
||||||
|
|
||||||
private StateGetter stateGetter;
|
private StateGetter stateGetter;
|
||||||
|
|
||||||
public JobInsertionConsideringFixCostsCalculator(final JobInsertionCalculator standardInsertionCalculator, StateGetter stateGetter) {
|
public JobInsertionConsideringFixCostsCalculator(final JobInsertionCostsCalculator standardInsertionCalculator, StateGetter stateGetter) {
|
||||||
super();
|
super();
|
||||||
this.standardServiceInsertion = standardInsertionCalculator;
|
this.standardServiceInsertion = standardInsertionCalculator;
|
||||||
this.stateGetter = stateGetter;
|
this.stateGetter = stateGetter;
|
||||||
|
|
@ -47,15 +47,15 @@ final class JobInsertionConsideringFixCostsCalculator implements JobInsertionCal
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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 relFixCost = getDeltaRelativeFixCost(currentRoute, newVehicle, jobToInsert);
|
||||||
double absFixCost = getDeltaAbsoluteFixCost(currentRoute, newVehicle, jobToInsert);
|
double absFixCost = getDeltaAbsoluteFixCost(currentRoute, newVehicle, jobToInsert);
|
||||||
double deltaFixCost = (1-solution_completeness_ratio)*relFixCost + solution_completeness_ratio*absFixCost;
|
double deltaFixCost = (1-solution_completeness_ratio)*relFixCost + solution_completeness_ratio*absFixCost;
|
||||||
double fixcost_contribution = weight_deltaFixCost*solution_completeness_ratio*deltaFixCost;
|
double fixcost_contribution = weight_deltaFixCost*solution_completeness_ratio*deltaFixCost;
|
||||||
if(fixcost_contribution > bestKnownPrice){
|
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){
|
if(iData instanceof NoInsertionFound){
|
||||||
return iData;
|
return iData;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,8 @@ import basics.route.Vehicle;
|
||||||
import basics.route.VehicleRoute;
|
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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -47,7 +47,7 @@ class LocalActivityInsertionCostsCalculator implements ActivityInsertionCostsCal
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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_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());
|
double tp_time_prevAct_newAct = routingCosts.getTransportTime(prevAct.getLocationId(), newAct.getLocationId(), depTimeAtPrevAct, iFacts.getNewDriver(), iFacts.getNewVehicle());
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,10 @@ import java.util.List;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import basics.algo.InsertionEndsListener;
|
import basics.algo.InsertionEndsListener;
|
||||||
|
import basics.route.VehicleFleetManager;
|
||||||
import basics.route.VehicleRoute;
|
import basics.route.VehicleRoute;
|
||||||
|
|
||||||
public class RemoveEmptyVehicles implements InsertionEndsListener{
|
class RemoveEmptyVehicles implements InsertionEndsListener{
|
||||||
|
|
||||||
private static Logger log = Logger.getLogger(RemoveEmptyVehicles.class);
|
private static Logger log = Logger.getLogger(RemoveEmptyVehicles.class);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import basics.Job;
|
import basics.Job;
|
||||||
import basics.algo.InsertionStartsListener;
|
import basics.algo.InsertionStartsListener;
|
||||||
|
import basics.route.VehicleFleetManager;
|
||||||
import basics.route.VehicleRoute;
|
import basics.route.VehicleRoute;
|
||||||
|
|
||||||
class ResetAndIniFleetManager implements InsertionStartsListener{
|
class ResetAndIniFleetManager implements InsertionStartsListener{
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ class RouteLevelActivityInsertionCostsEstimator implements ActivityInsertionCost
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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>();
|
List<TourActivity> path = new ArrayList<TourActivity>();
|
||||||
path.add(prevAct); path.add(newAct); path.add(nextAct);
|
path.add(prevAct); path.add(newAct); path.add(nextAct);
|
||||||
int actIndex;
|
int actIndex;
|
||||||
|
|
|
||||||
|
|
@ -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);
|
private static final Logger logger = Logger.getLogger(ServiceInsertionCalculator.class);
|
||||||
|
|
||||||
|
|
@ -85,13 +85,13 @@ final class ServiceInsertionCalculator implements JobInsertionCalculator{
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Override
|
@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(jobToInsert == null) throw new IllegalStateException("jobToInsert is missing.");
|
||||||
if(newVehicle == null || newVehicle instanceof NoVehicle) throw new IllegalStateException("newVehicle is missing.");
|
if(newVehicle == null || newVehicle instanceof NoVehicle) throw new IllegalStateException("newVehicle is missing.");
|
||||||
|
|
||||||
InsertionContext insertionContext = new InsertionContext(currentRoute, jobToInsert, newVehicle, newDriver, newVehicleDepartureTime);
|
InsertionContext insertionContext = new InsertionContext(currentRoute, jobToInsert, newVehicle, newDriver, newVehicleDepartureTime);
|
||||||
if(!hardRouteLevelConstraint.fulfilled(insertionContext)){
|
if(!hardRouteLevelConstraint.fulfilled(insertionContext)){
|
||||||
return InsertionData.noInsertionFound();
|
return InsertionData.createEmptyInsertionData();
|
||||||
}
|
}
|
||||||
|
|
||||||
double bestCost = bestKnownCosts;
|
double bestCost = bestKnownCosts;
|
||||||
|
|
@ -146,7 +146,7 @@ final class ServiceInsertionCalculator implements JobInsertionCalculator{
|
||||||
}
|
}
|
||||||
|
|
||||||
if(insertionIndex == InsertionData.NO_INDEX) {
|
if(insertionIndex == InsertionData.NO_INDEX) {
|
||||||
return InsertionData.noInsertionFound();
|
return InsertionData.createEmptyInsertionData();
|
||||||
}
|
}
|
||||||
InsertionData insertionData = new InsertionData(bestCost, InsertionData.NO_INDEX, insertionIndex, newVehicle, newDriver);
|
InsertionData insertionData = new InsertionData(bestCost, InsertionData.NO_INDEX, insertionIndex, newVehicle, newDriver);
|
||||||
insertionData.setVehicleDepartureTime(newVehicleDepartureTime);
|
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) {
|
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);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
private static final Logger logger = Logger.getLogger(ServiceInsertionOnRouteLevelCalculator.class);
|
||||||
|
|
||||||
|
|
@ -131,13 +131,13 @@ final class ServiceInsertionOnRouteLevelCalculator implements JobInsertionCalcul
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Override
|
@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(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!");
|
if(newVehicle == null || newVehicle instanceof NoVehicle) throw new IllegalStateException("no vehicle given. set para vehicle!");
|
||||||
|
|
||||||
InsertionContext insertionContext = new InsertionContext(currentRoute, jobToInsert, newVehicle, newDriver, newVehicleDepartureTime);
|
InsertionContext insertionContext = new InsertionContext(currentRoute, jobToInsert, newVehicle, newDriver, newVehicleDepartureTime);
|
||||||
if(!hardRouteLevelConstraint.fulfilled(insertionContext)){
|
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}
|
* 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)
|
* 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())){
|
if(neighborhood.areNeighbors(serviceAct2Insert.getLocationId(), prevAct.getLocationId()) && neighborhood.areNeighbors(serviceAct2Insert.getLocationId(), nextAct.getLocationId())){
|
||||||
ConstraintsStatus status = hardActivityLevelConstraint.fulfilled(insertionContext, prevAct, serviceAct2Insert, nextAct, prevActDepTime_newVehicle);
|
ConstraintsStatus status = hardActivityLevelConstraint.fulfilled(insertionContext, prevAct, serviceAct2Insert, nextAct, prevActDepTime_newVehicle);
|
||||||
if(status.equals(ConstraintsStatus.FULFILLED)){
|
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){
|
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)
|
* 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);
|
return new InsertionData(best_insertion_costs, InsertionData.NO_INDEX, best_insertion_index, newVehicle, newDriver);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,11 @@ import basics.algo.IterationStartsListener;
|
||||||
import basics.algo.JobInsertedListener;
|
import basics.algo.JobInsertedListener;
|
||||||
import basics.algo.RuinListener;
|
import basics.algo.RuinListener;
|
||||||
import basics.algo.RuinListeners;
|
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.TourActivity;
|
||||||
import basics.route.VehicleRoute;
|
import basics.route.VehicleRoute;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,10 @@ package algorithms;
|
||||||
|
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
import util.ActivityTimeTracker;
|
||||||
|
|
||||||
import basics.costs.ForwardTransportTime;
|
import basics.costs.ForwardTransportTime;
|
||||||
|
import basics.route.ActivityVisitor;
|
||||||
import basics.route.TourActivity;
|
import basics.route.TourActivity;
|
||||||
import basics.route.VehicleRoute;
|
import basics.route.VehicleRoute;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,13 @@ package algorithms;
|
||||||
|
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
import util.ActivityTimeTracker;
|
||||||
|
|
||||||
import algorithms.StateManager.StateImpl;
|
import algorithms.StateManager.StateImpl;
|
||||||
import basics.costs.ForwardTransportCost;
|
import basics.costs.ForwardTransportCost;
|
||||||
import basics.costs.VehicleRoutingActivityCosts;
|
import basics.costs.VehicleRoutingActivityCosts;
|
||||||
import basics.costs.VehicleRoutingTransportCosts;
|
import basics.costs.VehicleRoutingTransportCosts;
|
||||||
|
import basics.route.ActivityVisitor;
|
||||||
import basics.route.TourActivity;
|
import basics.route.TourActivity;
|
||||||
import basics.route.Vehicle;
|
import basics.route.Vehicle;
|
||||||
import basics.route.VehicleRoute;
|
import basics.route.VehicleRoute;
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import basics.algo.InsertionStartsListener;
|
||||||
import basics.algo.JobInsertedListener;
|
import basics.algo.JobInsertedListener;
|
||||||
import basics.costs.VehicleRoutingActivityCosts;
|
import basics.costs.VehicleRoutingActivityCosts;
|
||||||
import basics.costs.VehicleRoutingTransportCosts;
|
import basics.costs.VehicleRoutingTransportCosts;
|
||||||
|
import basics.route.RouteActivityVisitor;
|
||||||
import basics.route.VehicleRoute;
|
import basics.route.VehicleRoute;
|
||||||
|
|
||||||
class UpdateCostsAtRouteLevel implements StateUpdater,JobInsertedListener, InsertionStartsListener, InsertionEndsListener{
|
class UpdateCostsAtRouteLevel implements StateUpdater,JobInsertedListener, InsertionStartsListener, InsertionEndsListener{
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
package algorithms;
|
package algorithms;
|
||||||
|
|
||||||
|
import util.ActivityTimeTracker;
|
||||||
import algorithms.StateManager.StateImpl;
|
import algorithms.StateManager.StateImpl;
|
||||||
import basics.costs.VehicleRoutingTransportCosts;
|
import basics.costs.VehicleRoutingTransportCosts;
|
||||||
|
import basics.route.ActivityVisitor;
|
||||||
import basics.route.TourActivity;
|
import basics.route.TourActivity;
|
||||||
import basics.route.VehicleRoute;
|
import basics.route.VehicleRoute;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package algorithms;
|
package algorithms;
|
||||||
|
|
||||||
import basics.route.PickupActivity;
|
import basics.route.PickupActivity;
|
||||||
|
import basics.route.ReverseActivityVisitor;
|
||||||
import basics.route.ServiceActivity;
|
import basics.route.ServiceActivity;
|
||||||
import basics.route.TourActivity;
|
import basics.route.TourActivity;
|
||||||
import basics.route.VehicleRoute;
|
import basics.route.VehicleRoute;
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import algorithms.StateManager.StateImpl;
|
import algorithms.StateManager.StateImpl;
|
||||||
import basics.costs.VehicleRoutingTransportCosts;
|
import basics.costs.VehicleRoutingTransportCosts;
|
||||||
|
import basics.route.ReverseActivityVisitor;
|
||||||
import basics.route.TourActivity;
|
import basics.route.TourActivity;
|
||||||
import basics.route.VehicleRoute;
|
import basics.route.VehicleRoute;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package algorithms;
|
package algorithms;
|
||||||
|
|
||||||
import algorithms.StateManager.StateImpl;
|
import algorithms.StateManager.StateImpl;
|
||||||
|
import basics.route.ActivityVisitor;
|
||||||
import basics.route.TourActivity;
|
import basics.route.TourActivity;
|
||||||
import basics.route.VehicleRoute;
|
import basics.route.VehicleRoute;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package algorithms;
|
package algorithms;
|
||||||
|
|
||||||
import algorithms.StateManager.StateImpl;
|
import algorithms.StateManager.StateImpl;
|
||||||
|
import basics.route.ActivityVisitor;
|
||||||
import basics.route.TourActivity;
|
import basics.route.TourActivity;
|
||||||
import basics.route.VehicleRoute;
|
import basics.route.VehicleRoute;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package algorithms;
|
package algorithms;
|
||||||
|
|
||||||
|
import basics.route.ActivityVisitor;
|
||||||
import basics.route.TourActivity;
|
import basics.route.TourActivity;
|
||||||
import basics.route.VehicleRoute;
|
import basics.route.VehicleRoute;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package algorithms;
|
package algorithms;
|
||||||
|
|
||||||
import algorithms.StateManager.StateImpl;
|
import algorithms.StateManager.StateImpl;
|
||||||
|
import basics.route.ActivityVisitor;
|
||||||
import basics.route.DeliveryActivity;
|
import basics.route.DeliveryActivity;
|
||||||
import basics.route.TourActivity;
|
import basics.route.TourActivity;
|
||||||
import basics.route.VehicleRoute;
|
import basics.route.VehicleRoute;
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,11 @@ import basics.VehicleRoutingProblemSolution;
|
||||||
import basics.algo.SolutionCostCalculator;
|
import basics.algo.SolutionCostCalculator;
|
||||||
import basics.route.VehicleRoute;
|
import basics.route.VehicleRoute;
|
||||||
|
|
||||||
public class SolutionCostCalculatorFactory {
|
public class VariablePlusFixedSolutionCostCalculatorFactory {
|
||||||
|
|
||||||
private StateManager stateManager;
|
private StateManager stateManager;
|
||||||
|
|
||||||
public SolutionCostCalculatorFactory(StateManager stateManager) {
|
public VariablePlusFixedSolutionCostCalculatorFactory(StateManager stateManager) {
|
||||||
super();
|
super();
|
||||||
this.stateManager = stateManager;
|
this.stateManager = stateManager;
|
||||||
}
|
}
|
||||||
|
|
@ -17,13 +17,13 @@ public class SolutionCostCalculatorFactory {
|
||||||
return new SolutionCostCalculator() {
|
return new SolutionCostCalculator() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void calculateCosts(VehicleRoutingProblemSolution solution) {
|
public double getCosts(VehicleRoutingProblemSolution solution) {
|
||||||
double c = 0.0;
|
double c = 0.0;
|
||||||
for(VehicleRoute r : solution.getRoutes()){
|
for(VehicleRoute r : solution.getRoutes()){
|
||||||
c += stateManager.getRouteState(r, StateFactory.COSTS).toDouble();
|
c += stateManager.getRouteState(r, StateFactory.COSTS).toDouble();
|
||||||
c += r.getVehicle().getType().getVehicleCostParams().fix;
|
c += r.getVehicle().getType().getVehicleCostParams().fix;
|
||||||
}
|
}
|
||||||
solution.setCost(c);
|
return c;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -7,6 +7,7 @@ import basics.VehicleRoutingAlgorithm;
|
||||||
import basics.VehicleRoutingProblem;
|
import basics.VehicleRoutingProblem;
|
||||||
import basics.algo.SearchStrategyManager;
|
import basics.algo.SearchStrategyManager;
|
||||||
import basics.algo.VehicleRoutingAlgorithmListener;
|
import basics.algo.VehicleRoutingAlgorithmListener;
|
||||||
|
import basics.route.VehicleFleetManager;
|
||||||
|
|
||||||
public class VehicleRoutingAlgorithmBuilder {
|
public class VehicleRoutingAlgorithmBuilder {
|
||||||
|
|
||||||
|
|
@ -17,12 +18,15 @@ public class VehicleRoutingAlgorithmBuilder {
|
||||||
private StateManager stateManager;
|
private StateManager stateManager;
|
||||||
|
|
||||||
private Collection<VehicleRoutingAlgorithmListener> listeners = new ArrayList<VehicleRoutingAlgorithmListener>();
|
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();
|
super();
|
||||||
this.vrp = vrp;
|
this.vrp = vrp;
|
||||||
this.searchStrategyManager = searchStrategyManager;
|
this.searchStrategyManager = searchStrategyManager;
|
||||||
this.stateManager = stateManager;
|
this.stateManager = stateManager;
|
||||||
|
this.fleetManager = vehicleFleetManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addListener(VehicleRoutingAlgorithmListener listener){
|
public void addListener(VehicleRoutingAlgorithmListener listener){
|
||||||
|
|
@ -33,6 +37,7 @@ public class VehicleRoutingAlgorithmBuilder {
|
||||||
VehicleRoutingAlgorithm algorithm = new VehicleRoutingAlgorithm(vrp, searchStrategyManager);
|
VehicleRoutingAlgorithm algorithm = new VehicleRoutingAlgorithm(vrp, searchStrategyManager);
|
||||||
algorithm.getAlgorithmListeners().addListener(stateManager);
|
algorithm.getAlgorithmListeners().addListener(stateManager);
|
||||||
algorithm.getSearchStrategyManager().addSearchStrategyModuleListener(stateManager);
|
algorithm.getSearchStrategyManager().addSearchStrategyModuleListener(stateManager);
|
||||||
|
algorithm.getSearchStrategyManager().addSearchStrategyModuleListener(new RemoveEmptyVehicles(fleetManager));
|
||||||
return algorithm;
|
return algorithm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,8 +31,6 @@ import org.apache.commons.configuration.HierarchicalConfiguration;
|
||||||
import org.apache.commons.configuration.XMLConfiguration;
|
import org.apache.commons.configuration.XMLConfiguration;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import algorithms.VehicleRoutingAlgorithms.TypedMap.AbstractKey;
|
import algorithms.VehicleRoutingAlgorithms.TypedMap.AbstractKey;
|
||||||
import algorithms.VehicleRoutingAlgorithms.TypedMap.AcceptorKey;
|
import algorithms.VehicleRoutingAlgorithms.TypedMap.AcceptorKey;
|
||||||
import algorithms.VehicleRoutingAlgorithms.TypedMap.InsertionStrategyKey;
|
import algorithms.VehicleRoutingAlgorithms.TypedMap.InsertionStrategyKey;
|
||||||
|
|
@ -66,7 +64,10 @@ import basics.algo.VehicleRoutingAlgorithmListeners.PrioritizedVRAListener;
|
||||||
import basics.algo.VehicleRoutingAlgorithmListeners.Priority;
|
import basics.algo.VehicleRoutingAlgorithmListeners.Priority;
|
||||||
import basics.io.AlgorithmConfig;
|
import basics.io.AlgorithmConfig;
|
||||||
import basics.io.AlgorithmConfigXmlReader;
|
import basics.io.AlgorithmConfigXmlReader;
|
||||||
|
import basics.route.FiniteFleetManagerFactory;
|
||||||
|
import basics.route.InfiniteFleetManagerFactory;
|
||||||
import basics.route.Vehicle;
|
import basics.route.Vehicle;
|
||||||
|
import basics.route.VehicleFleetManager;
|
||||||
import basics.route.VehicleRoute;
|
import basics.route.VehicleRoute;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -492,23 +493,6 @@ public class VehicleRoutingAlgorithms {
|
||||||
* define stateUpdates
|
* 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 UpdateLoadsAtStartAndEndOfRouteWhenInsertionStarts(stateManager));
|
||||||
stateManager.addListener(new UpdateLoadsAtStartAndEndOfRouteWhenJobHasBeenInserted(stateManager));
|
stateManager.addListener(new UpdateLoadsAtStartAndEndOfRouteWhenJobHasBeenInserted(stateManager));
|
||||||
|
|
||||||
|
|
@ -546,14 +530,12 @@ public class VehicleRoutingAlgorithms {
|
||||||
SolutionCostCalculator calc = new SolutionCostCalculator() {
|
SolutionCostCalculator calc = new SolutionCostCalculator() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void calculateCosts(VehicleRoutingProblemSolution solution) {
|
public double getCosts(VehicleRoutingProblemSolution solution) {
|
||||||
double costs = 0.0;
|
double costs = 0.0;
|
||||||
for(VehicleRoute route : solution.getRoutes()){
|
for(VehicleRoute route : solution.getRoutes()){
|
||||||
|
|
||||||
costs += stateManager.getRouteState(route, StateFactory.COSTS).toDouble() + getFixedCosts(route.getVehicle());
|
costs += stateManager.getRouteState(route, StateFactory.COSTS).toDouble() + getFixedCosts(route.getVehicle());
|
||||||
|
|
||||||
}
|
}
|
||||||
solution.setCost(costs);
|
return costs;
|
||||||
}
|
}
|
||||||
|
|
||||||
private double getFixedCosts(Vehicle vehicle) {
|
private double getFixedCosts(Vehicle vehicle) {
|
||||||
|
|
@ -567,11 +549,11 @@ public class VehicleRoutingAlgorithms {
|
||||||
|
|
||||||
private static VehicleFleetManager createFleetManager(final VehicleRoutingProblem vrp) {
|
private static VehicleFleetManager createFleetManager(final VehicleRoutingProblem vrp) {
|
||||||
if(vrp.getFleetSize().equals(FleetSize.INFINITE)){
|
if(vrp.getFleetSize().equals(FleetSize.INFINITE)){
|
||||||
return new InfiniteVehicles(vrp.getVehicles());
|
return new InfiniteFleetManagerFactory(vrp.getVehicles()).createFleetManager();
|
||||||
|
|
||||||
}
|
}
|
||||||
else if(vrp.getFleetSize().equals(FleetSize.FINITE)){
|
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. " +
|
throw new IllegalStateException("fleet size can only be infinite or finite. " +
|
||||||
"makes sure your config file contains one of these options");
|
"makes sure your config file contains one of these options");
|
||||||
|
|
@ -669,11 +651,11 @@ public class VehicleRoutingAlgorithms {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void informAlgorithmStarts(VehicleRoutingProblem problem, VehicleRoutingAlgorithm algorithm, Collection<VehicleRoutingProblemSolution> solutions) {
|
public void informAlgorithmStarts(VehicleRoutingProblem problem, VehicleRoutingAlgorithm algorithm, Collection<VehicleRoutingProblemSolution> solutions) {
|
||||||
|
InsertionInitialSolutionFactory insertionInitialSolutionFactory = new InsertionInitialSolutionFactory(finalInsertionStrategy, getCostCalculator(routeStates));
|
||||||
CreateInitialSolution createInitialSolution = new CreateInitialSolution(finalInsertionStrategy, getCostCalculator(routeStates));
|
// CreateInitialSolution createInitialSolution = new CreateInitialSolution(finalInsertionStrategy, getCostCalculator(routeStates));
|
||||||
|
//
|
||||||
createInitialSolution.setGenerateAsMuchAsRoutesAsVehiclesExist(false);
|
// createInitialSolution.setGenerateAsMuchAsRoutesAsVehiclesExist(false);
|
||||||
VehicleRoutingProblemSolution vrpSol = createInitialSolution.createSolution(vrp);
|
VehicleRoutingProblemSolution vrpSol = insertionInitialSolutionFactory.createSolution(vrp);
|
||||||
solutions.add(vrpSol);
|
solutions.add(vrpSol);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
package algorithms;
|
package algorithms;
|
||||||
|
|
||||||
import basics.route.Vehicle;
|
import basics.route.Vehicle;
|
||||||
|
import basics.route.VehicleFleetManager;
|
||||||
import basics.route.VehicleRoute;
|
import basics.route.VehicleRoute;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,20 +25,21 @@ import algorithms.InsertionData.NoInsertionFound;
|
||||||
import basics.Job;
|
import basics.Job;
|
||||||
import basics.route.Driver;
|
import basics.route.Driver;
|
||||||
import basics.route.Vehicle;
|
import basics.route.Vehicle;
|
||||||
|
import basics.route.VehicleFleetManager;
|
||||||
import basics.route.VehicleImpl.NoVehicle;
|
import basics.route.VehicleImpl.NoVehicle;
|
||||||
import basics.route.VehicleRoute;
|
import basics.route.VehicleRoute;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
final class VehicleTypeDependentJobInsertionCalculator implements JobInsertionCalculator{
|
final class VehicleTypeDependentJobInsertionCalculator implements JobInsertionCostsCalculator{
|
||||||
|
|
||||||
private Logger logger = Logger.getLogger(VehicleTypeDependentJobInsertionCalculator.class);
|
private Logger logger = Logger.getLogger(VehicleTypeDependentJobInsertionCalculator.class);
|
||||||
|
|
||||||
private final VehicleFleetManager fleetManager;
|
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.fleetManager = fleetManager;
|
||||||
this.insertionCalculator = jobInsertionCalc;
|
this.insertionCalculator = jobInsertionCalc;
|
||||||
logger.info("inialise " + this);
|
logger.info("inialise " + this);
|
||||||
|
|
@ -49,10 +50,10 @@ final class VehicleTypeDependentJobInsertionCalculator implements JobInsertionCa
|
||||||
return "[name=vehicleTypeDependentServiceInsertion]";
|
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();
|
Vehicle selectedVehicle = currentRoute.getVehicle();
|
||||||
Driver selectedDriver = currentRoute.getDriver();
|
Driver selectedDriver = currentRoute.getDriver();
|
||||||
InsertionData bestIData = InsertionData.noInsertionFound();
|
InsertionData bestIData = InsertionData.createEmptyInsertionData();
|
||||||
double bestKnownCost_ = bestKnownCost;
|
double bestKnownCost_ = bestKnownCost;
|
||||||
Collection<Vehicle> relevantVehicles = new ArrayList<Vehicle>();
|
Collection<Vehicle> relevantVehicles = new ArrayList<Vehicle>();
|
||||||
if(!(selectedVehicle instanceof NoVehicle)) {
|
if(!(selectedVehicle instanceof NoVehicle)) {
|
||||||
|
|
@ -65,7 +66,7 @@ final class VehicleTypeDependentJobInsertionCalculator implements JobInsertionCa
|
||||||
|
|
||||||
for(Vehicle v : relevantVehicles){
|
for(Vehicle v : relevantVehicles){
|
||||||
double depTime = v.getEarliestDeparture();
|
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(iData instanceof NoInsertionFound) {
|
||||||
if(bestIData instanceof NoInsertionFound) bestIData = iData;
|
if(bestIData instanceof NoInsertionFound) bestIData = iData;
|
||||||
continue;
|
continue;
|
||||||
|
|
|
||||||
|
|
@ -125,7 +125,8 @@ public class SearchStrategy {
|
||||||
VehicleRoutingProblemSolution newSolution = module.runAndGetSolution(lastSolution);
|
VehicleRoutingProblemSolution newSolution = module.runAndGetSolution(lastSolution);
|
||||||
lastSolution = newSolution;
|
lastSolution = newSolution;
|
||||||
}
|
}
|
||||||
solutionCostCalculator.calculateCosts(lastSolution);
|
double costs = solutionCostCalculator.getCosts(lastSolution);
|
||||||
|
lastSolution.setCost(costs);
|
||||||
boolean solutionAccepted = solutionAcceptor.acceptSolution(solutions, lastSolution);
|
boolean solutionAccepted = solutionAcceptor.acceptSolution(solutions, lastSolution);
|
||||||
DiscoveredSolution discoveredSolution = new DiscoveredSolution(lastSolution, solutionAccepted, getName());
|
DiscoveredSolution discoveredSolution = new DiscoveredSolution(lastSolution, solutionAccepted, getName());
|
||||||
return discoveredSolution;
|
return discoveredSolution;
|
||||||
|
|
|
||||||
|
|
@ -21,10 +21,11 @@ import basics.VehicleRoutingProblemSolution;
|
||||||
public interface SolutionCostCalculator {
|
public interface SolutionCostCalculator {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This assumes that the solution is modified by setting its costs <br>
|
* Returns costs of solution.
|
||||||
* <code>solution.setCost(costs);</code>
|
*
|
||||||
* @param solution
|
* @param solution
|
||||||
|
* @return TODO
|
||||||
*/
|
*/
|
||||||
public void calculateCosts(VehicleRoutingProblemSolution solution);
|
public double getCosts(VehicleRoutingProblemSolution solution);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,10 +14,8 @@
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* 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/>.
|
* 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 {
|
public interface ActivityVisitor {
|
||||||
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
package algorithms;
|
package basics.route;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import basics.route.Vehicle;
|
|
||||||
|
|
||||||
public class FiniteFleetManagerFactory implements VehicleFleetManagerFactory{
|
public class FiniteFleetManagerFactory implements VehicleFleetManagerFactory{
|
||||||
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
package algorithms;
|
package basics.route;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import basics.route.Vehicle;
|
|
||||||
|
|
||||||
public class InfiniteFleetManagerFactory implements VehicleFleetManagerFactory{
|
public class InfiniteFleetManagerFactory implements VehicleFleetManagerFactory{
|
||||||
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* 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/>.
|
* 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.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
@ -24,20 +24,8 @@ import java.util.Map;
|
||||||
|
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import basics.route.Vehicle;
|
|
||||||
|
|
||||||
class InfiniteVehicles implements VehicleFleetManager{
|
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);
|
private static Logger logger = Logger.getLogger(InfiniteVehicles.class);
|
||||||
|
|
||||||
|
|
@ -62,7 +50,6 @@ class InfiniteVehicles implements VehicleFleetManager{
|
||||||
sortedTypes.add(typeKey);
|
sortedTypes.add(typeKey);
|
||||||
|
|
||||||
}
|
}
|
||||||
// Collections.sort(sortedTypes, new TypeKeyComparator());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -14,10 +14,8 @@
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* 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/>.
|
* 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 {
|
public interface ReverseActivityVisitor {
|
||||||
|
|
||||||
|
|
@ -14,14 +14,12 @@
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* 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/>.
|
* 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.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
import basics.route.TourActivity;
|
|
||||||
import basics.route.VehicleRoute;
|
|
||||||
|
|
||||||
public class ReverseRouteActivityVisitor implements RouteVisitor{
|
public class ReverseRouteActivityVisitor implements RouteVisitor{
|
||||||
|
|
||||||
|
|
@ -14,13 +14,11 @@
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* 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/>.
|
* 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.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import basics.route.TourActivity;
|
|
||||||
import basics.route.VehicleRoute;
|
|
||||||
|
|
||||||
public class RouteActivityVisitor implements RouteVisitor{
|
public class RouteActivityVisitor implements RouteVisitor{
|
||||||
|
|
||||||
|
|
@ -14,9 +14,8 @@
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* 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/>.
|
* 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 {
|
public interface RouteVisitor {
|
||||||
|
|
||||||
|
|
@ -113,6 +113,12 @@ public class TourActivities {
|
||||||
return Collections.unmodifiableSet(jobs);
|
return Collections.unmodifiableSet(jobs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if job is in jobList, otherwise false.
|
||||||
|
*
|
||||||
|
* @param job
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
public boolean servesJob(Job job) {
|
public boolean servesJob(Job job) {
|
||||||
return jobs.contains(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;
|
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) {
|
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 1 --> between start and act(0) --> act(0)
|
||||||
* if 2 && 2 <= acts.size --> between act(0) and act(1) --> act(1)
|
* if 2 && 2 <= acts.size --> between act(0) and act(1) --> act(1)
|
||||||
|
|
@ -170,6 +186,12 @@ public class TourActivities {
|
||||||
addJob(act);
|
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){
|
public void addActivity(TourActivity act){
|
||||||
if(tourActivities.contains(act)) throw new IllegalStateException("act " + act + " already in tour. cannot add act twice.");
|
if(tourActivities.contains(act)) throw new IllegalStateException("act " + act + " already in tour. cannot add act twice.");
|
||||||
tourActivities.add(act);
|
tourActivities.add(act);
|
||||||
|
|
@ -177,7 +199,6 @@ public class TourActivities {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addJob(TourActivity act) {
|
private void addJob(TourActivity act) {
|
||||||
|
|
||||||
if(act instanceof JobActivity){
|
if(act instanceof JobActivity){
|
||||||
Job job = ((JobActivity) act).getJob();
|
Job job = ((JobActivity) act).getJob();
|
||||||
jobs.add(job);
|
jobs.add(job);
|
||||||
|
|
@ -187,6 +208,11 @@ public class TourActivities {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns number of jobs.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
public int jobSize() {
|
public int jobSize() {
|
||||||
return jobs.size();
|
return jobs.size();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,11 +14,10 @@
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* 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/>.
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
package algorithms;
|
package basics.route;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import basics.route.Vehicle;
|
|
||||||
|
|
||||||
public interface VehicleFleetManager {
|
public interface VehicleFleetManager {
|
||||||
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package algorithms;
|
package basics.route;
|
||||||
|
|
||||||
public interface VehicleFleetManagerFactory {
|
public interface VehicleFleetManagerFactory {
|
||||||
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* 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/>.
|
* 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.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
@ -27,12 +27,11 @@ import java.util.Set;
|
||||||
|
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import basics.route.PenaltyVehicleType;
|
|
||||||
import basics.route.Vehicle;
|
|
||||||
import basics.route.VehicleImpl.NoVehicle;
|
import basics.route.VehicleImpl.NoVehicle;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class VehicleFleetManagerImpl implements VehicleFleetManager {
|
class VehicleFleetManagerImpl implements VehicleFleetManager {
|
||||||
|
|
||||||
public VehicleFleetManagerImpl newInstance(Collection<Vehicle> vehicles){
|
public VehicleFleetManagerImpl newInstance(Collection<Vehicle> vehicles){
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package algorithms;
|
package basics.route;
|
||||||
|
|
||||||
class VehicleTypeKey {
|
class VehicleTypeKey {
|
||||||
|
|
||||||
|
|
@ -14,9 +14,10 @@
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* 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/>.
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
package algorithms;
|
package util;
|
||||||
|
|
||||||
import basics.costs.ForwardTransportTime;
|
import basics.costs.ForwardTransportTime;
|
||||||
|
import basics.route.ActivityVisitor;
|
||||||
import basics.route.TourActivity;
|
import basics.route.TourActivity;
|
||||||
import basics.route.VehicleRoute;
|
import basics.route.VehicleRoute;
|
||||||
|
|
||||||
|
|
@ -34,7 +34,9 @@ import basics.algo.SearchStrategy;
|
||||||
import basics.algo.SearchStrategyManager;
|
import basics.algo.SearchStrategyManager;
|
||||||
import basics.algo.SolutionCostCalculator;
|
import basics.algo.SolutionCostCalculator;
|
||||||
import basics.io.VrpXMLReader;
|
import basics.io.VrpXMLReader;
|
||||||
|
import basics.route.InfiniteFleetManagerFactory;
|
||||||
import basics.route.TourActivity;
|
import basics.route.TourActivity;
|
||||||
|
import basics.route.VehicleFleetManager;
|
||||||
import basics.route.VehicleRoute;
|
import basics.route.VehicleRoute;
|
||||||
|
|
||||||
public class BuildCVRPAlgoFromScratchTest {
|
public class BuildCVRPAlgoFromScratchTest {
|
||||||
|
|
@ -62,8 +64,8 @@ public class BuildCVRPAlgoFromScratchTest {
|
||||||
ServiceInsertionCalculator serviceInsertion = new ServiceInsertionCalculator(vrp.getTransportCosts(), marginalCalculus, new HardLoadConstraint(stateManager), hardActLevelConstraint);
|
ServiceInsertionCalculator serviceInsertion = new ServiceInsertionCalculator(vrp.getTransportCosts(), marginalCalculus, new HardLoadConstraint(stateManager), hardActLevelConstraint);
|
||||||
|
|
||||||
|
|
||||||
VehicleFleetManager fleetManager = new InfiniteVehicles(vrp.getVehicles());
|
VehicleFleetManager fleetManager = new InfiniteFleetManagerFactory(vrp.getVehicles()).createFleetManager();
|
||||||
JobInsertionCalculator finalServiceInsertion = new VehicleTypeDependentJobInsertionCalculator(fleetManager, serviceInsertion);
|
JobInsertionCostsCalculator finalServiceInsertion = new VehicleTypeDependentJobInsertionCalculator(fleetManager, serviceInsertion);
|
||||||
|
|
||||||
BestInsertion bestInsertion = new BestInsertion(finalServiceInsertion);
|
BestInsertion bestInsertion = new BestInsertion(finalServiceInsertion);
|
||||||
|
|
||||||
|
|
@ -73,12 +75,12 @@ public class BuildCVRPAlgoFromScratchTest {
|
||||||
SolutionCostCalculator solutionCostCalculator = new SolutionCostCalculator() {
|
SolutionCostCalculator solutionCostCalculator = new SolutionCostCalculator() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void calculateCosts(VehicleRoutingProblemSolution solution) {
|
public double getCosts(VehicleRoutingProblemSolution solution) {
|
||||||
double costs = 0.0;
|
double costs = 0.0;
|
||||||
for(VehicleRoute route : solution.getRoutes()){
|
for(VehicleRoute route : solution.getRoutes()){
|
||||||
costs += stateManager.getRouteState(route, StateFactory.COSTS).toDouble();
|
costs += stateManager.getRouteState(route, StateFactory.COSTS).toDouble();
|
||||||
}
|
}
|
||||||
solution.setCost(costs);
|
return costs;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -111,7 +113,7 @@ public class BuildCVRPAlgoFromScratchTest {
|
||||||
vra.getSearchStrategyManager().addSearchStrategyModuleListener(new UpdateLoadAtRouteLevel(stateManager));
|
vra.getSearchStrategyManager().addSearchStrategyModuleListener(new UpdateLoadAtRouteLevel(stateManager));
|
||||||
|
|
||||||
|
|
||||||
VehicleRoutingProblemSolution iniSolution = new CreateInitialSolution(bestInsertion, solutionCostCalculator).createSolution(vrp);
|
VehicleRoutingProblemSolution iniSolution = new InsertionInitialSolutionFactory(bestInsertion, solutionCostCalculator).createSolution(vrp);
|
||||||
|
|
||||||
// System.out.println("ini: costs="+iniSolution.getCost()+";#routes="+iniSolution.getRoutes().size());
|
// System.out.println("ini: costs="+iniSolution.getCost()+";#routes="+iniSolution.getRoutes().size());
|
||||||
vra.addInitialSolution(iniSolution);
|
vra.addInitialSolution(iniSolution);
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ import org.apache.log4j.Logger;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import util.Solutions;
|
||||||
import algorithms.StateManager.StateImpl;
|
import algorithms.StateManager.StateImpl;
|
||||||
import algorithms.acceptors.AcceptNewIfBetterThanWorst;
|
import algorithms.acceptors.AcceptNewIfBetterThanWorst;
|
||||||
import algorithms.selectors.SelectBest;
|
import algorithms.selectors.SelectBest;
|
||||||
|
|
@ -37,6 +38,10 @@ import basics.algo.SearchStrategy;
|
||||||
import basics.algo.SearchStrategyManager;
|
import basics.algo.SearchStrategyManager;
|
||||||
import basics.algo.SolutionCostCalculator;
|
import basics.algo.SolutionCostCalculator;
|
||||||
import basics.io.VrpXMLReader;
|
import basics.io.VrpXMLReader;
|
||||||
|
import basics.route.InfiniteFleetManagerFactory;
|
||||||
|
import basics.route.ReverseRouteActivityVisitor;
|
||||||
|
import basics.route.RouteActivityVisitor;
|
||||||
|
import basics.route.VehicleFleetManager;
|
||||||
import basics.route.VehicleRoute;
|
import basics.route.VehicleRoute;
|
||||||
|
|
||||||
public class BuildPDVRPAlgoFromScratchTest {
|
public class BuildPDVRPAlgoFromScratchTest {
|
||||||
|
|
@ -66,8 +71,8 @@ public class BuildPDVRPAlgoFromScratchTest {
|
||||||
ServiceInsertionCalculator serviceInsertion = new ServiceInsertionCalculator(vrp.getTransportCosts(), marginalCalculus, new HardPickupAndDeliveryLoadRouteLevelConstraint(stateManager), actLevelConstraintAccumulator);
|
ServiceInsertionCalculator serviceInsertion = new ServiceInsertionCalculator(vrp.getTransportCosts(), marginalCalculus, new HardPickupAndDeliveryLoadRouteLevelConstraint(stateManager), actLevelConstraintAccumulator);
|
||||||
// CalculatesServiceInsertion serviceInsertion = new CalculatesServiceInsertion(vrp.getTransportCosts(), marginalCalculus, new HardConstraints.HardLoadConstraint(stateManager));
|
// CalculatesServiceInsertion serviceInsertion = new CalculatesServiceInsertion(vrp.getTransportCosts(), marginalCalculus, new HardConstraints.HardLoadConstraint(stateManager));
|
||||||
|
|
||||||
VehicleFleetManager fleetManager = new InfiniteVehicles(vrp.getVehicles());
|
VehicleFleetManager fleetManager = new InfiniteFleetManagerFactory(vrp.getVehicles()).createFleetManager();
|
||||||
JobInsertionCalculator finalServiceInsertion = new VehicleTypeDependentJobInsertionCalculator(fleetManager, serviceInsertion);
|
JobInsertionCostsCalculator finalServiceInsertion = new VehicleTypeDependentJobInsertionCalculator(fleetManager, serviceInsertion);
|
||||||
|
|
||||||
BestInsertion bestInsertion = new BestInsertion(finalServiceInsertion);
|
BestInsertion bestInsertion = new BestInsertion(finalServiceInsertion);
|
||||||
|
|
||||||
|
|
@ -77,12 +82,12 @@ public class BuildPDVRPAlgoFromScratchTest {
|
||||||
SolutionCostCalculator solutionCostCalculator = new SolutionCostCalculator() {
|
SolutionCostCalculator solutionCostCalculator = new SolutionCostCalculator() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void calculateCosts(VehicleRoutingProblemSolution solution) {
|
public double getCosts(VehicleRoutingProblemSolution solution) {
|
||||||
double costs = 0.0;
|
double costs = 0.0;
|
||||||
for(VehicleRoute route : solution.getRoutes()){
|
for(VehicleRoute route : solution.getRoutes()){
|
||||||
costs += stateManager.getRouteState(route, StateFactory.COSTS).toDouble();
|
costs += stateManager.getRouteState(route, StateFactory.COSTS).toDouble();
|
||||||
}
|
}
|
||||||
solution.setCost(costs);
|
return costs;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -166,7 +171,7 @@ public class BuildPDVRPAlgoFromScratchTest {
|
||||||
bestInsertion.addListener(loadVehicleInDepot);
|
bestInsertion.addListener(loadVehicleInDepot);
|
||||||
bestInsertion.addListener(updateLoadAfterJobHasBeenInserted);
|
bestInsertion.addListener(updateLoadAfterJobHasBeenInserted);
|
||||||
|
|
||||||
VehicleRoutingProblemSolution iniSolution = new CreateInitialSolution(bestInsertion, solutionCostCalculator).createSolution(vrp);
|
VehicleRoutingProblemSolution iniSolution = new InsertionInitialSolutionFactory(bestInsertion, solutionCostCalculator).createSolution(vrp);
|
||||||
|
|
||||||
// System.out.println("ini: costs="+iniSolution.getCost()+";#routes="+iniSolution.getRoutes().size());
|
// System.out.println("ini: costs="+iniSolution.getCost()+";#routes="+iniSolution.getRoutes().size());
|
||||||
vra.addInitialSolution(iniSolution);
|
vra.addInitialSolution(iniSolution);
|
||||||
|
|
@ -179,7 +184,7 @@ public class BuildPDVRPAlgoFromScratchTest {
|
||||||
@Test
|
@Test
|
||||||
public void test(){
|
public void test(){
|
||||||
Collection<VehicleRoutingProblemSolution> solutions = vra.searchSolutions();
|
Collection<VehicleRoutingProblemSolution> solutions = vra.searchSolutions();
|
||||||
// System.out.println(Solutions.getBest(solutions).getCost());
|
System.out.println(Solutions.getBest(solutions).getCost());
|
||||||
// new VrpXMLWriter(vrp, solutions).write("output/pd_solomon_r101.xml");
|
// new VrpXMLWriter(vrp, solutions).write("output/pd_solomon_r101.xml");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ import org.junit.Test;
|
||||||
import basics.Service;
|
import basics.Service;
|
||||||
import basics.route.TimeWindow;
|
import basics.route.TimeWindow;
|
||||||
import basics.route.Vehicle;
|
import basics.route.Vehicle;
|
||||||
|
import basics.route.VehicleFleetManager;
|
||||||
import basics.route.VehicleImpl;
|
import basics.route.VehicleImpl;
|
||||||
import basics.route.VehicleRoute;
|
import basics.route.VehicleRoute;
|
||||||
import basics.route.VehicleTypeImpl;
|
import basics.route.VehicleTypeImpl;
|
||||||
|
|
@ -71,28 +72,28 @@ public class CalcVehicleTypeDependentServiceInsertionTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenHaving2Vehicle_calcInsertionOfCheapest(){
|
public void whenHaving2Vehicle_calcInsertionOfCheapest(){
|
||||||
JobInsertionCalculator calc = mock(JobInsertionCalculator.class);
|
JobInsertionCostsCalculator calc = mock(JobInsertionCostsCalculator.class);
|
||||||
InsertionData iDataVeh1 = new InsertionData(10.0,InsertionData.NO_INDEX, 1, veh1, null);
|
InsertionData iDataVeh1 = new InsertionData(10.0,InsertionData.NO_INDEX, 1, veh1, null);
|
||||||
InsertionData iDataVeh2 = new InsertionData(20.0,InsertionData.NO_INDEX, 1, veh2, null);
|
InsertionData iDataVeh2 = new InsertionData(20.0,InsertionData.NO_INDEX, 1, veh2, null);
|
||||||
when(calc.calculate(vehicleRoute, service, veh1, veh1.getEarliestDeparture(), null, Double.MAX_VALUE)).thenReturn(iDataVeh1);
|
when(calc.getInsertionData(vehicleRoute, service, veh1, veh1.getEarliestDeparture(), null, Double.MAX_VALUE)).thenReturn(iDataVeh1);
|
||||||
when(calc.calculate(vehicleRoute, service, veh2, veh2.getEarliestDeparture(), null, Double.MAX_VALUE)).thenReturn(iDataVeh2);
|
when(calc.getInsertionData(vehicleRoute, service, veh2, veh2.getEarliestDeparture(), null, Double.MAX_VALUE)).thenReturn(iDataVeh2);
|
||||||
when(calc.calculate(vehicleRoute, service, veh2, veh2.getEarliestDeparture(), null, 10.0)).thenReturn(iDataVeh2);
|
when(calc.getInsertionData(vehicleRoute, service, veh2, veh2.getEarliestDeparture(), null, 10.0)).thenReturn(iDataVeh2);
|
||||||
VehicleTypeDependentJobInsertionCalculator insertion = new VehicleTypeDependentJobInsertionCalculator(fleetManager,calc);
|
VehicleTypeDependentJobInsertionCalculator insertion = new VehicleTypeDependentJobInsertionCalculator(fleetManager,calc);
|
||||||
InsertionData iData = insertion.calculate(vehicleRoute, service, null, 0.0, null, Double.MAX_VALUE);
|
InsertionData iData = insertion.getInsertionData(vehicleRoute, service, null, 0.0, null, Double.MAX_VALUE);
|
||||||
assertThat(iData.getSelectedVehicle(), is(veh1));
|
assertThat(iData.getSelectedVehicle(), is(veh1));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenHaving2Vehicle_calcInsertionOfCheapest2(){
|
public void whenHaving2Vehicle_calcInsertionOfCheapest2(){
|
||||||
JobInsertionCalculator calc = mock(JobInsertionCalculator.class);
|
JobInsertionCostsCalculator calc = mock(JobInsertionCostsCalculator.class);
|
||||||
InsertionData iDataVeh1 = new InsertionData(20.0,InsertionData.NO_INDEX, 1, veh1, null);
|
InsertionData iDataVeh1 = new InsertionData(20.0,InsertionData.NO_INDEX, 1, veh1, null);
|
||||||
InsertionData iDataVeh2 = new InsertionData(10.0,InsertionData.NO_INDEX, 1, veh2, null);
|
InsertionData iDataVeh2 = new InsertionData(10.0,InsertionData.NO_INDEX, 1, veh2, null);
|
||||||
when(calc.calculate(vehicleRoute, service, veh1, veh1.getEarliestDeparture(), null, Double.MAX_VALUE)).thenReturn(iDataVeh1);
|
when(calc.getInsertionData(vehicleRoute, service, veh1, veh1.getEarliestDeparture(), null, Double.MAX_VALUE)).thenReturn(iDataVeh1);
|
||||||
when(calc.calculate(vehicleRoute, service, veh2, veh2.getEarliestDeparture(), null, Double.MAX_VALUE)).thenReturn(iDataVeh2);
|
when(calc.getInsertionData(vehicleRoute, service, veh2, veh2.getEarliestDeparture(), null, Double.MAX_VALUE)).thenReturn(iDataVeh2);
|
||||||
when(calc.calculate(vehicleRoute, service, veh2, veh2.getEarliestDeparture(), null, 20.0)).thenReturn(iDataVeh2);
|
when(calc.getInsertionData(vehicleRoute, service, veh2, veh2.getEarliestDeparture(), null, 20.0)).thenReturn(iDataVeh2);
|
||||||
VehicleTypeDependentJobInsertionCalculator insertion = new VehicleTypeDependentJobInsertionCalculator(fleetManager,calc);
|
VehicleTypeDependentJobInsertionCalculator insertion = new VehicleTypeDependentJobInsertionCalculator(fleetManager,calc);
|
||||||
InsertionData iData = insertion.calculate(vehicleRoute, service, null, 0.0, null, Double.MAX_VALUE);
|
InsertionData iData = insertion.getInsertionData(vehicleRoute, service, null, 0.0, null, Double.MAX_VALUE);
|
||||||
assertThat(iData.getSelectedVehicle(), is(veh2));
|
assertThat(iData.getSelectedVehicle(), is(veh2));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,10 +37,12 @@ import basics.costs.VehicleRoutingActivityCosts;
|
||||||
import basics.costs.VehicleRoutingTransportCosts;
|
import basics.costs.VehicleRoutingTransportCosts;
|
||||||
import basics.route.Driver;
|
import basics.route.Driver;
|
||||||
import basics.route.DriverImpl;
|
import basics.route.DriverImpl;
|
||||||
|
import basics.route.FiniteFleetManagerFactory;
|
||||||
import basics.route.ServiceActivity;
|
import basics.route.ServiceActivity;
|
||||||
import basics.route.TimeWindow;
|
import basics.route.TimeWindow;
|
||||||
import basics.route.TourActivities;
|
import basics.route.TourActivities;
|
||||||
import basics.route.Vehicle;
|
import basics.route.Vehicle;
|
||||||
|
import basics.route.VehicleFleetManager;
|
||||||
import basics.route.VehicleImpl;
|
import basics.route.VehicleImpl;
|
||||||
import basics.route.VehicleRoute;
|
import basics.route.VehicleRoute;
|
||||||
import basics.route.VehicleTypeImpl;
|
import basics.route.VehicleTypeImpl;
|
||||||
|
|
@ -71,9 +73,9 @@ public class GendreauPostOptTest {
|
||||||
|
|
||||||
private List<Vehicle> vehicles;
|
private List<Vehicle> vehicles;
|
||||||
|
|
||||||
private VehicleFleetManagerImpl fleetManager;
|
private VehicleFleetManager fleetManager;
|
||||||
|
|
||||||
private JobInsertionCalculator insertionCalc;
|
private JobInsertionCostsCalculator insertionCalc;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp(){
|
public void setUp(){
|
||||||
|
|
@ -142,7 +144,7 @@ public class GendreauPostOptTest {
|
||||||
vehicles = Arrays.asList(lightVehicle1,lightVehicle2, heavyVehicle);
|
vehicles = Arrays.asList(lightVehicle1,lightVehicle2, heavyVehicle);
|
||||||
|
|
||||||
// Collection<Vehicle> vehicles = Arrays.asList(lightVehicle1,lightVehicle2, heavyVehicle);
|
// Collection<Vehicle> vehicles = Arrays.asList(lightVehicle1,lightVehicle2, heavyVehicle);
|
||||||
fleetManager = new VehicleFleetManagerImpl(vehicles);
|
fleetManager = new FiniteFleetManagerFactory(vehicles).createFleetManager();
|
||||||
states = new StateManager();
|
states = new StateManager();
|
||||||
|
|
||||||
activityCosts = new ExampleActivityCostFunction();
|
activityCosts = new ExampleActivityCostFunction();
|
||||||
|
|
|
||||||
|
|
@ -186,8 +186,8 @@ public class RefuseCollectionTest {
|
||||||
vra.setPrematureBreak(100);
|
vra.setPrematureBreak(100);
|
||||||
Collection<VehicleRoutingProblemSolution> solutions = vra.searchSolutions();
|
Collection<VehicleRoutingProblemSolution> solutions = vra.searchSolutions();
|
||||||
|
|
||||||
assertEquals(397.0,Solutions.getBest(solutions).getCost(),0.01);
|
assertEquals(397.0,Solutions.bestOf(solutions).getCost(),0.01);
|
||||||
assertEquals(2,Solutions.getBest(solutions).getRoutes().size());
|
assertEquals(2,Solutions.bestOf(solutions).getRoutes().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,8 @@ import basics.algo.InsertionStartsListener;
|
||||||
import basics.algo.JobInsertedListener;
|
import basics.algo.JobInsertedListener;
|
||||||
import basics.costs.VehicleRoutingActivityCosts;
|
import basics.costs.VehicleRoutingActivityCosts;
|
||||||
import basics.costs.VehicleRoutingTransportCosts;
|
import basics.costs.VehicleRoutingTransportCosts;
|
||||||
|
import basics.route.ReverseRouteActivityVisitor;
|
||||||
|
import basics.route.RouteActivityVisitor;
|
||||||
import basics.route.VehicleRoute;
|
import basics.route.VehicleRoute;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -171,7 +171,7 @@ public class TestCalculatesServiceInsertion {
|
||||||
VehicleRoute route = VehicleRoute.newInstance(tour,driver,vehicle);
|
VehicleRoute route = VehicleRoute.newInstance(tour,driver,vehicle);
|
||||||
stateUpdater.update(route);
|
stateUpdater.update(route);
|
||||||
|
|
||||||
InsertionData iData = serviceInsertion.calculate(route, first, vehicle, vehicle.getEarliestDeparture(), null, Double.MAX_VALUE);
|
InsertionData iData = serviceInsertion.getInsertionData(route, first, vehicle, vehicle.getEarliestDeparture(), null, Double.MAX_VALUE);
|
||||||
assertEquals(20.0, iData.getInsertionCost(), 0.2);
|
assertEquals(20.0, iData.getInsertionCost(), 0.2);
|
||||||
assertEquals(0, iData.getDeliveryInsertionIndex());
|
assertEquals(0, iData.getDeliveryInsertionIndex());
|
||||||
}
|
}
|
||||||
|
|
@ -184,7 +184,7 @@ public class TestCalculatesServiceInsertion {
|
||||||
VehicleRoute route = VehicleRoute.newInstance(tour,driver,vehicle);
|
VehicleRoute route = VehicleRoute.newInstance(tour,driver,vehicle);
|
||||||
stateUpdater.update(route);
|
stateUpdater.update(route);
|
||||||
|
|
||||||
InsertionData iData = serviceInsertion.calculate(route, second, vehicle, vehicle.getEarliestDeparture(), null, Double.MAX_VALUE);
|
InsertionData iData = serviceInsertion.getInsertionData(route, second, vehicle, vehicle.getEarliestDeparture(), null, Double.MAX_VALUE);
|
||||||
assertEquals(20.0, iData.getInsertionCost(), 0.2);
|
assertEquals(20.0, iData.getInsertionCost(), 0.2);
|
||||||
assertEquals(0, iData.getDeliveryInsertionIndex());
|
assertEquals(0, iData.getDeliveryInsertionIndex());
|
||||||
}
|
}
|
||||||
|
|
@ -199,7 +199,7 @@ public class TestCalculatesServiceInsertion {
|
||||||
|
|
||||||
stateUpdater.update(route);
|
stateUpdater.update(route);
|
||||||
|
|
||||||
InsertionData iData = serviceInsertion.calculate(route, third, vehicle, vehicle.getEarliestDeparture(), null, Double.MAX_VALUE);
|
InsertionData iData = serviceInsertion.getInsertionData(route, third, vehicle, vehicle.getEarliestDeparture(), null, Double.MAX_VALUE);
|
||||||
assertEquals(0.0, iData.getInsertionCost(), 0.2);
|
assertEquals(0.0, iData.getInsertionCost(), 0.2);
|
||||||
assertEquals(1, iData.getDeliveryInsertionIndex());
|
assertEquals(1, iData.getDeliveryInsertionIndex());
|
||||||
}
|
}
|
||||||
|
|
@ -214,7 +214,7 @@ public class TestCalculatesServiceInsertion {
|
||||||
|
|
||||||
stateUpdater.update(route);
|
stateUpdater.update(route);
|
||||||
|
|
||||||
InsertionData iData = serviceInsertion.calculate(route, third, newVehicle, newVehicle.getEarliestDeparture(), null, Double.MAX_VALUE);
|
InsertionData iData = serviceInsertion.getInsertionData(route, third, newVehicle, newVehicle.getEarliestDeparture(), null, Double.MAX_VALUE);
|
||||||
assertEquals(20.0, iData.getInsertionCost(), 0.2);
|
assertEquals(20.0, iData.getInsertionCost(), 0.2);
|
||||||
assertEquals(1, iData.getDeliveryInsertionIndex());
|
assertEquals(1, iData.getDeliveryInsertionIndex());
|
||||||
}
|
}
|
||||||
|
|
@ -228,7 +228,7 @@ public class TestCalculatesServiceInsertion {
|
||||||
VehicleRoute route = VehicleRoute.newInstance(tour,driver,vehicle);
|
VehicleRoute route = VehicleRoute.newInstance(tour,driver,vehicle);
|
||||||
stateUpdater.update(route);
|
stateUpdater.update(route);
|
||||||
|
|
||||||
InsertionData iData = serviceInsertion.calculate(route, second, vehicle, vehicle.getEarliestDeparture(), null, Double.MAX_VALUE);
|
InsertionData iData = serviceInsertion.getInsertionData(route, second, vehicle, vehicle.getEarliestDeparture(), null, Double.MAX_VALUE);
|
||||||
assertEquals(0.0, iData.getInsertionCost(), 0.2);
|
assertEquals(0.0, iData.getInsertionCost(), 0.2);
|
||||||
assertEquals(2, iData.getDeliveryInsertionIndex());
|
assertEquals(2, iData.getDeliveryInsertionIndex());
|
||||||
}
|
}
|
||||||
|
|
@ -244,7 +244,7 @@ public class TestCalculatesServiceInsertion {
|
||||||
// route.addActivity(states.getActivity(third,true));
|
// route.addActivity(states.getActivity(third,true));
|
||||||
stateUpdater.update(route);
|
stateUpdater.update(route);
|
||||||
|
|
||||||
InsertionData iData = serviceInsertion.calculate(route, second, newVehicle, newVehicle.getEarliestDeparture(), null, Double.MAX_VALUE);
|
InsertionData iData = serviceInsertion.getInsertionData(route, second, newVehicle, newVehicle.getEarliestDeparture(), null, Double.MAX_VALUE);
|
||||||
assertEquals(20.0, iData.getInsertionCost(), 0.2);
|
assertEquals(20.0, iData.getInsertionCost(), 0.2);
|
||||||
assertEquals(2, iData.getDeliveryInsertionIndex());
|
assertEquals(2, iData.getDeliveryInsertionIndex());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -164,7 +164,7 @@ public class TestCalculatesServiceInsertionOnRouteLevel {
|
||||||
VehicleRoute route = VehicleRoute.newInstance(tour,driver,vehicle);
|
VehicleRoute route = VehicleRoute.newInstance(tour,driver,vehicle);
|
||||||
updateStates.update(route);
|
updateStates.update(route);
|
||||||
|
|
||||||
InsertionData iData = serviceInsertion.calculate(route, first, vehicle, vehicle.getEarliestDeparture(), null, Double.MAX_VALUE);
|
InsertionData iData = serviceInsertion.getInsertionData(route, first, vehicle, vehicle.getEarliestDeparture(), null, Double.MAX_VALUE);
|
||||||
assertEquals(20.0, iData.getInsertionCost(), 0.2);
|
assertEquals(20.0, iData.getInsertionCost(), 0.2);
|
||||||
assertEquals(0, iData.getDeliveryInsertionIndex());
|
assertEquals(0, iData.getDeliveryInsertionIndex());
|
||||||
}
|
}
|
||||||
|
|
@ -178,7 +178,7 @@ public class TestCalculatesServiceInsertionOnRouteLevel {
|
||||||
VehicleRoute route = VehicleRoute.newInstance(tour,driver,vehicle);
|
VehicleRoute route = VehicleRoute.newInstance(tour,driver,vehicle);
|
||||||
updateStates.update(route);
|
updateStates.update(route);
|
||||||
|
|
||||||
InsertionData iData = serviceInsertion.calculate(route, third, vehicle, vehicle.getEarliestDeparture(), null, Double.MAX_VALUE);
|
InsertionData iData = serviceInsertion.getInsertionData(route, third, vehicle, vehicle.getEarliestDeparture(), null, Double.MAX_VALUE);
|
||||||
assertEquals(0.0, iData.getInsertionCost(), 0.2);
|
assertEquals(0.0, iData.getInsertionCost(), 0.2);
|
||||||
assertEquals(1, iData.getDeliveryInsertionIndex());
|
assertEquals(1, iData.getDeliveryInsertionIndex());
|
||||||
}
|
}
|
||||||
|
|
@ -192,7 +192,7 @@ public class TestCalculatesServiceInsertionOnRouteLevel {
|
||||||
VehicleRoute route = VehicleRoute.newInstance(tour,driver,vehicle);
|
VehicleRoute route = VehicleRoute.newInstance(tour,driver,vehicle);
|
||||||
updateStates.update(route);
|
updateStates.update(route);
|
||||||
|
|
||||||
InsertionData iData = serviceInsertion.calculate(route, third, newVehicle, vehicle.getEarliestDeparture(), null, Double.MAX_VALUE);
|
InsertionData iData = serviceInsertion.getInsertionData(route, third, newVehicle, vehicle.getEarliestDeparture(), null, Double.MAX_VALUE);
|
||||||
assertEquals(40.0, iData.getInsertionCost(), 0.2);
|
assertEquals(40.0, iData.getInsertionCost(), 0.2);
|
||||||
assertEquals(1, iData.getDeliveryInsertionIndex());
|
assertEquals(1, iData.getDeliveryInsertionIndex());
|
||||||
}
|
}
|
||||||
|
|
@ -206,7 +206,7 @@ public class TestCalculatesServiceInsertionOnRouteLevel {
|
||||||
VehicleRoute route = VehicleRoute.newInstance(tour,driver,vehicle);
|
VehicleRoute route = VehicleRoute.newInstance(tour,driver,vehicle);
|
||||||
updateStates.update(route);
|
updateStates.update(route);
|
||||||
|
|
||||||
InsertionData iData = serviceInsertion.calculate(route, second, vehicle, vehicle.getEarliestDeparture(), null, Double.MAX_VALUE);
|
InsertionData iData = serviceInsertion.getInsertionData(route, second, vehicle, vehicle.getEarliestDeparture(), null, Double.MAX_VALUE);
|
||||||
assertEquals(0.0, iData.getInsertionCost(), 0.2);
|
assertEquals(0.0, iData.getInsertionCost(), 0.2);
|
||||||
assertEquals(2, iData.getDeliveryInsertionIndex());
|
assertEquals(2, iData.getDeliveryInsertionIndex());
|
||||||
}
|
}
|
||||||
|
|
@ -220,7 +220,7 @@ public class TestCalculatesServiceInsertionOnRouteLevel {
|
||||||
VehicleRoute route = VehicleRoute.newInstance(tour,driver,vehicle);
|
VehicleRoute route = VehicleRoute.newInstance(tour,driver,vehicle);
|
||||||
updateStates.update(route);
|
updateStates.update(route);
|
||||||
|
|
||||||
InsertionData iData = serviceInsertion.calculate(route, second, newVehicle, vehicle.getEarliestDeparture(), null, Double.MAX_VALUE);
|
InsertionData iData = serviceInsertion.getInsertionData(route, second, newVehicle, vehicle.getEarliestDeparture(), null, Double.MAX_VALUE);
|
||||||
assertEquals(40.0, iData.getInsertionCost(), 0.2);
|
assertEquals(40.0, iData.getInsertionCost(), 0.2);
|
||||||
assertEquals(2, iData.getDeliveryInsertionIndex());
|
assertEquals(2, iData.getDeliveryInsertionIndex());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,210 +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 static org.junit.Assert.assertEquals;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import util.Coordinate;
|
|
||||||
import util.ManhattanDistanceCalculator;
|
|
||||||
import basics.Job;
|
|
||||||
import basics.Service;
|
|
||||||
import basics.costs.DefaultVehicleRoutingActivityCosts;
|
|
||||||
import basics.costs.VehicleRoutingTransportCosts;
|
|
||||||
import basics.route.Driver;
|
|
||||||
import basics.route.DriverImpl;
|
|
||||||
import basics.route.ServiceActivity;
|
|
||||||
import basics.route.TimeWindow;
|
|
||||||
import basics.route.TourActivities;
|
|
||||||
import basics.route.Vehicle;
|
|
||||||
import basics.route.VehicleImpl;
|
|
||||||
import basics.route.VehicleRoute;
|
|
||||||
import basics.route.VehicleTypeImpl;
|
|
||||||
|
|
||||||
public class TestIterateRouteForwardInTime {
|
|
||||||
|
|
||||||
TourActivities tour;
|
|
||||||
|
|
||||||
Driver driver;
|
|
||||||
|
|
||||||
Vehicle vehicle;
|
|
||||||
|
|
||||||
TourActivities anotherTour;
|
|
||||||
|
|
||||||
private VehicleRoute vehicleRoute;
|
|
||||||
|
|
||||||
private VehicleRoutingTransportCosts cost;
|
|
||||||
|
|
||||||
ServiceActivity firstAct;
|
|
||||||
|
|
||||||
ServiceActivity secondAct;
|
|
||||||
|
|
||||||
StateManager stateManager;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setUp(){
|
|
||||||
cost = new VehicleRoutingTransportCosts() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public double getBackwardTransportTime(String fromId, String toId,
|
|
||||||
double arrivalTime, Driver driver, Vehicle vehicle) {
|
|
||||||
return getTransportCost(fromId, toId, arrivalTime, driver, vehicle);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public double getBackwardTransportCost(String fromId, String toId,
|
|
||||||
double arrivalTime, Driver driver, Vehicle vehicle) {
|
|
||||||
return getTransportCost(fromId, toId, arrivalTime, driver, vehicle);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public double getTransportCost(String fromId, String toId, double departureTime, Driver driver, Vehicle vehicle) {
|
|
||||||
String[] fromTokens = fromId.split(",");
|
|
||||||
String[] toTokens = toId.split(",");
|
|
||||||
double fromX = Double.parseDouble(fromTokens[0]);
|
|
||||||
double fromY = Double.parseDouble(fromTokens[1]);
|
|
||||||
|
|
||||||
double toX = Double.parseDouble(toTokens[0]);
|
|
||||||
double toY = Double.parseDouble(toTokens[1]);
|
|
||||||
|
|
||||||
return ManhattanDistanceCalculator.calculateDistance(new Coordinate(fromX, fromY), new Coordinate(toX, toY));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public double getTransportTime(String fromId, String toId, double departureTime, Driver driver, Vehicle vehicle) {
|
|
||||||
return getTransportCost(fromId, toId, departureTime, driver, vehicle);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Service firstService = Service.Builder.newInstance("1", 5).setLocationId("10,0").setTimeWindow(TimeWindow.newInstance(0, 20)).build();
|
|
||||||
Service secondService = Service.Builder.newInstance("2", 5).setLocationId("0,10").setTimeWindow(TimeWindow.newInstance(0, 50)).build();
|
|
||||||
|
|
||||||
Collection<Job> services = new ArrayList<Job>();
|
|
||||||
services.add(firstService);
|
|
||||||
services.add(secondService);
|
|
||||||
|
|
||||||
VehicleTypeImpl type = VehicleTypeImpl.Builder.newInstance("test", 0).build();
|
|
||||||
vehicle = VehicleImpl.Builder.newInstance("testvehicle").setType(type).setLocationId("0,0")
|
|
||||||
.setEarliestStart(0.0).setLatestArrival(50.0).build();
|
|
||||||
|
|
||||||
tour = new TourActivities();
|
|
||||||
firstAct = ServiceActivity.newInstance(firstService);
|
|
||||||
tour.addActivity(firstAct);
|
|
||||||
secondAct = ServiceActivity.newInstance(secondService);
|
|
||||||
tour.addActivity(secondAct);
|
|
||||||
|
|
||||||
vehicleRoute = VehicleRoute.newInstance(tour,DriverImpl.noDriver(),vehicle);
|
|
||||||
|
|
||||||
stateManager = new StateManager();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void whenIteratingWithoutUpdate_itShouldUpdateNothing() {
|
|
||||||
IterateRouteForwardInTime forwardInTime = new IterateRouteForwardInTime(cost);
|
|
||||||
forwardInTime.iterate(vehicleRoute);
|
|
||||||
|
|
||||||
assertEquals(0.0,firstAct.getArrTime(),0.1);
|
|
||||||
assertEquals(0.0,firstAct.getEndTime(),0.1);
|
|
||||||
|
|
||||||
assertEquals(0.0,secondAct.getArrTime(),0.1);
|
|
||||||
assertEquals(0.0,secondAct.getEndTime(),0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void whenIteratingWithActivityTimeUpdater_itShouldUpdateActivityTimes() {
|
|
||||||
RouteActivityVisitor forwardInTime = new RouteActivityVisitor();
|
|
||||||
forwardInTime.addActivityVisitor(new UpdateActivityTimes(cost));
|
|
||||||
forwardInTime.visit(vehicleRoute);
|
|
||||||
|
|
||||||
assertEquals(10.0,firstAct.getArrTime(),0.1);
|
|
||||||
assertEquals(10.0,firstAct.getEndTime(),0.1);
|
|
||||||
|
|
||||||
assertEquals(30.0,secondAct.getArrTime(),0.1);
|
|
||||||
assertEquals(30.0,secondAct.getEndTime(),0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void whenIteratingWithLoadUpdateAtActLocations_itShouldUpdateLoad() {
|
|
||||||
RouteActivityVisitor forwardInTime = new RouteActivityVisitor();
|
|
||||||
forwardInTime.addActivityVisitor(new UpdateLoadAtAllLevels(stateManager));
|
|
||||||
forwardInTime.visit(vehicleRoute);
|
|
||||||
|
|
||||||
assertEquals(5.0, stateManager.getActivityState(firstAct,StateFactory.LOAD).toDouble(), 0.01);
|
|
||||||
assertEquals(10.0, stateManager.getActivityState(secondAct,StateFactory.LOAD).toDouble(), 0.01);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testStatesOfAct0(){
|
|
||||||
RouteActivityVisitor forwardInTime = new RouteActivityVisitor();
|
|
||||||
forwardInTime.visit(vehicleRoute);
|
|
||||||
|
|
||||||
assertEquals(0.0, vehicleRoute.getStart().getEndTime(),0.05);
|
|
||||||
assertEquals(vehicleRoute.getVehicle().getLocationId(), vehicleRoute.getStart().getLocationId());
|
|
||||||
assertEquals(vehicleRoute.getVehicle().getEarliestDeparture(), vehicleRoute.getStart().getTheoreticalEarliestOperationStartTime(),0.05);
|
|
||||||
assertEquals(vehicleRoute.getVehicle().getLatestArrival(), vehicleRoute.getStart().getTheoreticalLatestOperationStartTime(),0.05);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testStatesOfAct1(){
|
|
||||||
RouteActivityVisitor forwardInTime = new RouteActivityVisitor();
|
|
||||||
forwardInTime.addActivityVisitor(new UpdateLoadAtAllLevels(stateManager));
|
|
||||||
forwardInTime.addActivityVisitor(new UpdateEarliestStartTimeWindowAtActLocations(stateManager, cost));
|
|
||||||
forwardInTime.addActivityVisitor(new UpdateCostsAtAllLevels(new DefaultVehicleRoutingActivityCosts(), cost, stateManager));
|
|
||||||
forwardInTime.visit(vehicleRoute);
|
|
||||||
|
|
||||||
assertEquals(10.0, stateManager.getActivityState(firstAct, StateFactory.COSTS).toDouble(),0.05);
|
|
||||||
assertEquals(5.0, stateManager.getActivityState(firstAct, StateFactory.LOAD).toDouble(),0.05);
|
|
||||||
assertEquals(10.0, stateManager.getActivityState(firstAct, StateFactory.EARLIEST_OPERATION_START_TIME).toDouble(),0.05);
|
|
||||||
// assertEquals(20.0, states.getState(tour.getActivities().get(0)).getLatestOperationStart(),0.05);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testStatesOfAct2(){
|
|
||||||
RouteActivityVisitor forwardInTime = new RouteActivityVisitor();
|
|
||||||
|
|
||||||
forwardInTime.addActivityVisitor(new UpdateLoadAtAllLevels(stateManager));
|
|
||||||
forwardInTime.addActivityVisitor(new UpdateEarliestStartTimeWindowAtActLocations(stateManager, cost));
|
|
||||||
forwardInTime.addActivityVisitor(new UpdateCostsAtAllLevels(new DefaultVehicleRoutingActivityCosts(), cost, stateManager));
|
|
||||||
forwardInTime.visit(vehicleRoute);
|
|
||||||
|
|
||||||
assertEquals(30.0, stateManager.getActivityState(secondAct, StateFactory.COSTS).toDouble(),0.05);
|
|
||||||
assertEquals(10.0, stateManager.getActivityState(secondAct, StateFactory.LOAD).toDouble(),0.05);
|
|
||||||
assertEquals(30.0, stateManager.getActivityState(secondAct, StateFactory.EARLIEST_OPERATION_START_TIME).toDouble(),0.05);
|
|
||||||
// assertEquals(40.0, states.getState(tour.getActivities().get(1)).getLatestOperationStart(),0.05);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testStatesOfAct3(){
|
|
||||||
RouteActivityVisitor forwardInTime = new RouteActivityVisitor();
|
|
||||||
|
|
||||||
forwardInTime.addActivityVisitor(new UpdateActivityTimes(cost));
|
|
||||||
forwardInTime.addActivityVisitor(new UpdateCostsAtAllLevels(new DefaultVehicleRoutingActivityCosts(), cost, stateManager));
|
|
||||||
forwardInTime.visit(vehicleRoute);
|
|
||||||
|
|
||||||
assertEquals(40.0, stateManager.getRouteState(vehicleRoute,StateFactory.COSTS).toDouble(), 0.05);
|
|
||||||
assertEquals(40.0, vehicleRoute.getEnd().getArrTime(),0.05);
|
|
||||||
assertEquals(50.0, vehicleRoute.getEnd().getTheoreticalLatestOperationStartTime(),0.05);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -21,8 +21,10 @@ import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
import basics.route.FiniteFleetManagerFactory;
|
||||||
import basics.route.PenaltyVehicleType;
|
import basics.route.PenaltyVehicleType;
|
||||||
import basics.route.Vehicle;
|
import basics.route.Vehicle;
|
||||||
|
import basics.route.VehicleFleetManager;
|
||||||
import basics.route.VehicleImpl;
|
import basics.route.VehicleImpl;
|
||||||
import basics.route.VehicleTypeImpl;
|
import basics.route.VehicleTypeImpl;
|
||||||
|
|
||||||
|
|
@ -42,7 +44,7 @@ public class TestVehicleFleetManager extends TestCase{
|
||||||
|
|
||||||
vehicles.add(v1);
|
vehicles.add(v1);
|
||||||
vehicles.add(v2);
|
vehicles.add(v2);
|
||||||
fleetManager = new VehicleFleetManagerImpl(vehicles);
|
fleetManager = new FiniteFleetManagerFactory(vehicles).createFleetManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testGetVehicles(){
|
public void testGetVehicles(){
|
||||||
|
|
@ -94,7 +96,7 @@ public class TestVehicleFleetManager extends TestCase{
|
||||||
vehicles.add(v1);
|
vehicles.add(v1);
|
||||||
vehicles.add(v2);
|
vehicles.add(v2);
|
||||||
vehicles.add(penalty4standard);
|
vehicles.add(penalty4standard);
|
||||||
VehicleFleetManager fleetManager = new VehicleFleetManagerImpl(vehicles);
|
VehicleFleetManager fleetManager = new FiniteFleetManagerFactory(vehicles).createFleetManager();
|
||||||
|
|
||||||
Collection<Vehicle> availableVehicles = fleetManager.getAvailableVehicles();
|
Collection<Vehicle> availableVehicles = fleetManager.getAvailableVehicles();
|
||||||
assertEquals(2, availableVehicles.size());
|
assertEquals(2, availableVehicles.size());
|
||||||
|
|
@ -115,7 +117,7 @@ public class TestVehicleFleetManager extends TestCase{
|
||||||
vehicles.add(v2);
|
vehicles.add(v2);
|
||||||
vehicles.add(penalty4standard);
|
vehicles.add(penalty4standard);
|
||||||
vehicles.add(v3);
|
vehicles.add(v3);
|
||||||
VehicleFleetManager fleetManager = new VehicleFleetManagerImpl(vehicles);
|
VehicleFleetManager fleetManager = new FiniteFleetManagerFactory(vehicles).createFleetManager();
|
||||||
fleetManager.lock(v1);
|
fleetManager.lock(v1);
|
||||||
fleetManager.lock(v2);
|
fleetManager.lock(v2);
|
||||||
Collection<Vehicle> availableVehicles = fleetManager.getAvailableVehicles();
|
Collection<Vehicle> availableVehicles = fleetManager.getAvailableVehicles();
|
||||||
|
|
@ -133,7 +135,7 @@ public class TestVehicleFleetManager extends TestCase{
|
||||||
vehicles.add(v1);
|
vehicles.add(v1);
|
||||||
vehicles.add(v2);
|
vehicles.add(v2);
|
||||||
vehicles.add(penalty4standard);
|
vehicles.add(penalty4standard);
|
||||||
VehicleFleetManager fleetManager = new VehicleFleetManagerImpl(vehicles);
|
VehicleFleetManager fleetManager = new FiniteFleetManagerFactory(vehicles).createFleetManager();
|
||||||
fleetManager.lock(v1);
|
fleetManager.lock(v1);
|
||||||
fleetManager.lock(v2);
|
fleetManager.lock(v2);
|
||||||
Collection<Vehicle> availableVehicles = fleetManager.getAvailableVehicles();
|
Collection<Vehicle> availableVehicles = fleetManager.getAvailableVehicles();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue