diff --git a/Changelog.md b/Changelog.md
deleted file mode 100644
index 1a8c1bc5..00000000
--- a/Changelog.md
+++ /dev/null
@@ -1,21 +0,0 @@
-Change-log
-==========
-**v0.0.4** @ 2013-10-17
-
-- A number of internal improvements
-- License change from GPLv2 to LGPLv3
-- Add premature algorithm termination: PrematureAlgorithmBreaker.java and its implementations
-- SearchStrategy.java: public SearchStrategy(SolutionSelector,SolutionAcceptor) --> public SearchStratgy(SolutionSelector,SolutionAcceptor,SolutionCostCalculator)
-- SearchStrategy.java: public boolean run(...) --> public DiscoveredSolution run(...)
-- VehicleImpl.VehicleType.Builder --> VehicleTypeImpl.Builder
-- VehicleImpl.VehicleBuilder --> VehicleImpl.Builder
-
-**v0.0.3** @ 2013-06-04
-
-- Bug fix - access resources in jar
-
-**v0.0.2** @ 2013-06-03
-
-- Bug fix - access resources in jar
-
-**v0.0.1** @ 2013-06-02
diff --git a/jsprit-analysis/src/main/java/analysis/AlgorithmSearchProgressChartListener.java b/jsprit-analysis/src/main/java/analysis/AlgorithmSearchProgressChartListener.java
index c31b6e51..af7962d2 100644
--- a/jsprit-analysis/src/main/java/analysis/AlgorithmSearchProgressChartListener.java
+++ b/jsprit-analysis/src/main/java/analysis/AlgorithmSearchProgressChartListener.java
@@ -118,8 +118,10 @@ public class AlgorithmSearchProgressChartListener implements IterationEndsListen
XYPlot plot = chart.getXYPlot();
NumberAxis yAxis = (NumberAxis) plot.getRangeAxis();
- Range rangeY = new Range(minValue-0.05*minValue,maxValue + 0.05*maxValue);
- yAxis.setRange(rangeY);
+ Range rangeBounds = coll.getRangeBounds(true);
+ double upper = Math.min(rangeBounds.getUpperBound(), rangeBounds.getLowerBound()*5);
+ if(upper == 0.0){ upper = 10000; }
+ yAxis.setRangeWithMargins(rangeBounds.getLowerBound(),upper);
try {
ChartUtilities.saveChartAsJPEG(new File(filename), chart, 1000, 600);
@@ -143,9 +145,9 @@ public class AlgorithmSearchProgressChartListener implements IterationEndsListen
double best = Double.MAX_VALUE;
double sum = 0.0;
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();
- sum += sol.getCost();
+ sum += Math.min(sol.getCost(),Double.MAX_VALUE);
}
bestResultList.add(best);
worstResultList.add(worst);
diff --git a/jsprit-core/src/main/java/algorithms/ActivityInsertionCostsCalculator.java b/jsprit-core/src/main/java/algorithms/ActivityInsertionCostsCalculator.java
index 4a72322b..bed0a9c5 100644
--- a/jsprit-core/src/main/java/algorithms/ActivityInsertionCostsCalculator.java
+++ b/jsprit-core/src/main/java/algorithms/ActivityInsertionCostsCalculator.java
@@ -22,9 +22,9 @@ package algorithms;
import basics.route.TourActivity;
-interface ActivityInsertionCostsCalculator {
+public interface ActivityInsertionCostsCalculator {
- class ActivityInsertionCosts {
+ public class ActivityInsertionCosts {
private double additionalCosts;
private double additionalTime;
@@ -50,6 +50,6 @@ interface ActivityInsertionCostsCalculator {
}
- 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);
}
diff --git a/jsprit-core/src/main/java/algorithms/AvgJobDistance.java b/jsprit-core/src/main/java/algorithms/AvgJobDistance.java
index 0425aeca..eaa9c6a8 100644
--- a/jsprit-core/src/main/java/algorithms/AvgJobDistance.java
+++ b/jsprit-core/src/main/java/algorithms/AvgJobDistance.java
@@ -52,7 +52,7 @@ class AvgJobDistance implements JobDistance {
*
If the distance between two jobs cannot be calculated with input-transport costs, it tries the euclidean distance between these jobs.
*/
@Override
- public double calculateDistance(Job i, Job j) {
+ public double getDistance(Job i, Job j) {
if (i.equals(j)) return 0.0;
if (i instanceof Service && j instanceof Service) {
diff --git a/jsprit-core/src/main/java/algorithms/BestInsertion.java b/jsprit-core/src/main/java/algorithms/BestInsertion.java
index ca3f8241..d86173ba 100644
--- a/jsprit-core/src/main/java/algorithms/BestInsertion.java
+++ b/jsprit-core/src/main/java/algorithms/BestInsertion.java
@@ -42,6 +42,28 @@ import basics.route.VehicleRoute;
final class BestInsertion implements InsertionStrategy{
+ class Insertion {
+
+ private final VehicleRoute route;
+
+ private final InsertionData insertionData;
+
+ public Insertion(VehicleRoute vehicleRoute, InsertionData insertionData) {
+ super();
+ this.route = vehicleRoute;
+ this.insertionData = insertionData;
+ }
+
+ public VehicleRoute getRoute() {
+ return route;
+ }
+
+ public InsertionData getInsertionData() {
+ return insertionData;
+ }
+
+ }
+
private static Logger logger = Logger.getLogger(BestInsertion.class);
private Random random = RandomNumberGeneration.getRandom();
@@ -56,7 +78,7 @@ final class BestInsertion implements InsertionStrategy{
private Inserter inserter;
- private JobInsertionCalculator bestInsertionCostCalculator;
+ private JobInsertionCostsCalculator bestInsertionCostCalculator;
private boolean minVehiclesFirst = false;
@@ -64,7 +86,7 @@ final class BestInsertion implements InsertionStrategy{
this.random = random;
}
- public BestInsertion(JobInsertionCalculator jobInsertionCalculator) {
+ public BestInsertion(JobInsertionCostsCalculator jobInsertionCalculator) {
super();
this.insertionsListeners = new InsertionListeners();
inserter = new Inserter(insertionsListeners);
@@ -86,7 +108,7 @@ final class BestInsertion implements InsertionStrategy{
Insertion bestInsertion = null;
double bestInsertionCost = Double.MAX_VALUE;
for(VehicleRoute vehicleRoute : vehicleRoutes){
- InsertionData iData = bestInsertionCostCalculator.calculate(vehicleRoute, unassignedJob, NO_NEW_VEHICLE_YET, NO_NEW_DEPARTURE_TIME_YET, NO_NEW_DRIVER_YET, bestInsertionCost);
+ InsertionData iData = bestInsertionCostCalculator.getInsertionData(vehicleRoute, unassignedJob, NO_NEW_VEHICLE_YET, NO_NEW_DEPARTURE_TIME_YET, NO_NEW_DRIVER_YET, bestInsertionCost);
if(iData instanceof NoInsertionFound) {
continue;
}
@@ -97,7 +119,7 @@ final class BestInsertion implements InsertionStrategy{
}
if(!minVehiclesFirst){
VehicleRoute newRoute = VehicleRoute.emptyRoute();
- InsertionData newIData = bestInsertionCostCalculator.calculate(newRoute, unassignedJob, NO_NEW_VEHICLE_YET, NO_NEW_DEPARTURE_TIME_YET, NO_NEW_DRIVER_YET, bestInsertionCost);
+ InsertionData newIData = bestInsertionCostCalculator.getInsertionData(newRoute, unassignedJob, NO_NEW_VEHICLE_YET, NO_NEW_DEPARTURE_TIME_YET, NO_NEW_DRIVER_YET, bestInsertionCost);
if(newIData.getInsertionCost() < bestInsertionCost){
bestInsertion = new Insertion(newRoute,newIData);
bestInsertionCost = newIData.getInsertionCost();
@@ -106,7 +128,7 @@ final class BestInsertion implements InsertionStrategy{
}
if(bestInsertion == null){
VehicleRoute newRoute = VehicleRoute.emptyRoute();
- InsertionData bestI = bestInsertionCostCalculator.calculate(newRoute, unassignedJob, NO_NEW_VEHICLE_YET, NO_NEW_DEPARTURE_TIME_YET, NO_NEW_DRIVER_YET, Double.MAX_VALUE);
+ InsertionData bestI = bestInsertionCostCalculator.getInsertionData(newRoute, unassignedJob, NO_NEW_VEHICLE_YET, NO_NEW_DEPARTURE_TIME_YET, NO_NEW_DRIVER_YET, Double.MAX_VALUE);
if(bestI instanceof InsertionData.NoInsertionFound){
throw new IllegalStateException(getErrorMsg(unassignedJob));
}
diff --git a/jsprit-core/src/main/java/algorithms/BestInsertionBuilder.java b/jsprit-core/src/main/java/algorithms/BestInsertionBuilder.java
new file mode 100644
index 00000000..b13773ff
--- /dev/null
+++ b/jsprit-core/src/main/java/algorithms/BestInsertionBuilder.java
@@ -0,0 +1,129 @@
+package algorithms;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import basics.VehicleRoutingProblem;
+import basics.VehicleRoutingProblem.Constraint;
+import basics.algo.InsertionListener;
+import basics.algo.VehicleRoutingAlgorithmListeners.PrioritizedVRAListener;
+import basics.route.VehicleFleetManager;
+
+public class BestInsertionBuilder implements InsertionStrategyBuilder{
+
+ private VehicleRoutingProblem vrp;
+
+ private StateManager stateManager;
+
+ private boolean local = true;
+
+ private ConstraintManager constraintManager;
+
+ private VehicleFleetManager fleetManager;
+
+ private double weightOfFixedCosts;
+
+ private boolean considerFixedCosts = false;
+
+ private ActivityInsertionCostsCalculator actInsertionCostsCalculator = null;
+
+ private int forwaredLooking;
+
+ private int memory;
+
+ public BestInsertionBuilder(VehicleRoutingProblem vrp, VehicleFleetManager vehicleFleetManager, StateManager stateManager) {
+ super();
+ this.vrp = vrp;
+ this.stateManager = stateManager;
+ this.constraintManager = new ConstraintManager();
+ this.fleetManager = vehicleFleetManager;
+ addCoreStateUpdaters();
+ }
+
+ private void addCoreStateUpdaters(){
+ stateManager.addListener(new UpdateLoadsAtStartAndEndOfRouteWhenInsertionStarts(stateManager));
+ stateManager.addListener(new UpdateLoadsAtStartAndEndOfRouteWhenJobHasBeenInserted(stateManager));
+
+ stateManager.addActivityVisitor(new UpdateMaxLoad(stateManager));
+ stateManager.addActivityVisitor(new UpdateActivityTimes(vrp.getTransportCosts()));
+ stateManager.addActivityVisitor(new UpdateCostsAtAllLevels(vrp.getActivityCosts(), vrp.getTransportCosts(), stateManager));
+ }
+
+ public BestInsertionBuilder addHardLoadConstraints(){
+ constraintManager.addConstraint(new HardPickupAndDeliveryLoadRouteLevelConstraint(stateManager));
+ if(vrp.getProblemConstraints().contains(Constraint.DELIVERIES_FIRST)){
+ constraintManager.addConstraint(new HardPickupAndDeliveryBackhaulActivityLevelConstraint(stateManager));
+ }
+ else{
+ constraintManager.addConstraint(new HardPickupAndDeliveryActivityLevelConstraint(stateManager));
+ }
+ stateManager.addActivityVisitor(new UpdateOccuredDeliveriesAtActivityLevel(stateManager));
+ stateManager.addActivityVisitor(new UpdateFuturePickupsAtActivityLevel(stateManager));
+ return this;
+ }
+
+ public BestInsertionBuilder addHardTimeWindowConstraint(){
+ constraintManager.addConstraint(new HardTimeWindowActivityLevelConstraint(stateManager, vrp.getTransportCosts()));
+// stateManager.addActivityVisitor(new UpdateEarliestStartTimeWindowAtActLocations(stateManager, vrp.getTransportCosts()));
+ stateManager.addActivityVisitor(new UpdateLatestOperationStartTimeAtActLocations(stateManager, vrp.getTransportCosts()));
+ return this;
+ }
+
+
+ public BestInsertionBuilder addConstraint(HardActivityLevelConstraint hardActvitiyLevelConstraint){
+ constraintManager.addConstraint(hardActvitiyLevelConstraint);
+ return this;
+ };
+
+ public BestInsertionBuilder addConstraint(HardRouteLevelConstraint hardRouteLevelConstraint){
+ constraintManager.addConstraint(hardRouteLevelConstraint);
+ return this;
+ };
+
+ public void setRouteLevel(int forwardLooking, int memory){
+ local = false;
+ this.forwaredLooking = forwardLooking;
+ this.memory = memory;
+ };
+
+ public BestInsertionBuilder setLocalLevel(){
+ local = true;
+ return this;
+ };
+
+ public BestInsertionBuilder considerFixedCosts(double weightOfFixedCosts){
+ this.weightOfFixedCosts = weightOfFixedCosts;
+ this.considerFixedCosts = true;
+ return this;
+ }
+
+ public void setActivityInsertionCostCalculator(ActivityInsertionCostsCalculator activityInsertionCostsCalculator){
+ this.actInsertionCostsCalculator = activityInsertionCostsCalculator;
+ };
+
+ @Override
+ public InsertionStrategy build() {
+ List iListeners = new ArrayList();
+ List algorithmListeners = new ArrayList();
+ CalculatorBuilder calcBuilder = new CalculatorBuilder(iListeners, algorithmListeners);
+ if(local){
+ calcBuilder.setLocalLevel();
+ }
+ else {
+ calcBuilder.setRouteLevel(forwaredLooking, memory);
+ }
+ calcBuilder.setConstraintManager(constraintManager);
+ calcBuilder.setStates(stateManager);
+ calcBuilder.setVehicleRoutingProblem(vrp);
+ calcBuilder.setVehicleFleetManager(fleetManager);
+ calcBuilder.setActivityInsertionCostsCalculator(actInsertionCostsCalculator);
+ if(considerFixedCosts) {
+ calcBuilder.considerFixedCosts(weightOfFixedCosts);
+ }
+ JobInsertionCostsCalculator jobInsertions = calcBuilder.build();
+ BestInsertion bestInsertion = new BestInsertion(jobInsertions);
+ for(InsertionListener l : iListeners) bestInsertion.addListener(l);
+ return bestInsertion;
+ }
+
+}
diff --git a/jsprit-core/src/main/java/algorithms/BestInsertionStrategyFactory.java b/jsprit-core/src/main/java/algorithms/BestInsertionStrategyFactory.java
new file mode 100644
index 00000000..beb92f46
--- /dev/null
+++ b/jsprit-core/src/main/java/algorithms/BestInsertionStrategyFactory.java
@@ -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);
+ }
+
+}
diff --git a/jsprit-core/src/main/java/algorithms/CalculatesServiceInsertionWithTimeScheduling.java b/jsprit-core/src/main/java/algorithms/CalculatesServiceInsertionWithTimeScheduling.java
index b96999ec..f8ef9064 100644
--- a/jsprit-core/src/main/java/algorithms/CalculatesServiceInsertionWithTimeScheduling.java
+++ b/jsprit-core/src/main/java/algorithms/CalculatesServiceInsertionWithTimeScheduling.java
@@ -27,11 +27,11 @@ import basics.route.Driver;
import basics.route.Vehicle;
import basics.route.VehicleRoute;
-class CalculatesServiceInsertionWithTimeScheduling implements JobInsertionCalculator{
+class CalculatesServiceInsertionWithTimeScheduling implements JobInsertionCostsCalculator{
private static Logger log = Logger.getLogger(CalculatesServiceInsertionWithTimeScheduling.class);
- private JobInsertionCalculator jic;
+ private JobInsertionCostsCalculator jic;
private Random random = new Random();
@@ -39,7 +39,7 @@ class CalculatesServiceInsertionWithTimeScheduling implements JobInsertionCalcul
private double timeSlice = 900.0;
- public CalculatesServiceInsertionWithTimeScheduling(JobInsertionCalculator jic, double timeSlice, int neighbors) {
+ public CalculatesServiceInsertionWithTimeScheduling(JobInsertionCostsCalculator jic, double timeSlice, int neighbors) {
super();
this.jic = jic;
this.timeSlice = timeSlice;
@@ -53,7 +53,7 @@ class CalculatesServiceInsertionWithTimeScheduling implements JobInsertionCalcul
}
@Override
- public InsertionData calculate(VehicleRoute currentRoute, Job jobToInsert, Vehicle newVehicle, double newVehicleDepartureTime, Driver newDriver, double bestKnownScore) {
+ public InsertionData getInsertionData(VehicleRoute currentRoute, Job jobToInsert, Vehicle newVehicle, double newVehicleDepartureTime, Driver newDriver, double bestKnownScore) {
List vehicleDepartureTimes = new ArrayList();
double currentStart;
if(currentRoute.getStart() == null){
@@ -74,7 +74,7 @@ class CalculatesServiceInsertionWithTimeScheduling implements JobInsertionCalcul
InsertionData bestIData = null;
for(Double departureTime : vehicleDepartureTimes){
- InsertionData iData = jic.calculate(currentRoute, jobToInsert, newVehicle, departureTime, newDriver, bestKnownScore);
+ InsertionData iData = jic.getInsertionData(currentRoute, jobToInsert, newVehicle, departureTime, newDriver, bestKnownScore);
if(bestIData == null) bestIData = iData;
else if(iData.getInsertionCost() < bestIData.getInsertionCost()){
iData.setVehicleDepartureTime(departureTime);
diff --git a/jsprit-core/src/main/java/algorithms/CalculationUtils.java b/jsprit-core/src/main/java/algorithms/CalculationUtils.java
new file mode 100644
index 00000000..d584578c
--- /dev/null
+++ b/jsprit-core/src/main/java/algorithms/CalculationUtils.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (C) 2013 Stefan Schroeder
+ *
+ * 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.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributors:
+ * Stefan Schroeder - initial API and implementation
+ ******************************************************************************/
+package algorithms;
+
+import basics.route.TourActivity;
+
+class CalculationUtils {
+
+
+ /**
+ * Calculates actEndTime assuming that activity can at earliest start at act.getTheoreticalEarliestOperationStartTime().
+ *
+ * @param actArrTime
+ * @param act
+ * @return
+ */
+ public static double getActivityEndTime(double actArrTime, TourActivity act){
+ return Math.max(actArrTime, act.getTheoreticalEarliestOperationStartTime()) + act.getOperationTime();
+ }
+}
diff --git a/jsprit-core/src/main/java/algorithms/CalculatorBuilder.java b/jsprit-core/src/main/java/algorithms/CalculatorBuilder.java
index 47be6346..612977cb 100644
--- a/jsprit-core/src/main/java/algorithms/CalculatorBuilder.java
+++ b/jsprit-core/src/main/java/algorithms/CalculatorBuilder.java
@@ -19,10 +19,10 @@ package algorithms;
import java.util.ArrayList;
import java.util.List;
-import algorithms.HardConstraints.ConstraintManager;
import basics.VehicleRoutingProblem;
import basics.algo.InsertionListener;
import basics.algo.VehicleRoutingAlgorithmListeners.PrioritizedVRAListener;
+import basics.route.VehicleFleetManager;
@@ -30,16 +30,16 @@ class CalculatorBuilder {
private static class CalculatorPlusListeners {
- private JobInsertionCalculator calculator;
+ private JobInsertionCostsCalculator calculator;
- public JobInsertionCalculator getCalculator() {
+ public JobInsertionCostsCalculator getCalculator() {
return calculator;
}
private List algorithmListener = new ArrayList();
private List insertionListener = new ArrayList();
- public CalculatorPlusListeners(JobInsertionCalculator calculator) {
+ public CalculatorPlusListeners(JobInsertionCostsCalculator calculator) {
super();
this.calculator = calculator;
}
@@ -59,7 +59,7 @@ class CalculatorBuilder {
private VehicleRoutingProblem vrp;
- private StateManager states;
+ private StateGetter states;
private boolean local = true;
@@ -80,6 +80,8 @@ class CalculatorBuilder {
private int neighbors;
private ConstraintManager constraintManager;
+
+ private ActivityInsertionCostsCalculator activityInsertionCostCalculator = null;
/**
* Constructs the builder.
@@ -102,7 +104,7 @@ class CalculatorBuilder {
*
* @return
*/
- public CalculatorBuilder setStates(StateManager states){
+ public CalculatorBuilder setStates(StateGetter states){
this.states = states;
return this;
}
@@ -137,6 +139,10 @@ class CalculatorBuilder {
public void setLocalLevel(){
local = true;
}
+
+ public void setActivityInsertionCostsCalculator(ActivityInsertionCostsCalculator activityInsertionCostsCalculator){
+ this.activityInsertionCostCalculator = activityInsertionCostsCalculator;
+ }
/**
* Sets a flag to build a calculator that evaluates job insertion on route-level.
@@ -173,11 +179,11 @@ class CalculatorBuilder {
* @return jobInsertionCalculator.
* @throws IllegalStateException if vrp == null or activityStates == null or fleetManager == null.
*/
- public JobInsertionCalculator build(){
+ public JobInsertionCostsCalculator build(){
if(vrp == null) throw new IllegalStateException("vehicle-routing-problem is null, but it must be set (this.setVehicleRoutingProblem(vrp))");
if(states == null) throw new IllegalStateException("states is null, but is must be set (this.setStates(states))");
if(fleetManager == null) throw new IllegalStateException("fleetManager is null, but it must be set (this.setVehicleFleetManager(fleetManager))");
- JobInsertionCalculator baseCalculator = null;
+ JobInsertionCostsCalculator baseCalculator = null;
CalculatorPlusListeners standardLocal = null;
if(local){
standardLocal = createStandardLocal(vrp, states);
@@ -212,40 +218,58 @@ class CalculatorBuilder {
}
}
- private CalculatorPlusListeners createStandardLocal(VehicleRoutingProblem vrp, StateManager statesManager){
+ private CalculatorPlusListeners createStandardLocal(VehicleRoutingProblem vrp, StateGetter statesManager){
if(constraintManager == null) throw new IllegalStateException("constraint-manager is null");
- ActivityInsertionCostsCalculator defaultCalc = new LocalActivityInsertionCostsCalculator(vrp.getTransportCosts(), vrp.getActivityCosts(), constraintManager);
- JobInsertionCalculator standardServiceInsertion = new ServiceInsertionCalculator(vrp.getTransportCosts(), defaultCalc, constraintManager);
-
+//<<<<<<< HEAD
+// ActivityInsertionCostsCalculator defaultCalc = new LocalActivityInsertionCostsCalculator(vrp.getTransportCosts(), vrp.getActivityCosts(), constraintManager);
+// JobInsertionCalculator standardServiceInsertion = new ServiceInsertionCalculator(vrp.getTransportCosts(), defaultCalc, constraintManager);
+//
+//=======
+ ActivityInsertionCostsCalculator actInsertionCalc;
+ if(activityInsertionCostCalculator == null){
+ actInsertionCalc = new LocalActivityInsertionCostsCalculator(vrp.getTransportCosts(), vrp.getActivityCosts());
+ }
+ else{
+ actInsertionCalc = activityInsertionCostCalculator;
+ }
+
+ JobInsertionCostsCalculator standardServiceInsertion = new ServiceInsertionCalculator(vrp.getTransportCosts(), actInsertionCalc, constraintManager, constraintManager);
+//>>>>>>> refs/remotes/choose_remote_name/relaxAPI
((ServiceInsertionCalculator) standardServiceInsertion).setNeighborhood(vrp.getNeighborhood());
CalculatorPlusListeners calcPlusListeners = new CalculatorPlusListeners(standardServiceInsertion);
return calcPlusListeners;
}
- private CalculatorPlusListeners createCalculatorConsideringFixedCosts(VehicleRoutingProblem vrp, JobInsertionCalculator baseCalculator, StateManager activityStates2, double weightOfFixedCosts){
- final CalculatesServiceInsertionConsideringFixCost withFixCost = new CalculatesServiceInsertionConsideringFixCost(baseCalculator, activityStates2);
+ private CalculatorPlusListeners createCalculatorConsideringFixedCosts(VehicleRoutingProblem vrp, JobInsertionCostsCalculator baseCalculator, StateGetter activityStates2, double weightOfFixedCosts){
+ final JobInsertionConsideringFixCostsCalculator withFixCost = new JobInsertionConsideringFixCostsCalculator(baseCalculator, activityStates2);
withFixCost.setWeightOfFixCost(weightOfFixedCosts);
CalculatorPlusListeners calcPlusListeners = new CalculatorPlusListeners(withFixCost);
calcPlusListeners.getInsertionListener().add(new ConfigureFixCostCalculator(vrp, withFixCost));
return calcPlusListeners;
}
- private CalculatorPlusListeners createStandardRoute(VehicleRoutingProblem vrp, StateManager activityStates2, int forwardLooking, int solutionMemory){
+ private CalculatorPlusListeners createStandardRoute(VehicleRoutingProblem vrp, StateGetter activityStates2, int forwardLooking, int solutionMemory){
int after = forwardLooking;
- ActivityInsertionCostsCalculator routeLevelCostEstimator = new RouteLevelActivityInsertionCostsEstimator(vrp.getTransportCosts(), vrp.getActivityCosts(), constraintManager, activityStates2);
- JobInsertionCalculator jobInsertionCalculator = new CalculatesServiceInsertionOnRouteLevel(vrp.getTransportCosts(), vrp.getActivityCosts(), constraintManager, routeLevelCostEstimator);
- ((CalculatesServiceInsertionOnRouteLevel)jobInsertionCalculator).setNuOfActsForwardLooking(after);
- ((CalculatesServiceInsertionOnRouteLevel)jobInsertionCalculator).setMemorySize(solutionMemory);
- ((CalculatesServiceInsertionOnRouteLevel)jobInsertionCalculator).setNeighborhood(vrp.getNeighborhood());
- ((CalculatesServiceInsertionOnRouteLevel) jobInsertionCalculator).setStates(activityStates2);
+ ActivityInsertionCostsCalculator routeLevelCostEstimator;
+ if(activityInsertionCostCalculator == null){
+ routeLevelCostEstimator = new RouteLevelActivityInsertionCostsEstimator(vrp.getTransportCosts(), vrp.getActivityCosts(), activityStates2);
+ }
+ else{
+ routeLevelCostEstimator = activityInsertionCostCalculator;
+ }
+ JobInsertionCostsCalculator jobInsertionCalculator = new ServiceInsertionOnRouteLevelCalculator(vrp.getTransportCosts(), vrp.getActivityCosts(), routeLevelCostEstimator, constraintManager, constraintManager);
+ ((ServiceInsertionOnRouteLevelCalculator)jobInsertionCalculator).setNuOfActsForwardLooking(after);
+ ((ServiceInsertionOnRouteLevelCalculator)jobInsertionCalculator).setMemorySize(solutionMemory);
+ ((ServiceInsertionOnRouteLevelCalculator)jobInsertionCalculator).setNeighborhood(vrp.getNeighborhood());
+ ((ServiceInsertionOnRouteLevelCalculator) jobInsertionCalculator).setStates(activityStates2);
CalculatorPlusListeners calcPlusListener = new CalculatorPlusListeners(jobInsertionCalculator);
return calcPlusListener;
}
- private JobInsertionCalculator createFinalInsertion(VehicleFleetManager fleetManager, JobInsertionCalculator baseCalc, StateManager activityStates2){
- return new CalculatesVehTypeDepServiceInsertion(fleetManager, baseCalc);
+ private JobInsertionCostsCalculator createFinalInsertion(VehicleFleetManager fleetManager, JobInsertionCostsCalculator baseCalc, StateGetter activityStates2){
+ return new VehicleTypeDependentJobInsertionCalculator(fleetManager, baseCalc);
}
public void setConstraintManager(ConstraintManager constraintManager) {
diff --git a/jsprit-core/src/main/java/algorithms/ConfigureFixCostCalculator.java b/jsprit-core/src/main/java/algorithms/ConfigureFixCostCalculator.java
index 80b06a15..ed9fb977 100644
--- a/jsprit-core/src/main/java/algorithms/ConfigureFixCostCalculator.java
+++ b/jsprit-core/src/main/java/algorithms/ConfigureFixCostCalculator.java
@@ -37,11 +37,11 @@ final class ConfigureFixCostCalculator implements InsertionStartsListener, JobIn
VehicleRoutingProblem vrp;
- CalculatesServiceInsertionConsideringFixCost calcConsideringFix;
+ JobInsertionConsideringFixCostsCalculator calcConsideringFix;
private int nuOfJobsToRecreate;
- public ConfigureFixCostCalculator(VehicleRoutingProblem vrp, CalculatesServiceInsertionConsideringFixCost calcConsideringFix) {
+ public ConfigureFixCostCalculator(VehicleRoutingProblem vrp, JobInsertionConsideringFixCostsCalculator calcConsideringFix) {
super();
this.vrp = vrp;
this.calcConsideringFix = calcConsideringFix;
diff --git a/jsprit-core/src/main/java/algorithms/ConstraintManager.java b/jsprit-core/src/main/java/algorithms/ConstraintManager.java
new file mode 100644
index 00000000..d7713776
--- /dev/null
+++ b/jsprit-core/src/main/java/algorithms/ConstraintManager.java
@@ -0,0 +1,29 @@
+package algorithms;
+
+import basics.route.TourActivity;
+
+class ConstraintManager implements HardActivityLevelConstraint, HardRouteLevelConstraint{
+
+ private HardActivityLevelConstraintManager actLevelConstraintManager = new HardActivityLevelConstraintManager();
+
+ private HardRouteLevelConstraintManager routeLevelConstraintManager = new HardRouteLevelConstraintManager();
+
+ public void addConstraint(HardActivityLevelConstraint actLevelConstraint){
+ actLevelConstraintManager.addConstraint(actLevelConstraint);
+ }
+
+ public void addConstraint(HardRouteLevelConstraint routeLevelConstraint){
+ routeLevelConstraintManager.addConstraint(routeLevelConstraint);
+ }
+
+ @Override
+ public boolean fulfilled(InsertionContext insertionContext) {
+ return routeLevelConstraintManager.fulfilled(insertionContext);
+ }
+
+ @Override
+ public ConstraintsStatus fulfilled(InsertionContext iFacts, TourActivity prevAct,TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
+ return actLevelConstraintManager.fulfilled(iFacts, prevAct, newAct, nextAct, prevActDepTime);
+ }
+
+}
\ No newline at end of file
diff --git a/jsprit-core/src/main/java/algorithms/EuclideanServiceDistance.java b/jsprit-core/src/main/java/algorithms/EuclideanServiceDistance.java
index 5dc11af3..0f4641b3 100644
--- a/jsprit-core/src/main/java/algorithms/EuclideanServiceDistance.java
+++ b/jsprit-core/src/main/java/algorithms/EuclideanServiceDistance.java
@@ -27,7 +27,7 @@ class EuclideanServiceDistance implements JobDistance {
}
@Override
- public double calculateDistance(Job i, Job j) {
+ public double getDistance(Job i, Job j) {
double avgCost = 0.0;
if (i instanceof Service && j instanceof Service) {
if (i.equals(j)) {
diff --git a/jsprit-core/src/main/java/algorithms/FindCheaperVehicleAlgo.java b/jsprit-core/src/main/java/algorithms/FindCheaperVehicleAlgo.java
index 7354398c..abbfb90a 100644
--- a/jsprit-core/src/main/java/algorithms/FindCheaperVehicleAlgo.java
+++ b/jsprit-core/src/main/java/algorithms/FindCheaperVehicleAlgo.java
@@ -24,6 +24,7 @@ import org.apache.log4j.Logger;
import basics.route.TourActivities;
import basics.route.TourActivity;
import basics.route.Vehicle;
+import basics.route.VehicleFleetManager;
import basics.route.VehicleImpl.NoVehicle;
import basics.route.VehicleRoute;
@@ -41,13 +42,13 @@ final class FindCheaperVehicleAlgo {
private double weightFixCosts = 1.0;
- private StateManager states;
+ private StateGetter states;
public void setWeightFixCosts(double weightFixCosts) {
this.weightFixCosts = weightFixCosts;
}
- public void setStates(StateManager states) {
+ public void setStates(StateGetter states) {
this.states = states;
}
@@ -79,11 +80,11 @@ final class FindCheaperVehicleAlgo {
if(vehicle.getType().getTypeId().equals(vehicleRoute.getVehicle().getType().getTypeId())){
continue;
}
- if(states.getRouteState(vehicleRoute,StateTypes.LOAD).toDouble() <= vehicle.getCapacity()){
+ if(states.getRouteState(vehicleRoute,StateFactory.LOAD).toDouble() <= vehicle.getCapacity()){
double fixCostSaving = vehicleRoute.getVehicle().getType().getVehicleCostParams().fix - vehicle.getType().getVehicleCostParams().fix;
double departureTime = vehicleRoute.getStart().getEndTime();
double newCost = auxilliaryCostCalculator.costOfPath(path, departureTime, vehicleRoute.getDriver(), vehicle);
- double varCostSaving = states.getRouteState(vehicleRoute, StateTypes.COSTS).toDouble() - newCost;
+ double varCostSaving = states.getRouteState(vehicleRoute, StateFactory.COSTS).toDouble() - newCost;
double totalCostSaving = varCostSaving + weightFixCosts*fixCostSaving;
if(totalCostSaving > bestSaving){
bestSaving = totalCostSaving;
diff --git a/jsprit-core/src/main/java/algorithms/Gendreau.java b/jsprit-core/src/main/java/algorithms/Gendreau.java
index 951314ff..7c46473d 100644
--- a/jsprit-core/src/main/java/algorithms/Gendreau.java
+++ b/jsprit-core/src/main/java/algorithms/Gendreau.java
@@ -28,14 +28,15 @@ import java.util.Set;
import org.apache.log4j.Logger;
import util.RandomNumberGeneration;
-import algorithms.RuinStrategy.RuinListener;
import basics.Job;
import basics.VehicleRoutingProblem;
import basics.VehicleRoutingProblemSolution;
import basics.algo.InsertionListener;
+import basics.algo.RuinListener;
import basics.algo.SearchStrategyModule;
import basics.algo.SearchStrategyModuleListener;
import basics.route.TourActivity;
+import basics.route.VehicleFleetManager;
import basics.route.TourActivity.JobActivity;
import basics.route.VehicleRoute;
diff --git a/jsprit-core/src/main/java/algorithms/HardActivityLevelConstraint.java b/jsprit-core/src/main/java/algorithms/HardActivityLevelConstraint.java
new file mode 100644
index 00000000..fc3e878c
--- /dev/null
+++ b/jsprit-core/src/main/java/algorithms/HardActivityLevelConstraint.java
@@ -0,0 +1,15 @@
+package algorithms;
+
+import basics.route.TourActivity;
+
+public interface HardActivityLevelConstraint {
+
+ static enum ConstraintsStatus {
+
+ NOT_FULFILLED_BREAK, NOT_FULFILLED, FULFILLED;
+
+ }
+
+ public ConstraintsStatus fulfilled(InsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime);
+
+}
\ No newline at end of file
diff --git a/jsprit-core/src/main/java/algorithms/HardActivityLevelConstraintManager.java b/jsprit-core/src/main/java/algorithms/HardActivityLevelConstraintManager.java
new file mode 100644
index 00000000..da5dc409
--- /dev/null
+++ b/jsprit-core/src/main/java/algorithms/HardActivityLevelConstraintManager.java
@@ -0,0 +1,27 @@
+package algorithms;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import basics.route.TourActivity;
+
+class HardActivityLevelConstraintManager implements HardActivityLevelConstraint {
+
+ private Collection hardConstraints = new ArrayList();
+
+ public void addConstraint(HardActivityLevelConstraint constraint){
+ hardConstraints.add(constraint);
+ }
+
+ @Override
+ public ConstraintsStatus fulfilled(InsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
+ for(HardActivityLevelConstraint constraint : hardConstraints){
+ ConstraintsStatus status = constraint.fulfilled(iFacts, prevAct, newAct, nextAct, prevActDepTime);
+ if(status.equals(ConstraintsStatus.NOT_FULFILLED_BREAK) || status.equals(ConstraintsStatus.NOT_FULFILLED)){
+ return status;
+ }
+ }
+ return ConstraintsStatus.FULFILLED;
+ }
+
+}
\ No newline at end of file
diff --git a/jsprit-core/src/main/java/algorithms/HardConstraints.java b/jsprit-core/src/main/java/algorithms/HardConstraints.java
deleted file mode 100644
index 1fc26fd5..00000000
--- a/jsprit-core/src/main/java/algorithms/HardConstraints.java
+++ /dev/null
@@ -1,382 +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 .
- ******************************************************************************/
-package algorithms;
-
-import java.util.ArrayList;
-import java.util.Collection;
-
-import org.apache.log4j.Logger;
-
-import basics.Delivery;
-import basics.Pickup;
-import basics.Service;
-import basics.costs.VehicleRoutingTransportCosts;
-import basics.route.DeliverService;
-import basics.route.DeliverShipment;
-import basics.route.DeliveryActivity;
-import basics.route.PickupActivity;
-import basics.route.PickupService;
-import basics.route.PickupShipment;
-import basics.route.ServiceActivity;
-import basics.route.Start;
-import basics.route.TourActivity;
-
-/**
- * collection of hard constrainters bot at activity and at route level.
- *
- * HardPickupAndDeliveryLoadConstraint requires LOAD_AT_DEPOT and LOAD (i.e. load at end) at route-level
- *
- *
HardTimeWindowConstraint requires LATEST_OPERATION_START_TIME
- *
- *
HardPickupAndDeliveryConstraint requires LOAD_AT_DEPOT and LOAD at route-level and FUTURE_PICKS and PAST_DELIVIERS on activity-level
- *
- *
HardPickupAndDeliveryBackhaulConstraint requires LOAD_AT_DEPOT and LOAD at route-level and FUTURE_PICKS and PAST_DELIVIERS on activity-level
- *
- * @author stefan
- *
- */
-class HardConstraints {
-
- interface HardRouteLevelConstraint {
-
- public boolean fulfilled(InsertionContext insertionContext);
-
- }
-
- interface HardActivityLevelConstraint {
-
- public boolean fulfilled(InsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime);
-
- }
-
- static class HardRouteLevelConstraintManager implements HardRouteLevelConstraint {
-
- private Collection hardConstraints = new ArrayList();
-
- public void addConstraint(HardRouteLevelConstraint constraint){
- hardConstraints.add(constraint);
- }
-
- @Override
- public boolean fulfilled(InsertionContext insertionContext) {
- for(HardRouteLevelConstraint constraint : hardConstraints){
- if(!constraint.fulfilled(insertionContext)){
- return false;
- }
- }
- return true;
- }
-
- }
-
- static class ConstraintManager implements HardActivityLevelConstraint, HardRouteLevelConstraint{
-
- private HardActivityLevelConstraintManager actLevelConstraintManager = new HardActivityLevelConstraintManager();
-
- private HardRouteLevelConstraintManager routeLevelConstraintManager = new HardRouteLevelConstraintManager();
-
- public void addConstraint(HardActivityLevelConstraint actLevelConstraint){
- actLevelConstraintManager.addConstraint(actLevelConstraint);
- }
-
- public void addConstraint(HardRouteLevelConstraint routeLevelConstraint){
- routeLevelConstraintManager.addConstraint(routeLevelConstraint);
- }
-
- @Override
- public boolean fulfilled(InsertionContext insertionContext) {
- return routeLevelConstraintManager.fulfilled(insertionContext);
- }
-
- @Override
- public boolean fulfilled(InsertionContext iFacts, TourActivity prevAct,TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
- return actLevelConstraintManager.fulfilled(iFacts, prevAct, newAct, nextAct, prevActDepTime);
- }
-
- }
-
- static class HardActivityLevelConstraintManager implements HardActivityLevelConstraint {
-
- private Collection hardConstraints = new ArrayList();
-
- public void addConstraint(HardActivityLevelConstraint constraint){
- hardConstraints.add(constraint);
- }
-
- @Override
- public boolean fulfilled(InsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
- for(HardActivityLevelConstraint constraint : hardConstraints){
- if(!constraint.fulfilled(iFacts, prevAct, newAct, nextAct, prevActDepTime)){
- return false;
- }
- }
- return true;
- }
-
- }
-
- static class HardLoadConstraint implements HardRouteLevelConstraint{
-
- private StateManager states;
-
- public HardLoadConstraint(StateManager states) {
- super();
- this.states = states;
- }
-
- @Override
- public boolean fulfilled(InsertionContext insertionContext) {
- int currentLoad = (int) states.getRouteState(insertionContext.getRoute(), StateTypes.LOAD).toDouble();
- Service service = (Service) insertionContext.getJob();
- if(currentLoad + service.getCapacityDemand() > insertionContext.getNewVehicle().getCapacity()){
- return false;
- }
- return true;
- }
- }
-
- /**
- * lsjdfjsdlfjsa
- *
- * @author stefan
- *
- */
- static class HardPickupAndDeliveryLoadConstraint implements HardRouteLevelConstraint {
-
- private StateManager stateManager;
-
- public HardPickupAndDeliveryLoadConstraint(StateManager stateManager) {
- super();
- this.stateManager = stateManager;
- }
-
- @Override
- public boolean fulfilled(InsertionContext insertionContext) {
- if(insertionContext.getJob() instanceof Delivery){
- int loadAtDepot = (int) stateManager.getRouteState(insertionContext.getRoute(), StateTypes.LOAD_AT_DEPOT).toDouble();
- if(loadAtDepot + insertionContext.getJob().getCapacityDemand() > insertionContext.getNewVehicle().getCapacity()){
- return false;
- }
- }
- else if(insertionContext.getJob() instanceof Pickup || insertionContext.getJob() instanceof Service){
- int loadAtEnd = (int) stateManager.getRouteState(insertionContext.getRoute(), StateTypes.LOAD).toDouble();
- if(loadAtEnd + insertionContext.getJob().getCapacityDemand() > insertionContext.getNewVehicle().getCapacity()){
- return false;
- }
- }
- return true;
- }
-
- }
-
- /**
- * ljsljslfjs
- * @author stefan
- *
- */
- public static class HardTimeWindowActivityLevelConstraint implements HardActivityLevelConstraint {
-
- private static Logger log = Logger.getLogger(HardTimeWindowActivityLevelConstraint.class);
-
- private StateManager states;
-
- private VehicleRoutingTransportCosts routingCosts;
-
- public HardTimeWindowActivityLevelConstraint(StateManager states, VehicleRoutingTransportCosts routingCosts) {
- super();
- this.states = states;
- this.routingCosts = routingCosts;
- }
-
- @Override
- public boolean fulfilled(InsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
-// log.info("check insertion of " + newAct + " between " + prevAct + " and " + nextAct + ". prevActDepTime=" + prevActDepTime);
- double arrTimeAtNewAct = prevActDepTime + routingCosts.getTransportTime(prevAct.getLocationId(), newAct.getLocationId(), prevActDepTime, iFacts.getNewDriver(), iFacts.getNewVehicle());
- double latestArrTimeAtNewAct = states.getActivityState(newAct, StateTypes.LATEST_OPERATION_START_TIME).toDouble();
- if(arrTimeAtNewAct > latestArrTimeAtNewAct){
- return false;
- }
-// log.info(newAct + " arrTime=" + arrTimeAtNewAct);
- double endTimeAtNewAct = CalcUtils.getActivityEndTime(arrTimeAtNewAct, newAct);
- double arrTimeAtNextAct = endTimeAtNewAct + routingCosts.getTransportTime(newAct.getLocationId(), nextAct.getLocationId(), endTimeAtNewAct, iFacts.getNewDriver(), iFacts.getNewVehicle());
- double latestArrTimeAtNextAct = states.getActivityState(nextAct, StateTypes.LATEST_OPERATION_START_TIME).toDouble();
- if(arrTimeAtNextAct > latestArrTimeAtNextAct){
- return false;
- }
-// log.info(nextAct + " arrTime=" + arrTimeAtNextAct);
- return true;
- }
- }
-
- static class HardPickupAndDeliveryActivityLevelConstraint implements HardActivityLevelConstraint {
-
- private StateManager stateManager;
-
- private boolean backhaul = false;
-
- public HardPickupAndDeliveryActivityLevelConstraint(StateManager stateManager) {
- super();
- this.stateManager = stateManager;
- }
-
- public HardPickupAndDeliveryActivityLevelConstraint(StateManager stateManager, boolean backhaul) {
- super();
- this.stateManager = stateManager;
- this.backhaul = backhaul;
- }
-
- @Override
- public boolean fulfilled(InsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
- if(!(newAct instanceof PickupService) && !(newAct instanceof DeliverService)){
- return true;
- }
- if(backhaul){
- if(newAct instanceof PickupService && nextAct instanceof DeliverService){ return false; }
- if(newAct instanceof DeliverService && prevAct instanceof PickupService){ return false; }
- }
- int loadAtPrevAct;
- int futurePicks;
- int pastDeliveries;
- if(prevAct instanceof Start){
- loadAtPrevAct = (int)stateManager.getRouteState(iFacts.getRoute(), StateTypes.LOAD_AT_DEPOT).toDouble();
- futurePicks = (int)stateManager.getRouteState(iFacts.getRoute(), StateTypes.LOAD).toDouble();
- pastDeliveries = 0;
- }
- else{
- loadAtPrevAct = (int) stateManager.getActivityState(prevAct, StateTypes.LOAD).toDouble();
- futurePicks = (int) stateManager.getActivityState(prevAct, StateTypes.FUTURE_PICKS).toDouble();
- pastDeliveries = (int) stateManager.getActivityState(prevAct, StateTypes.PAST_DELIVERIES).toDouble();
- }
- if(newAct instanceof PickupService){
- if(loadAtPrevAct + newAct.getCapacityDemand() + futurePicks > iFacts.getNewVehicle().getCapacity()){
- return false;
- }
- }
- if(newAct instanceof DeliverService){
- if(loadAtPrevAct + Math.abs(newAct.getCapacityDemand()) + pastDeliveries > iFacts.getNewVehicle().getCapacity()){
- return false;
- }
-
- }
- return true;
- }
-
- }
-
- static class HardPickupAndDeliveryShipmentActivityLevelConstraint implements HardActivityLevelConstraint {
-
- private StateManager stateManager;
-
- private boolean backhaul = false;
-
- public HardPickupAndDeliveryShipmentActivityLevelConstraint(StateManager stateManager) {
- super();
- this.stateManager = stateManager;
- }
-
- public HardPickupAndDeliveryShipmentActivityLevelConstraint(StateManager stateManager, boolean backhaul) {
- super();
- this.stateManager = stateManager;
- this.backhaul = backhaul;
- }
-
- @Override
- public boolean fulfilled(InsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
- if(!(newAct instanceof PickupShipment) && !(newAct instanceof DeliverShipment)){
- return true;
- }
- if(backhaul){
-// if(newAct instanceof PickupShipment && nextAct instanceof DeliverShipment){ return false; }
- if(newAct instanceof DeliverShipment && prevAct instanceof PickupShipment){ return false; }
- }
- int loadAtPrevAct;
-// int futurePicks;
-// int pastDeliveries;
- if(prevAct instanceof Start){
- loadAtPrevAct = (int)stateManager.getRouteState(iFacts.getRoute(), StateTypes.LOAD_AT_DEPOT).toDouble();
-// futurePicks = (int)stateManager.getRouteState(iFacts.getRoute(), StateTypes.LOAD).toDouble();
-// pastDeliveries = 0;
- }
- else{
- loadAtPrevAct = (int) stateManager.getActivityState(prevAct, StateTypes.LOAD).toDouble();
-// futurePicks = (int) stateManager.getActivityState(prevAct, StateTypes.FUTURE_PICKS).toDouble();
-// pastDeliveries = (int) stateManager.getActivityState(prevAct, StateTypes.PAST_DELIVERIES).toDouble();
- }
- if(newAct instanceof PickupShipment){
- if(loadAtPrevAct + newAct.getCapacityDemand() > iFacts.getNewVehicle().getCapacity()){
- return false;
- }
- }
- if(newAct instanceof DeliverShipment){
- if(loadAtPrevAct + Math.abs(newAct.getCapacityDemand()) > iFacts.getNewVehicle().getCapacity()){
- return false;
- }
-
- }
- return true;
- }
-
- }
-
-
- static class HardPickupAndDeliveryBackhaulActivityLevelConstraint implements HardActivityLevelConstraint {
-
- private StateManager stateManager;
-
- public HardPickupAndDeliveryBackhaulActivityLevelConstraint(StateManager stateManager) {
- super();
- this.stateManager = stateManager;
- }
-
- @Override
- public boolean fulfilled(InsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
- if(newAct instanceof PickupService && nextAct instanceof DeliverService){ return false; }
-// if(newAct instanceof ServiceActivity && nextAct instanceof DeliveryActivity){ return false; }
- if(newAct instanceof DeliverService && prevAct instanceof PickupService){ return false; }
-// if(newAct instanceof DeliveryActivity && prevAct instanceof ServiceActivity){ return false; }
- int loadAtPrevAct;
- int futurePicks;
- int pastDeliveries;
- if(prevAct instanceof Start){
- loadAtPrevAct = (int)stateManager.getRouteState(iFacts.getRoute(), StateTypes.LOAD_AT_DEPOT).toDouble();
- futurePicks = (int)stateManager.getRouteState(iFacts.getRoute(), StateTypes.LOAD).toDouble();
- pastDeliveries = 0;
- }
- else{
- loadAtPrevAct = (int) stateManager.getActivityState(prevAct, StateTypes.LOAD).toDouble();
- futurePicks = (int) stateManager.getActivityState(prevAct, StateTypes.FUTURE_PICKS).toDouble();
- pastDeliveries = (int) stateManager.getActivityState(prevAct, StateTypes.PAST_DELIVERIES).toDouble();
- }
- if(newAct instanceof PickupActivity || newAct instanceof ServiceActivity){
- if(loadAtPrevAct + newAct.getCapacityDemand() + futurePicks > iFacts.getNewVehicle().getCapacity()){
- return false;
- }
- }
- if(newAct instanceof DeliveryActivity){
- if(loadAtPrevAct + Math.abs(newAct.getCapacityDemand()) + pastDeliveries > iFacts.getNewVehicle().getCapacity()){
- return false;
- }
-
- }
- return true;
- }
-
- }
-
-
-
-}
diff --git a/jsprit-core/src/main/java/algorithms/HardLoadConstraint.java b/jsprit-core/src/main/java/algorithms/HardLoadConstraint.java
new file mode 100644
index 00000000..0cc1dbd2
--- /dev/null
+++ b/jsprit-core/src/main/java/algorithms/HardLoadConstraint.java
@@ -0,0 +1,23 @@
+package algorithms;
+
+import basics.Service;
+
+class HardLoadConstraint implements HardRouteLevelConstraint{
+
+ private StateGetter states;
+
+ public HardLoadConstraint(StateGetter states) {
+ super();
+ this.states = states;
+ }
+
+ @Override
+ public boolean fulfilled(InsertionContext insertionContext) {
+ int currentLoad = (int) states.getRouteState(insertionContext.getRoute(), StateFactory.LOAD).toDouble();
+ Service service = (Service) insertionContext.getJob();
+ if(currentLoad + service.getCapacityDemand() > insertionContext.getNewVehicle().getCapacity()){
+ return false;
+ }
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/jsprit-core/src/main/java/algorithms/HardPickupAndDeliveryActivityLevelConstraint.java b/jsprit-core/src/main/java/algorithms/HardPickupAndDeliveryActivityLevelConstraint.java
new file mode 100644
index 00000000..f7b9e06c
--- /dev/null
+++ b/jsprit-core/src/main/java/algorithms/HardPickupAndDeliveryActivityLevelConstraint.java
@@ -0,0 +1,47 @@
+package algorithms;
+
+import basics.route.DeliveryActivity;
+import basics.route.PickupActivity;
+import basics.route.ServiceActivity;
+import basics.route.Start;
+import basics.route.TourActivity;
+
+class HardPickupAndDeliveryActivityLevelConstraint implements HardActivityLevelConstraint {
+
+ private StateGetter stateManager;
+
+ public HardPickupAndDeliveryActivityLevelConstraint(StateGetter stateManager) {
+ super();
+ this.stateManager = stateManager;
+ }
+
+ @Override
+ public ConstraintsStatus fulfilled(InsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
+ int loadAtPrevAct;
+ int futurePicks;
+ int pastDeliveries;
+ if(prevAct instanceof Start){
+ loadAtPrevAct = (int)stateManager.getRouteState(iFacts.getRoute(), StateFactory.LOAD_AT_BEGINNING).toDouble();
+ futurePicks = (int)stateManager.getRouteState(iFacts.getRoute(), StateFactory.LOAD_AT_END).toDouble();
+ pastDeliveries = 0;
+ }
+ else{
+ loadAtPrevAct = (int) stateManager.getActivityState(prevAct, StateFactory.LOAD).toDouble();
+ futurePicks = (int) stateManager.getActivityState(prevAct, StateFactory.FUTURE_PICKS).toDouble();
+ pastDeliveries = (int) stateManager.getActivityState(prevAct, StateFactory.PAST_DELIVERIES).toDouble();
+ }
+ if(newAct instanceof PickupActivity || newAct instanceof ServiceActivity){
+ if(loadAtPrevAct + newAct.getCapacityDemand() + futurePicks > iFacts.getNewVehicle().getCapacity()){
+ return ConstraintsStatus.NOT_FULFILLED;
+ }
+ }
+ if(newAct instanceof DeliveryActivity){
+ if(loadAtPrevAct + Math.abs(newAct.getCapacityDemand()) + pastDeliveries > iFacts.getNewVehicle().getCapacity()){
+ return ConstraintsStatus.NOT_FULFILLED;
+ }
+
+ }
+ return ConstraintsStatus.FULFILLED;
+ }
+
+}
\ No newline at end of file
diff --git a/jsprit-core/src/main/java/algorithms/HardPickupAndDeliveryBackhaulActivityLevelConstraint.java b/jsprit-core/src/main/java/algorithms/HardPickupAndDeliveryBackhaulActivityLevelConstraint.java
new file mode 100644
index 00000000..007912f2
--- /dev/null
+++ b/jsprit-core/src/main/java/algorithms/HardPickupAndDeliveryBackhaulActivityLevelConstraint.java
@@ -0,0 +1,51 @@
+package algorithms;
+
+import basics.route.DeliveryActivity;
+import basics.route.PickupActivity;
+import basics.route.ServiceActivity;
+import basics.route.Start;
+import basics.route.TourActivity;
+
+class HardPickupAndDeliveryBackhaulActivityLevelConstraint implements HardActivityLevelConstraint {
+
+ private StateGetter stateManager;
+
+ public HardPickupAndDeliveryBackhaulActivityLevelConstraint(StateGetter stateManager) {
+ super();
+ this.stateManager = stateManager;
+ }
+
+ @Override
+ public ConstraintsStatus fulfilled(InsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
+ if(newAct instanceof PickupActivity && nextAct instanceof DeliveryActivity){ return ConstraintsStatus.NOT_FULFILLED; }
+ if(newAct instanceof ServiceActivity && nextAct instanceof DeliveryActivity){ return ConstraintsStatus.NOT_FULFILLED; }
+ if(newAct instanceof DeliveryActivity && prevAct instanceof PickupActivity){ return ConstraintsStatus.NOT_FULFILLED; }
+ if(newAct instanceof DeliveryActivity && prevAct instanceof ServiceActivity){ return ConstraintsStatus.NOT_FULFILLED; }
+ int loadAtPrevAct;
+ int futurePicks;
+ int pastDeliveries;
+ if(prevAct instanceof Start){
+ loadAtPrevAct = (int)stateManager.getRouteState(iFacts.getRoute(), StateFactory.LOAD_AT_BEGINNING).toDouble();
+ futurePicks = (int)stateManager.getRouteState(iFacts.getRoute(), StateFactory.LOAD_AT_END).toDouble();
+ pastDeliveries = 0;
+ }
+ else{
+ loadAtPrevAct = (int) stateManager.getActivityState(prevAct, StateFactory.LOAD).toDouble();
+ futurePicks = (int) stateManager.getActivityState(prevAct, StateFactory.FUTURE_PICKS).toDouble();
+ pastDeliveries = (int) stateManager.getActivityState(prevAct, StateFactory.PAST_DELIVERIES).toDouble();
+ }
+ if(newAct instanceof PickupActivity || newAct instanceof ServiceActivity){
+ if(loadAtPrevAct + newAct.getCapacityDemand() + futurePicks > iFacts.getNewVehicle().getCapacity()){
+ return ConstraintsStatus.NOT_FULFILLED;
+ }
+ }
+ if(newAct instanceof DeliveryActivity){
+ if(loadAtPrevAct + Math.abs(newAct.getCapacityDemand()) + pastDeliveries > iFacts.getNewVehicle().getCapacity()){
+ return ConstraintsStatus.NOT_FULFILLED;
+ }
+
+ }
+ return ConstraintsStatus.FULFILLED;
+ }
+
+}
\ No newline at end of file
diff --git a/jsprit-core/src/main/java/algorithms/HardPickupAndDeliveryLoadRouteLevelConstraint.java b/jsprit-core/src/main/java/algorithms/HardPickupAndDeliveryLoadRouteLevelConstraint.java
new file mode 100644
index 00000000..b5281620
--- /dev/null
+++ b/jsprit-core/src/main/java/algorithms/HardPickupAndDeliveryLoadRouteLevelConstraint.java
@@ -0,0 +1,39 @@
+package algorithms;
+
+import basics.Delivery;
+import basics.Pickup;
+import basics.Service;
+
+/**
+ * lsjdfjsdlfjsa
+ *
+ * @author stefan
+ *
+ */
+class HardPickupAndDeliveryLoadRouteLevelConstraint implements HardRouteLevelConstraint {
+
+ private StateGetter stateManager;
+
+ public HardPickupAndDeliveryLoadRouteLevelConstraint(StateGetter stateManager) {
+ super();
+ this.stateManager = stateManager;
+ }
+
+ @Override
+ public boolean fulfilled(InsertionContext insertionContext) {
+ if(insertionContext.getJob() instanceof Delivery){
+ int loadAtDepot = (int) stateManager.getRouteState(insertionContext.getRoute(), StateFactory.LOAD_AT_BEGINNING).toDouble();
+ if(loadAtDepot + insertionContext.getJob().getCapacityDemand() > insertionContext.getNewVehicle().getCapacity()){
+ return false;
+ }
+ }
+ else if(insertionContext.getJob() instanceof Pickup || insertionContext.getJob() instanceof Service){
+ int loadAtEnd = (int) stateManager.getRouteState(insertionContext.getRoute(), StateFactory.LOAD_AT_END).toDouble();
+ if(loadAtEnd + insertionContext.getJob().getCapacityDemand() > insertionContext.getNewVehicle().getCapacity()){
+ return false;
+ }
+ }
+ return true;
+ }
+
+}
\ No newline at end of file
diff --git a/jsprit-core/src/main/java/algorithms/HardRouteLevelConstraint.java b/jsprit-core/src/main/java/algorithms/HardRouteLevelConstraint.java
new file mode 100644
index 00000000..9cbd6258
--- /dev/null
+++ b/jsprit-core/src/main/java/algorithms/HardRouteLevelConstraint.java
@@ -0,0 +1,8 @@
+package algorithms;
+
+
+public interface HardRouteLevelConstraint {
+
+ public boolean fulfilled(InsertionContext insertionContext);
+
+}
\ No newline at end of file
diff --git a/jsprit-core/src/main/java/algorithms/HardRouteLevelConstraintManager.java b/jsprit-core/src/main/java/algorithms/HardRouteLevelConstraintManager.java
new file mode 100644
index 00000000..c9fe37fb
--- /dev/null
+++ b/jsprit-core/src/main/java/algorithms/HardRouteLevelConstraintManager.java
@@ -0,0 +1,25 @@
+package algorithms;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+
+class HardRouteLevelConstraintManager implements HardRouteLevelConstraint {
+
+ private Collection hardConstraints = new ArrayList();
+
+ public void addConstraint(HardRouteLevelConstraint constraint){
+ hardConstraints.add(constraint);
+ }
+
+ @Override
+ public boolean fulfilled(InsertionContext insertionContext) {
+ for(HardRouteLevelConstraint constraint : hardConstraints){
+ if(!constraint.fulfilled(insertionContext)){
+ return false;
+ }
+ }
+ return true;
+ }
+
+}
\ No newline at end of file
diff --git a/jsprit-core/src/main/java/algorithms/HardTimeWindowActivityLevelConstraint.java b/jsprit-core/src/main/java/algorithms/HardTimeWindowActivityLevelConstraint.java
new file mode 100644
index 00000000..137b0a81
--- /dev/null
+++ b/jsprit-core/src/main/java/algorithms/HardTimeWindowActivityLevelConstraint.java
@@ -0,0 +1,51 @@
+package algorithms;
+
+import org.apache.log4j.Logger;
+
+import basics.costs.VehicleRoutingTransportCosts;
+import basics.route.TourActivity;
+
+/**
+ * ljsljslfjs
+ * @author stefan
+ *
+ */
+ class HardTimeWindowActivityLevelConstraint implements HardActivityLevelConstraint {
+
+ private static Logger log = Logger.getLogger(HardTimeWindowActivityLevelConstraint.class);
+
+ private StateGetter states;
+
+ private VehicleRoutingTransportCosts routingCosts;
+
+ public HardTimeWindowActivityLevelConstraint(StateGetter states, VehicleRoutingTransportCosts routingCosts) {
+ super();
+ this.states = states;
+ this.routingCosts = routingCosts;
+ }
+
+ @Override
+ public ConstraintsStatus fulfilled(InsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
+ if(newAct.getTheoreticalLatestOperationStartTime() < prevAct.getTheoreticalEarliestOperationStartTime()){
+ return ConstraintsStatus.NOT_FULFILLED_BREAK;
+ }
+ if(newAct.getTheoreticalEarliestOperationStartTime() > nextAct.getTheoreticalLatestOperationStartTime()){
+ return ConstraintsStatus.NOT_FULFILLED;
+ }
+ // log.info("check insertion of " + newAct + " between " + prevAct + " and " + nextAct + ". prevActDepTime=" + prevActDepTime);
+ double arrTimeAtNewAct = prevActDepTime + routingCosts.getTransportTime(prevAct.getLocationId(), newAct.getLocationId(), prevActDepTime, iFacts.getNewDriver(), iFacts.getNewVehicle());
+ double latestArrTimeAtNewAct = states.getActivityState(newAct, StateFactory.LATEST_OPERATION_START_TIME).toDouble();
+
+ if(arrTimeAtNewAct > latestArrTimeAtNewAct){
+ return ConstraintsStatus.NOT_FULFILLED;
+ }
+// log.info(newAct + " arrTime=" + arrTimeAtNewAct);
+ double endTimeAtNewAct = CalculationUtils.getActivityEndTime(arrTimeAtNewAct, newAct);
+ double arrTimeAtNextAct = endTimeAtNewAct + routingCosts.getTransportTime(newAct.getLocationId(), nextAct.getLocationId(), endTimeAtNewAct, iFacts.getNewDriver(), iFacts.getNewVehicle());
+ double latestArrTimeAtNextAct = states.getActivityState(nextAct, StateFactory.LATEST_OPERATION_START_TIME).toDouble();
+ if(arrTimeAtNextAct > latestArrTimeAtNextAct){
+ return ConstraintsStatus.NOT_FULFILLED;
+ }
+ return ConstraintsStatus.FULFILLED;
+ }
+ }
\ No newline at end of file
diff --git a/jsprit-core/src/main/java/algorithms/InitialSolutionFactory.java b/jsprit-core/src/main/java/algorithms/InitialSolutionFactory.java
index 1bc2e612..0942bddd 100644
--- a/jsprit-core/src/main/java/algorithms/InitialSolutionFactory.java
+++ b/jsprit-core/src/main/java/algorithms/InitialSolutionFactory.java
@@ -21,8 +21,8 @@ import basics.VehicleRoutingProblemSolution;
-interface InitialSolutionFactory {
+public interface InitialSolutionFactory {
- public VehicleRoutingProblemSolution createInitialSolution(VehicleRoutingProblem vrp);
+ public VehicleRoutingProblemSolution createSolution(VehicleRoutingProblem vrp);
}
diff --git a/jsprit-core/src/main/java/algorithms/InsertionContext.java b/jsprit-core/src/main/java/algorithms/InsertionContext.java
index 150ea6cf..16c5c377 100644
--- a/jsprit-core/src/main/java/algorithms/InsertionContext.java
+++ b/jsprit-core/src/main/java/algorithms/InsertionContext.java
@@ -21,7 +21,7 @@ import basics.route.Driver;
import basics.route.Vehicle;
import basics.route.VehicleRoute;
-class InsertionContext {
+public class InsertionContext {
private VehicleRoute route;
private Job job;
diff --git a/jsprit-core/src/main/java/algorithms/InsertionData.java b/jsprit-core/src/main/java/algorithms/InsertionData.java
index c06be526..e033684d 100644
--- a/jsprit-core/src/main/java/algorithms/InsertionData.java
+++ b/jsprit-core/src/main/java/algorithms/InsertionData.java
@@ -19,9 +19,14 @@ package algorithms;
import basics.route.Driver;
import basics.route.Vehicle;
-
-
-class InsertionData {
+/**
+ * Data object that collects insertion information. It collects insertionCosts, insertionIndeces, vehicle and driver to be employed
+ * and departureTime of vehicle at vehicle's start location (e.g. depot).
+ *
+ * @author stefan
+ *
+ */
+public class InsertionData {
static class NoInsertionFound extends InsertionData{
@@ -33,7 +38,15 @@ class InsertionData {
private static InsertionData noInsertion = new NoInsertionFound();
- public static InsertionData noInsertionFound(){
+ /**
+ * Returns an instance of InsertionData that represents an EmptyInsertionData (which might indicate
+ * that no insertion has been found). It is internally instantiated as follows:
+ * new InsertionData(Double.MAX_VALUE, NO_INDEX, NO_INDEX, null, null);
+ * where NO_INDEX=-1.
+ *
+ * @return
+ */
+ public static InsertionData createEmptyInsertionData(){
return noInsertion;
}
@@ -80,22 +93,47 @@ class InsertionData {
return "[iCost="+insertionCost+"][iIndex="+deliveryInsertionIndex+"][depTime="+departureTime+"][vehicle="+selectedVehicle+"][driver="+selectedDriver+"]";
}
+ /**
+ * Returns insertionIndex of deliveryActivity. If no insertionPosition is found, it returns NO_INDEX (=-1).
+ *
+ * @return
+ */
public int getDeliveryInsertionIndex(){
return deliveryInsertionIndex;
}
+ /**
+ * Returns insertionIndex of pickkupActivity. If no insertionPosition is found, it returns NO_INDEX (=-1).
+ *
+ * @return
+ */
public int getPickupInsertionIndex(){
return pickupInsertionIndex;
}
+ /**
+ * Returns insertion costs (which might be the additional costs of inserting the corresponding job).
+ *
+ * @return
+ */
public double getInsertionCost() {
return insertionCost;
}
+ /**
+ * Returns the vehicle to be employed.
+ *
+ * @return
+ */
public Vehicle getSelectedVehicle() {
return selectedVehicle;
}
+ /**
+ * Returns the vehicle to be employed.
+ *
+ * @return
+ */
public Driver getSelectedDriver(){
return selectedDriver;
}
diff --git a/jsprit-core/src/main/java/algorithms/InsertionFactory.java b/jsprit-core/src/main/java/algorithms/InsertionFactory.java
index 9dae4a80..64ec876e 100644
--- a/jsprit-core/src/main/java/algorithms/InsertionFactory.java
+++ b/jsprit-core/src/main/java/algorithms/InsertionFactory.java
@@ -23,19 +23,18 @@ import java.util.concurrent.ExecutorService;
import org.apache.commons.configuration.HierarchicalConfiguration;
import org.apache.log4j.Logger;
-import algorithms.HardConstraints.ConstraintManager;
import basics.VehicleRoutingProblem;
import basics.algo.InsertionListener;
import basics.algo.VehicleRoutingAlgorithmListeners.PrioritizedVRAListener;
+import basics.route.VehicleFleetManager;
class InsertionFactory {
private static Logger log = Logger.getLogger(InsertionFactory.class);
public static InsertionStrategy createInsertion(VehicleRoutingProblem vrp, HierarchicalConfiguration config,
- VehicleFleetManager vehicleFleetManager, StateManagerImpl routeStates, List algorithmListeners, ExecutorService executorService, int nuOfThreads, ConstraintManager constraintManager){
- boolean concurrentInsertion = false;
- if(executorService != null) concurrentInsertion = true;
+ VehicleFleetManager vehicleFleetManager, StateManager routeStates, List algorithmListeners, ExecutorService executorService, int nuOfThreads, ConstraintManager constraintManager){
+
if(config.containsKey("[@name]")){
String insertionName = config.getString("[@name]");
if(!insertionName.equals("bestInsertion") && !insertionName.equals("regretInsertion")){
@@ -89,27 +88,14 @@ class InsertionFactory {
calcBuilder.experimentalTimeScheduler(Double.parseDouble(timeSliceString),Integer.parseInt(neighbors));
}
- JobInsertionCalculator jic = calcBuilder.build();
+ JobInsertionCostsCalculator jic = calcBuilder.build();
if(insertionName.equals("bestInsertion")){
insertionStrategy = new BestInsertion(jic);
}
-// else if(insertionName.equals("regretInsertion")){
-// insertionStrategy = RegretInsertion.newInstance(routeAlgorithm);
-// }
-
-// insertionStrategy.addListener(new RemoveEmptyVehicles(vehicleFleetManager));
-// insertionStrategy.addListener(new ResetAndIniFleetManager(vehicleFleetManager));
-// insertionStrategy.addListener(new VehicleSwitched(vehicleFleetManager));
-
-// insertionStrategy.addListener(new UpdateLoadAtRouteLevel(routeStates));
-
-// insertionStrategy.addListener(new UpdateStates(routeStates, vrp.getTransportCosts(), vrp.getActivityCosts()));
for(InsertionListener l : insertionListeners) insertionStrategy.addListener(l);
-// insertionStrategy.addListener(new FindCheaperVehicle(
-// new FindCheaperVehicleAlgoNew(vehicleFleetManager, tourStateCalculator, auxCalculator)));
-
+
algorithmListeners.addAll(algoListeners);
return insertionStrategy;
diff --git a/jsprit-core/src/main/java/algorithms/CreateInitialSolution.java b/jsprit-core/src/main/java/algorithms/InsertionInitialSolutionFactory.java
similarity index 52%
rename from jsprit-core/src/main/java/algorithms/CreateInitialSolution.java
rename to jsprit-core/src/main/java/algorithms/InsertionInitialSolutionFactory.java
index b2e9655b..39e990ce 100644
--- a/jsprit-core/src/main/java/algorithms/CreateInitialSolution.java
+++ b/jsprit-core/src/main/java/algorithms/InsertionInitialSolutionFactory.java
@@ -1,18 +1,14 @@
/*******************************************************************************
- * Copyright (C) 2013 Stefan Schroeder
+ * Copyright (c) 2011 Stefan Schroeder.
+ * eMail: stefan.schroeder@kit.edu
*
- * 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.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the GNU Public License v2.0
+ * which accompanies this distribution, and is available at
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
- * 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 .
+ * Contributors:
+ * Stefan Schroeder - initial API and implementation
******************************************************************************/
/* *********************************************************************** *
* project: org.matsim.*
@@ -45,48 +41,34 @@ 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 {
+public final class InsertionInitialSolutionFactory implements InitialSolutionFactory {
- private static final Logger logger = Logger.getLogger(CreateInitialSolution.class);
+ private static final Logger logger = Logger.getLogger(InsertionInitialSolutionFactory.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) {
+ private SolutionCostCalculator solutionCostsCalculator;
+
+ public InsertionInitialSolutionFactory(InsertionStrategy insertionStrategy, SolutionCostCalculator solutionCostCalculator) {
super();
this.insertion = insertionStrategy;
- this.solutionCostCalculator = solutionCostCalculator;
+ this.solutionCostsCalculator = solutionCostCalculator;
}
@Override
- public VehicleRoutingProblemSolution createInitialSolution(final VehicleRoutingProblem vrp) {
+ public VehicleRoutingProblemSolution createSolution(final VehicleRoutingProblem vrp) {
logger.info("create initial solution.");
List vehicleRoutes = new ArrayList();
- if(generateAsMuchAsRoutesAsVehiclesExist){
- for(Vehicle vehicle : vrp.getVehicles()){
- vehicleRoutes.add(VehicleRoute.newInstance(TourActivities.emptyTour(), DriverImpl.noDriver(), vehicle));
- }
- }
insertion.insertJobs(vehicleRoutes, getUnassignedJobs(vrp));
-// double totalCost = getTotalCost(vehicleRoutes);
+ VehicleRoutingProblemSolution solution = new VehicleRoutingProblemSolution(vehicleRoutes, Double.MAX_VALUE);
+ double costs = solutionCostsCalculator.getCosts(solution);
+ solution.setCost(costs);
logger.info("creation done");
- VehicleRoutingProblemSolution vehicleRoutingProblemSolution = new VehicleRoutingProblemSolution(vehicleRoutes, 0.0);
- solutionCostCalculator.calculateCosts(vehicleRoutingProblemSolution);
- return vehicleRoutingProblemSolution;
+ return solution;
}
private List getUnassignedJobs(VehicleRoutingProblem vrp) {
diff --git a/jsprit-core/src/main/java/algorithms/InsertionStrategy.java b/jsprit-core/src/main/java/algorithms/InsertionStrategy.java
index 239e1c61..17c84fad 100644
--- a/jsprit-core/src/main/java/algorithms/InsertionStrategy.java
+++ b/jsprit-core/src/main/java/algorithms/InsertionStrategy.java
@@ -31,33 +31,7 @@ import basics.route.VehicleRoute;
*
*/
-interface InsertionStrategy {
-
- class Insertion {
-
- private final VehicleRoute route;
-
- private final InsertionData insertionData;
-
- public Insertion(VehicleRoute vehicleRoute, InsertionData insertionData) {
- super();
- this.route = vehicleRoute;
- this.insertionData = insertionData;
- }
-
- public VehicleRoute getRoute() {
- return route;
- }
-
- public InsertionData getInsertionData() {
- return insertionData;
- }
-
- }
-
-
-
-
+public interface InsertionStrategy {
/**
* Assigns the unassigned jobs to service-providers
diff --git a/jsprit-core/src/main/java/algorithms/InsertionStrategyBuilder.java b/jsprit-core/src/main/java/algorithms/InsertionStrategyBuilder.java
new file mode 100644
index 00000000..04e34208
--- /dev/null
+++ b/jsprit-core/src/main/java/algorithms/InsertionStrategyBuilder.java
@@ -0,0 +1,7 @@
+package algorithms;
+
+public interface InsertionStrategyBuilder {
+
+ public InsertionStrategy build();
+
+}
diff --git a/jsprit-core/src/main/java/algorithms/IterateRouteBackwardInTime.java b/jsprit-core/src/main/java/algorithms/IterateRouteBackwardInTime.java
deleted file mode 100644
index 4204c943..00000000
--- a/jsprit-core/src/main/java/algorithms/IterateRouteBackwardInTime.java
+++ /dev/null
@@ -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 .
- ******************************************************************************/
-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 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); }
-
-}
diff --git a/jsprit-core/src/main/java/algorithms/IterateRouteForwardInTime.java b/jsprit-core/src/main/java/algorithms/IterateRouteForwardInTime.java
deleted file mode 100644
index dd507fb6..00000000
--- a/jsprit-core/src/main/java/algorithms/IterateRouteForwardInTime.java
+++ /dev/null
@@ -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 .
- ******************************************************************************/
-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);
- }
-
-}
diff --git a/jsprit-core/src/main/java/algorithms/JobCalculatorSwitcher.java b/jsprit-core/src/main/java/algorithms/JobCalculatorSwitcher.java
index 617da19d..da3485b8 100644
--- a/jsprit-core/src/main/java/algorithms/JobCalculatorSwitcher.java
+++ b/jsprit-core/src/main/java/algorithms/JobCalculatorSwitcher.java
@@ -8,18 +8,18 @@ import basics.route.Driver;
import basics.route.Vehicle;
import basics.route.VehicleRoute;
-public class JobCalculatorSwitcher implements JobInsertionCalculator{
+public class JobCalculatorSwitcher implements JobInsertionCostsCalculator{
- private Map,JobInsertionCalculator> calcMap = new HashMap, JobInsertionCalculator>();
+ private Map,JobInsertionCostsCalculator> calcMap = new HashMap, JobInsertionCostsCalculator>();
- void put(Class extends Job> jobClass, JobInsertionCalculator jic){
+ void put(Class extends Job> jobClass, JobInsertionCostsCalculator jic){
calcMap.put(jobClass, jic);
}
- public InsertionData calculate(VehicleRoute currentRoute, Job jobToInsert, Vehicle newVehicle, double newVehicleDepartureTime, Driver newDriver, double bestKnownScore){
- JobInsertionCalculator jic = calcMap.get(jobToInsert.getClass());
+ public InsertionData getInsertionData(VehicleRoute currentRoute, Job jobToInsert, Vehicle newVehicle, double newVehicleDepartureTime, Driver newDriver, double bestKnownScore){
+ JobInsertionCostsCalculator jic = calcMap.get(jobToInsert.getClass());
if(jic==null) throw new IllegalStateException("cannot find calculator for " + jobToInsert.getClass());
- return jic.calculate(currentRoute, jobToInsert, newVehicle, newVehicleDepartureTime, newDriver, bestKnownScore);
+ return jic.getInsertionData(currentRoute, jobToInsert, newVehicle, newVehicleDepartureTime, newDriver, bestKnownScore);
}
}
diff --git a/jsprit-core/src/main/java/algorithms/JobDistance.java b/jsprit-core/src/main/java/algorithms/JobDistance.java
index c8da4a72..3ac28dbe 100644
--- a/jsprit-core/src/main/java/algorithms/JobDistance.java
+++ b/jsprit-core/src/main/java/algorithms/JobDistance.java
@@ -20,8 +20,8 @@ import basics.Job;
-interface JobDistance {
+public interface JobDistance {
- public double calculateDistance(Job i, Job j);
+ public double getDistance(Job i, Job j);
}
diff --git a/jsprit-core/src/main/java/algorithms/JobDistanceAvgCosts.java b/jsprit-core/src/main/java/algorithms/JobDistanceAvgCosts.java
index f0ef7726..66194819 100644
--- a/jsprit-core/src/main/java/algorithms/JobDistanceAvgCosts.java
+++ b/jsprit-core/src/main/java/algorithms/JobDistanceAvgCosts.java
@@ -49,7 +49,7 @@ class JobDistanceAvgCosts implements JobDistance {
* If the distance between two jobs cannot be calculated with input-transport costs, it tries the euclidean distance between these jobs.
*/
@Override
- public double calculateDistance(Job i, Job j) {
+ public double getDistance(Job i, Job j) {
double avgCost = 0.0;
if (i instanceof Service && j instanceof Service) {
if (i.equals(j)) {
@@ -76,7 +76,7 @@ class JobDistanceAvgCosts implements JobDistance {
// now try the euclidean distance between these two services
}
EuclideanServiceDistance euclidean = new EuclideanServiceDistance();
- distance = euclidean.calculateDistance(s_i, s_j);
+ distance = euclidean.getDistance(s_i, s_j);
return distance;
}
diff --git a/jsprit-core/src/main/java/algorithms/JobDistanceBeeline.java b/jsprit-core/src/main/java/algorithms/JobDistanceBeeline.java
index 21c467b0..f4287639 100644
--- a/jsprit-core/src/main/java/algorithms/JobDistanceBeeline.java
+++ b/jsprit-core/src/main/java/algorithms/JobDistanceBeeline.java
@@ -33,7 +33,7 @@ class JobDistanceBeeline implements JobDistance {
}
@Override
- public double calculateDistance(Job i, Job j) {
+ public double getDistance(Job i, Job j) {
double avgCost = 0.0;
if (i instanceof Service && j instanceof Service) {
if (i.equals(j)) {
diff --git a/jsprit-core/src/main/java/algorithms/CalculatesServiceInsertionConsideringFixCost.java b/jsprit-core/src/main/java/algorithms/JobInsertionConsideringFixCostsCalculator.java
similarity index 75%
rename from jsprit-core/src/main/java/algorithms/CalculatesServiceInsertionConsideringFixCost.java
rename to jsprit-core/src/main/java/algorithms/JobInsertionConsideringFixCostsCalculator.java
index 68fe3a66..87c70abb 100644
--- a/jsprit-core/src/main/java/algorithms/CalculatesServiceInsertionConsideringFixCost.java
+++ b/jsprit-core/src/main/java/algorithms/JobInsertionConsideringFixCostsCalculator.java
@@ -27,35 +27,35 @@ import basics.route.VehicleRoute;
-final class CalculatesServiceInsertionConsideringFixCost implements JobInsertionCalculator{
+final class JobInsertionConsideringFixCostsCalculator implements JobInsertionCostsCalculator{
- private static final Logger logger = Logger.getLogger(CalculatesServiceInsertionConsideringFixCost.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 solution_completeness_ratio = 0.5;
- private StateManager states;
+ private StateGetter stateGetter;
- public CalculatesServiceInsertionConsideringFixCost(final JobInsertionCalculator standardInsertionCalculator, StateManager activityStates2) {
+ public JobInsertionConsideringFixCostsCalculator(final JobInsertionCostsCalculator standardInsertionCalculator, StateGetter stateGetter) {
super();
this.standardServiceInsertion = standardInsertionCalculator;
- this.states = activityStates2;
+ this.stateGetter = stateGetter;
logger.info("inialise " + this);
}
@Override
- public InsertionData calculate(final VehicleRoute currentRoute, final Job jobToInsert, final Vehicle newVehicle, double newVehicleDepartureTime, final Driver newDriver, final double bestKnownPrice) {
+ public InsertionData getInsertionData(final VehicleRoute currentRoute, final Job jobToInsert, final Vehicle newVehicle, double newVehicleDepartureTime, final Driver newDriver, final double bestKnownPrice) {
double relFixCost = getDeltaRelativeFixCost(currentRoute, newVehicle, jobToInsert);
double absFixCost = getDeltaAbsoluteFixCost(currentRoute, newVehicle, jobToInsert);
double deltaFixCost = (1-solution_completeness_ratio)*relFixCost + solution_completeness_ratio*absFixCost;
double fixcost_contribution = weight_deltaFixCost*solution_completeness_ratio*deltaFixCost;
if(fixcost_contribution > bestKnownPrice){
- return InsertionData.noInsertionFound();
+ return InsertionData.createEmptyInsertionData();
}
- InsertionData iData = standardServiceInsertion.calculate(currentRoute, jobToInsert, newVehicle, newVehicleDepartureTime, newDriver, bestKnownPrice);
+ InsertionData iData = standardServiceInsertion.getInsertionData(currentRoute, jobToInsert, newVehicle, newVehicleDepartureTime, newDriver, bestKnownPrice);
if(iData instanceof NoInsertionFound){
return iData;
}
@@ -80,7 +80,7 @@ final class CalculatesServiceInsertionConsideringFixCost implements JobInsertion
}
private double getDeltaAbsoluteFixCost(VehicleRoute route, Vehicle newVehicle, Job job) {
- double load = getCurrentLoad(route) + job.getCapacityDemand();
+ double load = getCurrentMaxLoadInRoute(route) + job.getCapacityDemand();
double currentFix = 0.0;
if(route.getVehicle() != null){
if(!(route.getVehicle() instanceof NoVehicle)){
@@ -94,7 +94,7 @@ final class CalculatesServiceInsertionConsideringFixCost implements JobInsertion
}
private double getDeltaRelativeFixCost(VehicleRoute route, Vehicle newVehicle, Job job) {
- int currentLoad = getCurrentLoad(route);
+ int currentLoad = getCurrentMaxLoadInRoute(route);
double load = currentLoad + job.getCapacityDemand();
double currentRelFix = 0.0;
if(route.getVehicle() != null){
@@ -109,8 +109,8 @@ final class CalculatesServiceInsertionConsideringFixCost implements JobInsertion
return relativeFixCost;
}
- private int getCurrentLoad(VehicleRoute route) {
- return (int) states.getRouteState(route, StateTypes.LOAD).toDouble();
+ private int getCurrentMaxLoadInRoute(VehicleRoute route) {
+ return (int) stateGetter.getRouteState(route, StateFactory.MAXLOAD).toDouble();
}
}
diff --git a/jsprit-core/src/main/java/algorithms/JobInsertionCalculator.java b/jsprit-core/src/main/java/algorithms/JobInsertionCostsCalculator.java
similarity index 82%
rename from jsprit-core/src/main/java/algorithms/JobInsertionCalculator.java
rename to jsprit-core/src/main/java/algorithms/JobInsertionCostsCalculator.java
index a8f3376f..28f908dd 100644
--- a/jsprit-core/src/main/java/algorithms/JobInsertionCalculator.java
+++ b/jsprit-core/src/main/java/algorithms/JobInsertionCostsCalculator.java
@@ -22,8 +22,8 @@ import basics.route.Vehicle;
import basics.route.VehicleRoute;
- interface JobInsertionCalculator {
+ public interface JobInsertionCostsCalculator {
- public InsertionData calculate(VehicleRoute currentRoute, Job jobToInsert, Vehicle newVehicle, double newVehicleDepartureTime, Driver newDriver, double bestKnownScore);
+ public InsertionData getInsertionData(VehicleRoute currentRoute, Job newJob, Vehicle newVehicle, double newVehicleDepartureTime, Driver newDriver, double bestKnownCosts);
}
diff --git a/jsprit-core/src/main/java/algorithms/LocalActivityInsertionCostsCalculator.java b/jsprit-core/src/main/java/algorithms/LocalActivityInsertionCostsCalculator.java
index 9dd9a20b..4aac5785 100644
--- a/jsprit-core/src/main/java/algorithms/LocalActivityInsertionCostsCalculator.java
+++ b/jsprit-core/src/main/java/algorithms/LocalActivityInsertionCostsCalculator.java
@@ -20,38 +20,42 @@
******************************************************************************/
package algorithms;
-import algorithms.HardConstraints.HardActivityLevelConstraint;
import basics.costs.VehicleRoutingActivityCosts;
import basics.costs.VehicleRoutingTransportCosts;
import basics.route.TourActivity;
+/**
+ * Calculates activity insertion costs locally, i.e. by comparing the additional costs of insertion the new activity k between
+ * activity i (prevAct) and j (nextAct).
+ * Additional costs are then basically calculated as delta c = c_ik + c_kj - c_ij.
+ *
+ *
Note once time has an effect on costs this class requires activity endTimes.
+ *
+ * @author stefan
+ *
+ */
class LocalActivityInsertionCostsCalculator implements ActivityInsertionCostsCalculator{
- private HardActivityLevelConstraint hardConstraint;
-
private VehicleRoutingTransportCosts routingCosts;
private VehicleRoutingActivityCosts activityCosts;
- public LocalActivityInsertionCostsCalculator(VehicleRoutingTransportCosts routingCosts, VehicleRoutingActivityCosts actCosts, HardActivityLevelConstraint hardActivityLevelConstraint) {
+
+ public LocalActivityInsertionCostsCalculator(VehicleRoutingTransportCosts routingCosts, VehicleRoutingActivityCosts actCosts) {
super();
this.routingCosts = routingCosts;
this.activityCosts = actCosts;
- this.hardConstraint = hardActivityLevelConstraint;
}
@Override
- public ActivityInsertionCosts calculate(InsertionContext iFacts, TourActivity prevAct, TourActivity nextAct, TourActivity newAct, double depTimeAtPrevAct) {
- if(!hardConstraint.fulfilled(iFacts, prevAct, newAct, nextAct, depTimeAtPrevAct)){
- return null;
- }
+ public ActivityInsertionCosts getCosts(InsertionContext iFacts, TourActivity prevAct, TourActivity nextAct, TourActivity newAct, double depTimeAtPrevAct) {
double tp_costs_prevAct_newAct = routingCosts.getTransportCost(prevAct.getLocationId(), newAct.getLocationId(), depTimeAtPrevAct, iFacts.getNewDriver(), iFacts.getNewVehicle());
double tp_time_prevAct_newAct = routingCosts.getTransportTime(prevAct.getLocationId(), newAct.getLocationId(), depTimeAtPrevAct, iFacts.getNewDriver(), iFacts.getNewVehicle());
double newAct_arrTime = depTimeAtPrevAct + tp_time_prevAct_newAct;
- double newAct_endTime = CalcUtils.getActivityEndTime(newAct_arrTime, newAct);
+ double newAct_endTime = CalculationUtils.getActivityEndTime(newAct_arrTime, newAct);
double act_costs_newAct = activityCosts.getActivityCost(newAct, newAct_arrTime, iFacts.getNewDriver(), iFacts.getNewVehicle());
diff --git a/jsprit-core/src/main/java/algorithms/NeighborhoodThresholdInitialiser.java b/jsprit-core/src/main/java/algorithms/NeighborhoodThresholdInitialiser.java
index 60a293d4..a9abcdfe 100644
--- a/jsprit-core/src/main/java/algorithms/NeighborhoodThresholdInitialiser.java
+++ b/jsprit-core/src/main/java/algorithms/NeighborhoodThresholdInitialiser.java
@@ -35,7 +35,7 @@ import basics.algo.VehicleRoutingAlgorithmFactory;
import basics.route.TourActivity;
import basics.route.VehicleRoute;
-public class NeighborhoodThresholdInitialiser implements AlgorithmStartsListener{
+class NeighborhoodThresholdInitialiser implements AlgorithmStartsListener{
private static Logger log = Logger.getLogger(NeighborhoodThresholdInitialiser.class);
diff --git a/jsprit-core/src/main/java/algorithms/RadialRuinStrategyFactory.java b/jsprit-core/src/main/java/algorithms/RadialRuinStrategyFactory.java
new file mode 100644
index 00000000..c541c4c9
--- /dev/null
+++ b/jsprit-core/src/main/java/algorithms/RadialRuinStrategyFactory.java
@@ -0,0 +1,22 @@
+package algorithms;
+
+import basics.VehicleRoutingProblem;
+
+public class RadialRuinStrategyFactory implements RuinStrategyFactory{
+
+ private double fraction;
+
+ private JobDistance jobDistance;
+
+ public RadialRuinStrategyFactory(double fraction, JobDistance jobDistance) {
+ super();
+ this.fraction = fraction;
+ this.jobDistance = jobDistance;
+ }
+
+ @Override
+ public RuinStrategy createStrategy(VehicleRoutingProblem vrp) {
+ return new RuinRadial(vrp,fraction,jobDistance);
+ }
+
+}
diff --git a/jsprit-core/src/main/java/algorithms/RandomRuinStrategyFactory.java b/jsprit-core/src/main/java/algorithms/RandomRuinStrategyFactory.java
new file mode 100644
index 00000000..5a32c9f2
--- /dev/null
+++ b/jsprit-core/src/main/java/algorithms/RandomRuinStrategyFactory.java
@@ -0,0 +1,19 @@
+package algorithms;
+
+import basics.VehicleRoutingProblem;
+
+public class RandomRuinStrategyFactory implements RuinStrategyFactory{
+
+ private double fraction;
+
+ public RandomRuinStrategyFactory(double fraction) {
+ super();
+ this.fraction = fraction;
+ }
+
+ @Override
+ public RuinStrategy createStrategy(VehicleRoutingProblem vrp) {
+ return new RuinRandom(vrp, fraction);
+ }
+
+}
diff --git a/jsprit-core/src/main/java/algorithms/RemoveEmptyVehicles.java b/jsprit-core/src/main/java/algorithms/RemoveEmptyVehicles.java
index 6e069b90..28919048 100644
--- a/jsprit-core/src/main/java/algorithms/RemoveEmptyVehicles.java
+++ b/jsprit-core/src/main/java/algorithms/RemoveEmptyVehicles.java
@@ -23,6 +23,7 @@ import java.util.List;
import org.apache.log4j.Logger;
import basics.algo.InsertionEndsListener;
+import basics.route.VehicleFleetManager;
import basics.route.VehicleRoute;
class RemoveEmptyVehicles implements InsertionEndsListener{
@@ -31,7 +32,7 @@ class RemoveEmptyVehicles implements InsertionEndsListener{
private VehicleFleetManager fleetManager;
- RemoveEmptyVehicles(VehicleFleetManager fleetManager) {
+ public RemoveEmptyVehicles(VehicleFleetManager fleetManager) {
super();
this.fleetManager = fleetManager;
}
diff --git a/jsprit-core/src/main/java/algorithms/ResetAndIniFleetManager.java b/jsprit-core/src/main/java/algorithms/ResetAndIniFleetManager.java
index d03f255d..81c68738 100644
--- a/jsprit-core/src/main/java/algorithms/ResetAndIniFleetManager.java
+++ b/jsprit-core/src/main/java/algorithms/ResetAndIniFleetManager.java
@@ -23,6 +23,7 @@ import org.apache.log4j.Logger;
import basics.Job;
import basics.algo.InsertionStartsListener;
+import basics.route.VehicleFleetManager;
import basics.route.VehicleRoute;
class ResetAndIniFleetManager implements InsertionStartsListener{
diff --git a/jsprit-core/src/main/java/algorithms/RouteLevelActivityInsertionCostsEstimator.java b/jsprit-core/src/main/java/algorithms/RouteLevelActivityInsertionCostsEstimator.java
index 2daa5e63..adc9776f 100644
--- a/jsprit-core/src/main/java/algorithms/RouteLevelActivityInsertionCostsEstimator.java
+++ b/jsprit-core/src/main/java/algorithms/RouteLevelActivityInsertionCostsEstimator.java
@@ -23,7 +23,6 @@ package algorithms;
import java.util.ArrayList;
import java.util.List;
-import algorithms.HardConstraints.HardActivityLevelConstraint;
import basics.costs.VehicleRoutingActivityCosts;
import basics.costs.VehicleRoutingTransportCosts;
import basics.route.End;
@@ -33,30 +32,23 @@ import basics.route.VehicleRoute;
class RouteLevelActivityInsertionCostsEstimator implements ActivityInsertionCostsCalculator{
- private HardActivityLevelConstraint hardConstraint;
-
private VehicleRoutingActivityCosts activityCosts;
private AuxilliaryCostCalculator auxilliaryPathCostCalculator;
- private StateManager stateManager;
+ private StateGetter stateManager;
private int nuOfActivities2LookForward = 0;
- public RouteLevelActivityInsertionCostsEstimator(VehicleRoutingTransportCosts routingCosts, VehicleRoutingActivityCosts actCosts, HardActivityLevelConstraint hardActivityLevelConstraint, StateManager stateManager) {
+ public RouteLevelActivityInsertionCostsEstimator(VehicleRoutingTransportCosts routingCosts, VehicleRoutingActivityCosts actCosts, StateGetter stateManager) {
super();
this.activityCosts = actCosts;
- this.hardConstraint = hardActivityLevelConstraint;
this.stateManager = stateManager;
auxilliaryPathCostCalculator = new AuxilliaryCostCalculator(routingCosts, activityCosts);
}
@Override
- public ActivityInsertionCosts calculate(InsertionContext iFacts, TourActivity prevAct, TourActivity nextAct, TourActivity newAct, double depTimeAtPrevAct) {
- if(!hardConstraint.fulfilled(iFacts, prevAct, newAct, nextAct, depTimeAtPrevAct)){
- return null;
- }
-
+ public ActivityInsertionCosts getCosts(InsertionContext iFacts, TourActivity prevAct, TourActivity nextAct, TourActivity newAct, double depTimeAtPrevAct) {
List path = new ArrayList();
path.add(prevAct); path.add(newAct); path.add(nextAct);
int actIndex;
@@ -77,9 +69,9 @@ class RouteLevelActivityInsertionCostsEstimator implements ActivityInsertionCost
private double actCostsOld(VehicleRoute vehicleRoute, TourActivity act) {
if(act instanceof End){
- return stateManager.getRouteState(vehicleRoute,StateTypes.COSTS).toDouble();
+ return stateManager.getRouteState(vehicleRoute,StateFactory.COSTS).toDouble();
}
- return stateManager.getActivityState(act,StateTypes.COSTS).toDouble();
+ return stateManager.getActivityState(act,StateFactory.COSTS).toDouble();
}
private List getForwardLookingPath(VehicleRoute route, int actIndex) {
diff --git a/jsprit-core/src/main/java/algorithms/RuinAndRecreateModule.java b/jsprit-core/src/main/java/algorithms/RuinAndRecreateModule.java
index 73c6f3a5..53703592 100644
--- a/jsprit-core/src/main/java/algorithms/RuinAndRecreateModule.java
+++ b/jsprit-core/src/main/java/algorithms/RuinAndRecreateModule.java
@@ -18,14 +18,14 @@ package algorithms;
import java.util.Collection;
-import algorithms.RuinStrategy.RuinListener;
import basics.Job;
import basics.VehicleRoutingProblemSolution;
import basics.algo.InsertionListener;
+import basics.algo.RuinListener;
import basics.algo.SearchStrategyModule;
import basics.algo.SearchStrategyModuleListener;
-class RuinAndRecreateModule implements SearchStrategyModule{
+public class RuinAndRecreateModule implements SearchStrategyModule{
private InsertionStrategy insertion;
@@ -44,9 +44,8 @@ class RuinAndRecreateModule implements SearchStrategyModule{
public VehicleRoutingProblemSolution runAndGetSolution(VehicleRoutingProblemSolution vrpSolution) {
Collection ruinedJobs = ruin.ruin(vrpSolution.getRoutes());
insertion.insertJobs(vrpSolution.getRoutes(), ruinedJobs);
-// double totalCost = RouteUtils.getTotalCost(vrpSolution.getRoutes());
-// vrpSolution.setCost(totalCost);
return vrpSolution;
+
}
@Override
diff --git a/jsprit-core/src/main/java/algorithms/RuinListeners.java b/jsprit-core/src/main/java/algorithms/RuinListeners.java
deleted file mode 100644
index 1b0e18b4..00000000
--- a/jsprit-core/src/main/java/algorithms/RuinListeners.java
+++ /dev/null
@@ -1,54 +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 .
- ******************************************************************************/
-package algorithms;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-
-import algorithms.RuinStrategy.RuinListener;
-import basics.Job;
-import basics.route.VehicleRoute;
-
-class RuinListeners {
-
- private Collection ruinListeners = new ArrayList();
-
- void ruinStarts(Collection routes){
- for(RuinListener l : ruinListeners) l.ruinStarts(routes);
- }
-
- void ruinEnds(Collection routes, Collection unassignedJobs){
- for(RuinListener l : ruinListeners) l.ruinEnds(routes, unassignedJobs);
- }
-
- void removed(Job job, VehicleRoute fromRoute){
- for(RuinListener l : ruinListeners) l.removed(job, fromRoute);
- }
-
- void addListener(RuinListener ruinListener){
- ruinListeners.add(ruinListener);
- }
-
- void removeListener(RuinListener ruinListener){
- ruinListeners.remove(ruinListener);
- }
-
- Collection getListeners(){
- return Collections.unmodifiableCollection(ruinListeners);
- }
-}
diff --git a/jsprit-core/src/main/java/algorithms/RuinRadial.java b/jsprit-core/src/main/java/algorithms/RuinRadial.java
index 330f6a1a..c0c0fffe 100644
--- a/jsprit-core/src/main/java/algorithms/RuinRadial.java
+++ b/jsprit-core/src/main/java/algorithms/RuinRadial.java
@@ -33,6 +33,8 @@ import util.RandomNumberGeneration;
import util.StopWatch;
import basics.Job;
import basics.VehicleRoutingProblem;
+import basics.algo.RuinListener;
+import basics.algo.RuinListeners;
import basics.route.VehicleRoute;
@@ -120,7 +122,7 @@ final class RuinRadial implements RuinStrategy {
});
distanceNodeTree.put(i.getId(), treeSet);
for (Job j : vrp.getJobs().values()) {
- double distance = jobDistance.calculateDistance(i, j);
+ double distance = jobDistance.getDistance(i, j);
ReferencedJob refNode = new ReferencedJob(j, distance);
treeSet.add(refNode);
nuOfDistancesStored++;
diff --git a/jsprit-core/src/main/java/algorithms/RuinRandom.java b/jsprit-core/src/main/java/algorithms/RuinRandom.java
index da3ab873..bbe1b2c6 100644
--- a/jsprit-core/src/main/java/algorithms/RuinRandom.java
+++ b/jsprit-core/src/main/java/algorithms/RuinRandom.java
@@ -27,6 +27,8 @@ import org.apache.log4j.Logger;
import util.RandomNumberGeneration;
import basics.Job;
import basics.VehicleRoutingProblem;
+import basics.algo.RuinListener;
+import basics.algo.RuinListeners;
import basics.route.VehicleRoute;
diff --git a/jsprit-core/src/main/java/algorithms/RuinStrategy.java b/jsprit-core/src/main/java/algorithms/RuinStrategy.java
index b06e932d..3f03b5dc 100644
--- a/jsprit-core/src/main/java/algorithms/RuinStrategy.java
+++ b/jsprit-core/src/main/java/algorithms/RuinStrategy.java
@@ -19,6 +19,7 @@ package algorithms;
import java.util.Collection;
import basics.Job;
+import basics.algo.RuinListener;
import basics.route.VehicleRoute;
@@ -30,41 +31,8 @@ import basics.route.VehicleRoute;
*
*/
-interface RuinStrategy {
+public interface RuinStrategy {
- /**
- * Listener that listens to the ruin-process. It informs whoever is interested about start, end and about a removal of a job.
- *
- * @author schroeder
- *
- */
- public static interface RuinListener {
-
- /**
- * informs about ruin-start.
- *
- * @param routes
- */
- public void ruinStarts(Collection routes);
-
- /**
- * informs about ruin-end.
- *
- * @param routes
- * @param unassignedJobs
- */
- public void ruinEnds(Collection routes, Collection unassignedJobs);
-
- /**
- * informs if a {@link Job} has been removed from a {@link VehicleRoute}.
- *
- * @param job
- * @param fromRoute
- */
- public void removed(Job job, VehicleRoute fromRoute);
-
- }
-
/**
* Ruins a current solution, i.e. a collection of vehicle-routes and
* returns a collection of removed and thus unassigned jobs.
diff --git a/jsprit-core/src/main/java/algorithms/RuinStrategyFactory.java b/jsprit-core/src/main/java/algorithms/RuinStrategyFactory.java
index 202abb54..26cf1212 100644
--- a/jsprit-core/src/main/java/algorithms/RuinStrategyFactory.java
+++ b/jsprit-core/src/main/java/algorithms/RuinStrategyFactory.java
@@ -18,7 +18,7 @@ package algorithms;
import basics.VehicleRoutingProblem;
-interface RuinStrategyFactory {
+public interface RuinStrategyFactory {
public RuinStrategy createStrategy(VehicleRoutingProblem vrp);
diff --git a/jsprit-core/src/main/java/algorithms/ServiceInsertionCalculator.java b/jsprit-core/src/main/java/algorithms/ServiceInsertionCalculator.java
index 582f395a..daa6f637 100644
--- a/jsprit-core/src/main/java/algorithms/ServiceInsertionCalculator.java
+++ b/jsprit-core/src/main/java/algorithms/ServiceInsertionCalculator.java
@@ -20,7 +20,8 @@ import org.apache.log4j.Logger;
import util.Neighborhood;
import algorithms.ActivityInsertionCostsCalculator.ActivityInsertionCosts;
-import algorithms.HardConstraints.HardRouteLevelConstraint;
+
+import algorithms.HardActivityLevelConstraint.ConstraintsStatus;
import basics.Job;
import basics.Service;
import basics.costs.VehicleRoutingTransportCosts;
@@ -36,12 +37,14 @@ import basics.route.VehicleRoute;
-final class ServiceInsertionCalculator implements JobInsertionCalculator{
+final class ServiceInsertionCalculator implements JobInsertionCostsCalculator{
private static final Logger logger = Logger.getLogger(ServiceInsertionCalculator.class);
private HardRouteLevelConstraint hardRouteLevelConstraint;
+ private HardActivityLevelConstraint hardActivityLevelConstraint;
+
private Neighborhood neighborhood = new Neighborhood() {
@Override
@@ -61,10 +64,12 @@ final class ServiceInsertionCalculator implements JobInsertionCalculator{
logger.info("initialise neighborhood " + neighborhood);
}
- public ServiceInsertionCalculator(VehicleRoutingTransportCosts routingCosts, ActivityInsertionCostsCalculator activityInsertionCostsCalculator, HardRouteLevelConstraint hardRouteLevelConstraint) {
+
+ public ServiceInsertionCalculator(VehicleRoutingTransportCosts routingCosts, ActivityInsertionCostsCalculator activityInsertionCostsCalculator, HardRouteLevelConstraint hardRouteLevelConstraint, HardActivityLevelConstraint hardActivityLevelConstraint) {
super();
this.activityInsertionCostsCalculator = activityInsertionCostsCalculator;
this.hardRouteLevelConstraint = hardRouteLevelConstraint;
+ this.hardActivityLevelConstraint = hardActivityLevelConstraint;
this.transportCosts = routingCosts;
activityFactory = new DefaultTourActivityFactory();
logger.info("initialise " + this);
@@ -81,13 +86,13 @@ final class ServiceInsertionCalculator implements JobInsertionCalculator{
*
*/
@Override
- public InsertionData calculate(final VehicleRoute currentRoute, final Job jobToInsert, final Vehicle newVehicle, double newVehicleDepartureTime, final Driver newDriver, final double bestKnownCosts) {
+ public InsertionData getInsertionData(final VehicleRoute currentRoute, final Job jobToInsert, final Vehicle newVehicle, double newVehicleDepartureTime, final Driver newDriver, final double bestKnownCosts) {
if(jobToInsert == null) throw new IllegalStateException("jobToInsert is missing.");
if(newVehicle == null || newVehicle instanceof NoVehicle) throw new IllegalStateException("newVehicle is missing.");
InsertionContext insertionContext = new InsertionContext(currentRoute, jobToInsert, newVehicle, newDriver, newVehicleDepartureTime);
if(!hardRouteLevelConstraint.fulfilled(insertionContext)){
- return InsertionData.noInsertionFound();
+ return InsertionData.createEmptyInsertionData();
}
double bestCost = bestKnownCosts;
@@ -99,17 +104,40 @@ final class ServiceInsertionCalculator implements JobInsertionCalculator{
Start start = Start.newInstance(newVehicle.getLocationId(), newVehicle.getEarliestDeparture(), newVehicle.getLatestArrival());
start.setEndTime(newVehicleDepartureTime);
-
End end = End.newInstance(newVehicle.getLocationId(), 0.0, newVehicle.getLatestArrival());
TourActivity prevAct = start;
double prevActStartTime = newVehicleDepartureTime;
int actIndex = 0;
-
+ boolean loopBroken = false;
for(TourActivity nextAct : currentRoute.getTourActivities().getActivities()){
if(neighborhood.areNeighbors(deliveryAct2Insert.getLocationId(), prevAct.getLocationId()) && neighborhood.areNeighbors(deliveryAct2Insert.getLocationId(), nextAct.getLocationId())){
- ActivityInsertionCosts mc = calculate(insertionContext, prevAct, nextAct, deliveryAct2Insert, prevActStartTime);
- if(mc != null){
+ ConstraintsStatus status = hardActivityLevelConstraint.fulfilled(insertionContext, prevAct, deliveryAct2Insert, nextAct, prevActStartTime);
+ if(status.equals(ConstraintsStatus.FULFILLED)){
+ ActivityInsertionCosts mc = calculate(insertionContext, prevAct, nextAct, deliveryAct2Insert, prevActStartTime);
+ if(mc.getAdditionalCosts() < bestCost){
+ bestCost = mc.getAdditionalCosts();
+ bestMarginals = mc;
+ insertionIndex = actIndex;
+ }
+ }
+ else if(status.equals(ConstraintsStatus.NOT_FULFILLED_BREAK)){
+ loopBroken = true;
+ break;
+ }
+ }
+ double nextActArrTime = prevActStartTime + transportCosts.getTransportTime(prevAct.getLocationId(), nextAct.getLocationId(), prevActStartTime, newDriver, newVehicle);
+ double nextActEndTime = CalculationUtils.getActivityEndTime(nextActArrTime, nextAct);
+ prevActStartTime = nextActEndTime;
+ prevAct = nextAct;
+ actIndex++;
+ }
+ End nextAct = end;
+ if(!loopBroken){
+ if(neighborhood.areNeighbors(deliveryAct2Insert.getLocationId(), prevAct.getLocationId()) && neighborhood.areNeighbors(deliveryAct2Insert.getLocationId(), nextAct.getLocationId())){
+ ConstraintsStatus status = hardActivityLevelConstraint.fulfilled(insertionContext, prevAct, deliveryAct2Insert, nextAct, prevActStartTime);
+ if(status.equals(ConstraintsStatus.FULFILLED)){
+ ActivityInsertionCosts mc = calculate(insertionContext, prevAct, nextAct, deliveryAct2Insert, prevActStartTime);
if(mc.getAdditionalCosts() < bestCost){
bestCost = mc.getAdditionalCosts();
bestMarginals = mc;
@@ -117,28 +145,10 @@ final class ServiceInsertionCalculator implements JobInsertionCalculator{
}
}
}
- double nextActArrTime = prevActStartTime + transportCosts.getTransportTime(prevAct.getLocationId(), nextAct.getLocationId(), prevActStartTime, newDriver, newVehicle);
- double nextActEndTime = CalcUtils.getActivityEndTime(nextActArrTime, nextAct);
-
- prevActStartTime = nextActEndTime;
-
- prevAct = nextAct;
- actIndex++;
}
- End nextAct = end;
- if(neighborhood.areNeighbors(deliveryAct2Insert.getLocationId(), prevAct.getLocationId()) && neighborhood.areNeighbors(deliveryAct2Insert.getLocationId(), nextAct.getLocationId())){
- ActivityInsertionCosts mc = calculate(insertionContext, prevAct, nextAct, deliveryAct2Insert, prevActStartTime);
- if(mc != null) {
- if(mc.getAdditionalCosts() < bestCost){
- bestCost = mc.getAdditionalCosts();
- bestMarginals = mc;
- insertionIndex = actIndex;
- }
- }
- }
if(insertionIndex == InsertionData.NO_INDEX) {
- return InsertionData.noInsertionFound();
+ return InsertionData.createEmptyInsertionData();
}
InsertionData insertionData = new InsertionData(bestCost, InsertionData.NO_INDEX, insertionIndex, newVehicle, newDriver);
insertionData.setVehicleDepartureTime(newVehicleDepartureTime);
@@ -147,7 +157,6 @@ final class ServiceInsertionCalculator implements JobInsertionCalculator{
}
public ActivityInsertionCosts calculate(InsertionContext iFacts, TourActivity prevAct, TourActivity nextAct, TourActivity newAct, double departureTimeAtPrevAct) {
- return activityInsertionCostsCalculator.calculate(iFacts, prevAct, nextAct, newAct, departureTimeAtPrevAct);
-
+ return activityInsertionCostsCalculator.getCosts(iFacts, prevAct, nextAct, newAct, departureTimeAtPrevAct);
}
}
diff --git a/jsprit-core/src/main/java/algorithms/CalculatesServiceInsertionOnRouteLevel.java b/jsprit-core/src/main/java/algorithms/ServiceInsertionOnRouteLevelCalculator.java
similarity index 77%
rename from jsprit-core/src/main/java/algorithms/CalculatesServiceInsertionOnRouteLevel.java
rename to jsprit-core/src/main/java/algorithms/ServiceInsertionOnRouteLevelCalculator.java
index 88a848a1..843f5d40 100644
--- a/jsprit-core/src/main/java/algorithms/CalculatesServiceInsertionOnRouteLevel.java
+++ b/jsprit-core/src/main/java/algorithms/ServiceInsertionOnRouteLevelCalculator.java
@@ -27,7 +27,7 @@ import org.apache.log4j.Logger;
import util.Neighborhood;
import algorithms.ActivityInsertionCostsCalculator.ActivityInsertionCosts;
-import algorithms.HardConstraints.HardRouteLevelConstraint;
+import algorithms.HardActivityLevelConstraint.ConstraintsStatus;
import basics.Job;
import basics.Service;
import basics.costs.VehicleRoutingActivityCosts;
@@ -45,9 +45,9 @@ import basics.route.VehicleRoute;
-final class CalculatesServiceInsertionOnRouteLevel implements JobInsertionCalculator{
+final class ServiceInsertionOnRouteLevelCalculator implements JobInsertionCostsCalculator{
- private static final Logger logger = Logger.getLogger(CalculatesServiceInsertionOnRouteLevel.class);
+ private static final Logger logger = Logger.getLogger(ServiceInsertionOnRouteLevelCalculator.class);
private final VehicleRoutingTransportCosts transportCosts;
@@ -57,10 +57,12 @@ final class CalculatesServiceInsertionOnRouteLevel implements JobInsertionCalcul
private TourActivityFactory tourActivityFactory = new DefaultTourActivityFactory();
- private StateManager stateManager;
+ private StateGetter stateManager;
private HardRouteLevelConstraint hardRouteLevelConstraint;
+ private HardActivityLevelConstraint hardActivityLevelConstraint;
+
private ActivityInsertionCostsCalculator activityInsertionCostsCalculator;
private int nuOfActsForwardLooking = 0;
@@ -94,18 +96,19 @@ final class CalculatesServiceInsertionOnRouteLevel implements JobInsertionCalcul
logger.info("set [solutionMemory="+memorySize+"]");
}
- public CalculatesServiceInsertionOnRouteLevel(VehicleRoutingTransportCosts vehicleRoutingCosts, VehicleRoutingActivityCosts costFunc, HardRouteLevelConstraint hardRouteLevelConstraint, ActivityInsertionCostsCalculator activityInsertionCostsCalculator) {
+ public ServiceInsertionOnRouteLevelCalculator(VehicleRoutingTransportCosts vehicleRoutingCosts, VehicleRoutingActivityCosts costFunc, ActivityInsertionCostsCalculator activityInsertionCostsCalculator, HardRouteLevelConstraint hardRouteLevelConstraint, HardActivityLevelConstraint hardActivityLevelConstraint) {
super();
this.transportCosts = vehicleRoutingCosts;
this.activityCosts = costFunc;
- this.hardRouteLevelConstraint = hardRouteLevelConstraint;
this.activityInsertionCostsCalculator = activityInsertionCostsCalculator;
+ this.hardRouteLevelConstraint = hardRouteLevelConstraint;
+ this.hardActivityLevelConstraint = hardActivityLevelConstraint;
auxilliaryPathCostCalculator = new AuxilliaryCostCalculator(transportCosts, activityCosts);
logger.info("initialise " + this);
}
- public void setStates(StateManager stateManager){
+ public void setStates(StateGetter stateManager){
this.stateManager = stateManager;
}
@@ -128,13 +131,13 @@ final class CalculatesServiceInsertionOnRouteLevel implements JobInsertionCalcul
*
*/
@Override
- public InsertionData calculate(final VehicleRoute currentRoute, final Job jobToInsert, final Vehicle newVehicle, double newVehicleDepartureTime, final Driver newDriver, final double best_known_insertion_costs) {
+ public InsertionData getInsertionData(final VehicleRoute currentRoute, final Job jobToInsert, final Vehicle newVehicle, double newVehicleDepartureTime, final Driver newDriver, final double best_known_insertion_costs) {
if(jobToInsert == null) throw new IllegalStateException("job is null. cannot calculate the insertion of a null-job.");
if(newVehicle == null || newVehicle instanceof NoVehicle) throw new IllegalStateException("no vehicle given. set para vehicle!");
InsertionContext insertionContext = new InsertionContext(currentRoute, jobToInsert, newVehicle, newDriver, newVehicleDepartureTime);
if(!hardRouteLevelConstraint.fulfilled(insertionContext)){
- return InsertionData.noInsertionFound();
+ return InsertionData.createEmptyInsertionData();
}
/**
@@ -150,6 +153,7 @@ final class CalculatesServiceInsertionOnRouteLevel implements JobInsertionCalcul
TourActivities tour = currentRoute.getTourActivities();
double best_insertion_costs = best_known_insertion_costs;
Service service = (Service)jobToInsert;
+
/**
* some inis
@@ -164,6 +168,7 @@ final class CalculatesServiceInsertionOnRouteLevel implements JobInsertionCalcul
double sumOf_prevCosts_newVehicle = 0.0;
double prevActDepTime_newVehicle = start.getEndTime();
+ boolean loopBroken = false;
/**
* inserting serviceAct2Insert in route r={0,1,...,i-1,i,j,j+1,...,n(r),n(r)+1}
* i=prevAct
@@ -172,12 +177,13 @@ final class CalculatesServiceInsertionOnRouteLevel implements JobInsertionCalcul
*/
for(TourActivity nextAct : tour.getActivities()){
if(neighborhood.areNeighbors(serviceAct2Insert.getLocationId(), prevAct.getLocationId()) && neighborhood.areNeighbors(serviceAct2Insert.getLocationId(), nextAct.getLocationId())){
- /**
- * builds a path on this route forwardPath={i,k,j,j+1,j+2,...,j+nuOfActsForwardLooking}
- */
- InsertionContext iContext = new InsertionContext(currentRoute, jobToInsert, newVehicle, newDriver, prevActDepTime_newVehicle);
- ActivityInsertionCosts actInsertionCosts = activityInsertionCostsCalculator.calculate(iContext, prevAct, nextAct, serviceAct2Insert, prevActDepTime_newVehicle);
- if(actInsertionCosts != null){
+ ConstraintsStatus status = hardActivityLevelConstraint.fulfilled(insertionContext, prevAct, serviceAct2Insert, nextAct, prevActDepTime_newVehicle);
+ if(status.equals(ConstraintsStatus.FULFILLED)){
+ /**
+ * builds a path on this route forwardPath={i,k,j,j+1,j+2,...,j+nuOfActsForwardLooking}
+ */
+ 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)
*/
@@ -190,6 +196,10 @@ final class CalculatesServiceInsertionOnRouteLevel implements JobInsertionCalcul
bestInsertionsQueue.add(new InsertionData(insertion_cost_approximation, InsertionData.NO_INDEX, actIndex, newVehicle, newDriver));
}
}
+ else if(status.equals(ConstraintsStatus.NOT_FULFILLED_BREAK)){
+ loopBroken = true;
+ break;
+ }
}
/**
@@ -219,22 +229,25 @@ final class CalculatesServiceInsertionOnRouteLevel implements JobInsertionCalcul
actIndex++;
}
- End nextAct = end;
- if(neighborhood.areNeighbors(serviceAct2Insert.getLocationId(), prevAct.getLocationId()) && neighborhood.areNeighbors(serviceAct2Insert.getLocationId(), nextAct.getLocationId())){
+ if(!loopBroken){
+ End nextAct = end;
+ if(neighborhood.areNeighbors(serviceAct2Insert.getLocationId(), prevAct.getLocationId()) && neighborhood.areNeighbors(serviceAct2Insert.getLocationId(), nextAct.getLocationId())){
+ ConstraintsStatus status = hardActivityLevelConstraint.fulfilled(insertionContext, prevAct, serviceAct2Insert, nextAct, prevActDepTime_newVehicle);
+ if(status.equals(ConstraintsStatus.FULFILLED)){
+ ActivityInsertionCosts actInsertionCosts = activityInsertionCostsCalculator.getCosts(insertionContext, prevAct, nextAct, serviceAct2Insert, prevActDepTime_newVehicle);
+ if(actInsertionCosts != null){
+ /**
+ * insertion_cost_approximation = c({0,1,...,i},newVehicle) + c({i,k,j,j+1,j+2,...,j+nuOfActsForwardLooking},newVehicle) - c({0,1,...,i,j,j+1,...,j+nuOfActsForwardLooking},oldVehicle)
+ */
+ double insertion_cost_approximation = sumOf_prevCosts_newVehicle - sumOf_prevCosts_oldVehicle(currentRoute,prevAct) + actInsertionCosts.getAdditionalCosts();
- InsertionContext iContext = new InsertionContext(currentRoute, jobToInsert, newVehicle, newDriver, prevActDepTime_newVehicle);
- ActivityInsertionCosts actInsertionCosts = activityInsertionCostsCalculator.calculate(iContext, prevAct, nextAct, serviceAct2Insert, prevActDepTime_newVehicle);
- if(actInsertionCosts != null){
- /**
- * insertion_cost_approximation = c({0,1,...,i},newVehicle) + c({i,k,j,j+1,j+2,...,j+nuOfActsForwardLooking},newVehicle) - c({0,1,...,i,j,j+1,...,j+nuOfActsForwardLooking},oldVehicle)
- */
- double insertion_cost_approximation = sumOf_prevCosts_newVehicle - sumOf_prevCosts_oldVehicle(currentRoute,prevAct) + actInsertionCosts.getAdditionalCosts();
-
- /**
- * memorize it in insertion-queue
- */
- if(insertion_cost_approximation < best_known_insertion_costs){
- bestInsertionsQueue.add(new InsertionData(insertion_cost_approximation, InsertionData.NO_INDEX, actIndex, newVehicle, newDriver));
+ /**
+ * memorize it in insertion-queue
+ */
+ if(insertion_cost_approximation < best_known_insertion_costs){
+ bestInsertionsQueue.add(new InsertionData(insertion_cost_approximation, InsertionData.NO_INDEX, actIndex, newVehicle, newDriver));
+ }
+ }
}
}
}
@@ -254,6 +267,7 @@ final class CalculatesServiceInsertionOnRouteLevel implements JobInsertionCalcul
}
}
else{
+
for(int i=0;i insertion_costs
*/
- double insertion_costs = auxilliaryPathCostCalculator.costOfPath(wholeTour, start.getEndTime(), newDriver, newVehicle) - stateManager.getRouteState(currentRoute,StateTypes.COSTS).toDouble();
+ double insertion_costs = auxilliaryPathCostCalculator.costOfPath(wholeTour, start.getEndTime(), newDriver, newVehicle) - stateManager.getRouteState(currentRoute,StateFactory.COSTS).toDouble();
/**
* if better than best known, make it the best known
@@ -282,7 +296,7 @@ final class CalculatesServiceInsertionOnRouteLevel 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);
}
@@ -316,9 +330,9 @@ final class CalculatesServiceInsertionOnRouteLevel implements JobInsertionCalcul
private double sumOf_prevCosts_oldVehicle(VehicleRoute vehicleRoute, TourActivity act) {
if(act instanceof End){
- return stateManager.getRouteState(vehicleRoute,StateTypes.COSTS).toDouble();
+ return stateManager.getRouteState(vehicleRoute,StateFactory.COSTS).toDouble();
}
- return stateManager.getActivityState(act,StateTypes.COSTS).toDouble();
+ return stateManager.getActivityState(act,StateFactory.COSTS).toDouble();
}
/**
diff --git a/jsprit-core/src/main/java/algorithms/ShipmentInsertionCalculator.java b/jsprit-core/src/main/java/algorithms/ShipmentInsertionCalculator.java
index a2d91f8c..21364830 100644
--- a/jsprit-core/src/main/java/algorithms/ShipmentInsertionCalculator.java
+++ b/jsprit-core/src/main/java/algorithms/ShipmentInsertionCalculator.java
@@ -22,7 +22,7 @@ import org.apache.log4j.Logger;
import util.Neighborhood;
import algorithms.ActivityInsertionCostsCalculator.ActivityInsertionCosts;
-import algorithms.HardConstraints.HardRouteLevelConstraint;
+import algorithms.HardActivityLevelConstraint.ConstraintsStatus;
import basics.Job;
import basics.Shipment;
import basics.costs.VehicleRoutingTransportCosts;
@@ -38,12 +38,14 @@ import basics.route.VehicleRoute;
-final class ShipmentInsertionCalculator implements JobInsertionCalculator{
+final class ShipmentInsertionCalculator implements JobInsertionCostsCalculator{
private static final Logger logger = Logger.getLogger(ShipmentInsertionCalculator.class);
private HardRouteLevelConstraint hardRouteLevelConstraint;
+ private HardActivityLevelConstraint hardActivityLevelConstraint;
+
private Neighborhood neighborhood = new Neighborhood() {
@Override
@@ -63,10 +65,11 @@ final class ShipmentInsertionCalculator implements JobInsertionCalculator{
logger.info("initialise neighborhood " + neighborhood);
}
- public ShipmentInsertionCalculator(VehicleRoutingTransportCosts routingCosts, ActivityInsertionCostsCalculator activityInsertionCostsCalculator, HardRouteLevelConstraint hardRouteLevelConstraint) {
+ public ShipmentInsertionCalculator(VehicleRoutingTransportCosts routingCosts, ActivityInsertionCostsCalculator activityInsertionCostsCalculator, HardRouteLevelConstraint hardRouteLevelConstraint, HardActivityLevelConstraint hardActivityLevelConstraint) {
super();
this.activityInsertionCostsCalculator = activityInsertionCostsCalculator;
this.hardRouteLevelConstraint = hardRouteLevelConstraint;
+ this.hardActivityLevelConstraint = hardActivityLevelConstraint;
this.transportCosts = routingCosts;
activityFactory = new DefaultShipmentActivityFactory();
logger.info("initialise " + this);
@@ -83,25 +86,24 @@ final class ShipmentInsertionCalculator implements JobInsertionCalculator{
*
*/
@Override
- public InsertionData calculate(final VehicleRoute currentRoute, final Job jobToInsert, final Vehicle newVehicle, double newVehicleDepartureTime, final Driver newDriver, final double bestKnownCosts) {
+ public InsertionData getInsertionData(final VehicleRoute currentRoute, final Job jobToInsert, final Vehicle newVehicle, double newVehicleDepartureTime, final Driver newDriver, final double bestKnownCosts) {
if(jobToInsert == null) throw new IllegalStateException("jobToInsert is missing.");
if(newVehicle == null || newVehicle instanceof NoVehicle) throw new IllegalStateException("newVehicle is missing.");
if(!(jobToInsert instanceof Shipment)) throw new IllegalStateException("jobToInsert should be of type Shipment!");
InsertionContext insertionContext = new InsertionContext(currentRoute, jobToInsert, newVehicle, newDriver, newVehicleDepartureTime);
if(!hardRouteLevelConstraint.fulfilled(insertionContext)){
- return InsertionData.noInsertionFound();
+ return InsertionData.createEmptyInsertionData();
}
double bestCost = bestKnownCosts;
Shipment shipment = (Shipment)jobToInsert;
TourActivity pickupShipment = activityFactory.createPickup(shipment);
- TourActivity deliveryShipment = activityFactory.createDelivery(shipment);
+ TourActivity deliverShipment = activityFactory.createDelivery(shipment);
int pickupInsertionIndex = InsertionData.NO_INDEX;
int deliveryInsertionIndex = InsertionData.NO_INDEX;
-// int insertionIndex = 0;
Start start = Start.newInstance(newVehicle.getLocationId(), newVehicle.getEarliestDeparture(), newVehicle.getLatestArrival());
start.setEndTime(newVehicleDepartureTime);
@@ -109,23 +111,32 @@ final class ShipmentInsertionCalculator implements JobInsertionCalculator{
TourActivity prevAct = start;
double prevActEndTime = newVehicleDepartureTime;
+ boolean pickupShipmentLoopBroken = false;
//pickupShipmentLoop
List activities = currentRoute.getTourActivities().getActivities();
for(int i=0;i reservedIds = Arrays.asList("maxload","load","costs","loadAtBeginning","loadAtEnd","duration","latestOST","earliestOST"
+ ,"futurePicks","pastDeliveries");
+
+
+ public static StateId createId(String name){
+ if(reservedIds.contains(name)){ throwException(name); }
+ return new StateIdImpl(name);
+ }
+
+ public static State createState(double value){
+ return new StateImpl(value);
+ }
+
+ private static void throwException(String name) {
+ throw new IllegalStateException("state-id with name '" + name + "' cannot be created. it is already reserved internally.");
+ }
+
+
+ static class StateIdImpl implements StateId {
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((name == null) ? 0 : name.hashCode());
+ return result;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ StateIdImpl other = (StateIdImpl) obj;
+ if (name == null) {
+ if (other.name != null)
+ return false;
+ } else if (!name.equals(other.name))
+ return false;
+ return true;
+ }
+
+ private String name;
+
+ public StateIdImpl(String name) {
+ super();
+ this.name = name;
+ }
+
+ public String toString(){
+ return name;
+ }
+ }
+}
diff --git a/jsprit-core/src/main/java/algorithms/CalcUtils.java b/jsprit-core/src/main/java/algorithms/StateGetter.java
similarity index 71%
rename from jsprit-core/src/main/java/algorithms/CalcUtils.java
rename to jsprit-core/src/main/java/algorithms/StateGetter.java
index c4515849..32a88e0e 100644
--- a/jsprit-core/src/main/java/algorithms/CalcUtils.java
+++ b/jsprit-core/src/main/java/algorithms/StateGetter.java
@@ -17,18 +17,22 @@
package algorithms;
import basics.route.TourActivity;
+import basics.route.VehicleRoute;
-class CalcUtils {
+public interface StateGetter {
+
+ public interface StateId {
+
+ }
+
+ public interface State {
+ double toDouble();
+ }
- /**
- * Calculates actEndTime assuming that activity can at earliest start at act.getTheoreticalEarliestOperationStartTime().
- *
- * @param actArrTime
- * @param act
- * @return
- */
- static double getActivityEndTime(double actArrTime, TourActivity act){
- return Math.max(actArrTime, act.getTheoreticalEarliestOperationStartTime()) + act.getOperationTime();
- }
+ State getActivityState(TourActivity act, StateId stateId);
+
+ State getRouteState(VehicleRoute route, StateId stateId);
+
+
}
diff --git a/jsprit-core/src/main/java/algorithms/StateManager.java b/jsprit-core/src/main/java/algorithms/StateManager.java
index 35d2f4f8..e83241b8 100644
--- a/jsprit-core/src/main/java/algorithms/StateManager.java
+++ b/jsprit-core/src/main/java/algorithms/StateManager.java
@@ -16,16 +16,42 @@
******************************************************************************/
package algorithms;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import basics.Job;
+import basics.VehicleRoutingProblem;
+import basics.VehicleRoutingProblemSolution;
+import basics.algo.InsertionEndsListener;
+import basics.algo.InsertionListener;
+import basics.algo.InsertionListeners;
+import basics.algo.InsertionStartsListener;
+import basics.algo.IterationStartsListener;
+import basics.algo.JobInsertedListener;
+import basics.algo.RuinListener;
+import basics.algo.RuinListeners;
+import basics.route.ActivityVisitor;
+import basics.route.ReverseActivityVisitor;
+import basics.route.ReverseRouteActivityVisitor;
+import basics.route.RouteActivityVisitor;
+import basics.route.RouteVisitor;
import basics.route.TourActivity;
import basics.route.VehicleRoute;
-interface StateManager {
+public class StateManager implements StateGetter, IterationStartsListener, RuinListener, InsertionStartsListener, JobInsertedListener, InsertionEndsListener {
+
- interface State {
- double toDouble();
+
+ private interface States {
+
+ State getState(StateId key);
+
}
- class StateImpl implements State{
+ static class StateImpl implements State{
double state;
public StateImpl(double state) {
@@ -40,14 +66,225 @@ interface StateManager {
}
- interface States {
-
- State getState(String key);
-
- }
-
- State getActivityState(TourActivity act, String stateType);
-
- State getRouteState(VehicleRoute route, String stateType);
+ private static class StatesImpl implements States{
+ private Map states = new HashMap();
+
+ public void putState(StateId key, State state) {
+ states.put(key, state);
+ }
+
+ @Override
+ public State getState(StateId key) {
+ return states.get(key);
+ }
+
+ }
+
+ private Map vehicleRouteStates = new HashMap();
+
+ private Map activityStates = new HashMap();
+
+ private RouteActivityVisitor routeActivityVisitor = new RouteActivityVisitor();
+
+ private ReverseRouteActivityVisitor revRouteActivityVisitor = new ReverseRouteActivityVisitor();
+
+ private Collection routeVisitors = new ArrayList();
+
+ private RuinListeners ruinListeners = new RuinListeners();
+
+ private InsertionListeners insertionListeners = new InsertionListeners();
+
+ private Collection updaters = new ArrayList();
+
+ private Map defaultRouteStates = new HashMap();
+
+ private Map defaultActivityStates = new HashMap();
+
+ public void addDefaultRouteState(StateId stateId, State defaultState){
+ defaultRouteStates.put(stateId, defaultState);
+ }
+
+ public void addDefaultActivityState(StateId stateId, State defaultState){
+ defaultActivityStates.put(stateId, defaultState);
+ }
+
+ public void clear(){
+ vehicleRouteStates.clear();
+ activityStates.clear();
+ }
+
+ @Override
+ public State getActivityState(TourActivity act, StateId stateId) {
+ if(!activityStates.containsKey(act)){
+ return getDefaultActState(stateId,act);
+ }
+ StatesImpl actStates = (StatesImpl) activityStates.get(act);
+ State state = actStates.getState(stateId);
+ if(state == null){
+ return getDefaultActState(stateId,act);
+ }
+ return state;
+ }
+
+ public void putActivityState(TourActivity act, StateId stateId, State state){
+ if(!activityStates.containsKey(act)){
+ activityStates.put(act, new StatesImpl());
+ }
+ StatesImpl actStates = (StatesImpl) activityStates.get(act);
+ actStates.putState(stateId, state);
+ }
+
+
+ public void putRouteState(VehicleRoute route, StateId stateId, State state){
+ if(!vehicleRouteStates.containsKey(route)){
+ vehicleRouteStates.put(route, new StatesImpl());
+ }
+ StatesImpl routeStates = (StatesImpl) vehicleRouteStates.get(route);
+ routeStates.putState(stateId, state);
+ }
+
+ @Override
+ public State getRouteState(VehicleRoute route, StateId stateId) {
+ if(!vehicleRouteStates.containsKey(route)){
+ return getDefaultRouteState(stateId,route);
+ }
+ StatesImpl routeStates = (StatesImpl) vehicleRouteStates.get(route);
+ State state = routeStates.getState(stateId);
+ if(state == null){
+ return getDefaultRouteState(stateId, route);
+ }
+ return state;
+ }
+
+ /**
+ * Adds state updater.
+ *
+ * Note that a state update occurs if route and/or activity states change, i.e. if jobs are removed
+ * or inserted into a route. Thus here, it is assumed that a state updater is either of type InsertionListener,
+ * RuinListener, ActivityVisitor, ReverseActivityVisitor, RouteVisitor, ReverseRouteVisitor.
+ *
+ *
The following rule pertain for activity/route visitors:These visitors visits all activities/route in a route subsequently in two cases. First, if insertionStart (after ruinStrategies have removed activities from routes)
+ * and, second, if a job has been inserted and thus if a route has changed.
+ *
+ * @param updater
+ */
+ public void addStateUpdater(StateUpdater updater){
+ if(updater instanceof ActivityVisitor) addActivityVisitor((ActivityVisitor) updater);
+ if(updater instanceof ReverseActivityVisitor) addActivityVisitor((ReverseActivityVisitor)updater);
+ if(updater instanceof RouteVisitor) addRouteVisitor((RouteVisitor) updater);
+ if(updater instanceof InsertionListener) addListener((InsertionListener) updater);
+ if(updater instanceof RuinListener) addListener((RuinListener) updater);
+ updaters.add(updater);
+ }
+
+ Collection getStateUpdaters(){
+ return Collections.unmodifiableCollection(updaters);
+ }
+
+ /**
+ * Adds an activityVisitor.
+ * This visitor visits all activities in a route subsequently in two cases. First, if insertionStart (after ruinStrategies have removed activities from routes)
+ * and, second, if a job has been inserted and thus if a route has changed.
+ *
+ * @param activityVistor
+ */
+ void addActivityVisitor(ActivityVisitor activityVistor){
+ routeActivityVisitor.addActivityVisitor(activityVistor);
+ }
+
+ /**
+ * Adds an reverseActivityVisitor.
+ *
This reverseVisitor visits all activities in a route subsequently (starting from the end of the route) in two cases. First, if insertionStart (after ruinStrategies have removed activities from routes)
+ * and, second, if a job has been inserted and thus if a route has changed.
+ *
+ * @param reverseActivityVistor
+ */
+ void addActivityVisitor(ReverseActivityVisitor activityVistor){
+ revRouteActivityVisitor.addActivityVisitor(activityVistor);
+ }
+
+ void addRouteVisitor(RouteVisitor routeVisitor){
+ routeVisitors.add(routeVisitor);
+ }
+
+ void addListener(RuinListener ruinListener){
+ ruinListeners.addListener(ruinListener);
+ }
+
+ void removeListener(RuinListener ruinListener){
+ ruinListeners.removeListener(ruinListener);
+ }
+
+ void addListener(InsertionListener insertionListener){
+ insertionListeners.addListener(insertionListener);
+ }
+
+ void removeListener(InsertionListener insertionListener){
+ insertionListeners.removeListener(insertionListener);
+ }
+
+ private State getDefaultActState(StateId stateId, TourActivity act){
+ if(stateId.equals(StateFactory.LOAD)) return new StateImpl(0);
+ if(stateId.equals(StateFactory.COSTS)) return new StateImpl(0);
+ if(stateId.equals(StateFactory.DURATION)) return new StateImpl(0);
+ if(stateId.equals(StateFactory.EARLIEST_OPERATION_START_TIME)) return new StateImpl(act.getTheoreticalEarliestOperationStartTime());
+ if(stateId.equals(StateFactory.LATEST_OPERATION_START_TIME)) return new StateImpl(act.getTheoreticalLatestOperationStartTime());
+ if(stateId.equals(StateFactory.FUTURE_PICKS)) return new StateImpl(0);
+ if(stateId.equals(StateFactory.PAST_DELIVERIES)) return new StateImpl(0);
+ return null;
+ }
+
+ private State getDefaultRouteState(StateId stateId, VehicleRoute route){
+ if(stateId.equals(StateFactory.MAXLOAD)) return new StateImpl(0);
+ if(stateId.equals(StateFactory.LOAD)) return new StateImpl(0);
+ if(stateId.equals(StateFactory.LOAD_AT_END)) return new StateImpl(0);
+ if(stateId.equals(StateFactory.LOAD_AT_BEGINNING)) return new StateImpl(0);
+ if(stateId.equals(StateFactory.COSTS)) return new StateImpl(0);
+ if(stateId.equals(StateFactory.DURATION)) return new StateImpl(0);
+ return null;
+ }
+
+ @Override
+ public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) {
+ insertionListeners.jobInserted(job2insert, inRoute, additionalCosts, additionalTime);
+ for(RouteVisitor v : routeVisitors){ v.visit(inRoute); }
+ routeActivityVisitor.visit(inRoute);
+ revRouteActivityVisitor.visit(inRoute);
+ }
+
+ @Override
+ public void informInsertionStarts(Collection vehicleRoutes,Collection unassignedJobs) {
+ insertionListeners.insertionStarts(vehicleRoutes, unassignedJobs);
+ for(VehicleRoute route : vehicleRoutes){
+ for(RouteVisitor v : routeVisitors){ v.visit(route); }
+ routeActivityVisitor.visit(route);
+ revRouteActivityVisitor.visit(route);
+ }
+ }
+
+ @Override
+ public void informIterationStarts(int i, VehicleRoutingProblem problem, Collection solutions) {
+ clear();
+ }
+
+ @Override
+ public void ruinStarts(Collection routes) {
+ ruinListeners.ruinStarts(routes);
+ }
+
+ @Override
+ public void ruinEnds(Collection routes, Collection unassignedJobs) {
+ ruinListeners.ruinEnds(routes, unassignedJobs);
+ }
+
+ @Override
+ public void removed(Job job, VehicleRoute fromRoute) {
+ ruinListeners.removed(job, fromRoute);
+ }
+
+ @Override
+ public void informInsertionEnds(Collection vehicleRoutes) {
+ insertionListeners.insertionEnds(vehicleRoutes);
+ }
}
diff --git a/jsprit-core/src/main/java/algorithms/StateManagerImpl.java b/jsprit-core/src/main/java/algorithms/StateManagerImpl.java
deleted file mode 100644
index cf31497d..00000000
--- a/jsprit-core/src/main/java/algorithms/StateManagerImpl.java
+++ /dev/null
@@ -1,151 +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 .
- ******************************************************************************/
-package algorithms;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-
-import basics.Job;
-import basics.algo.InsertionStartsListener;
-import basics.algo.JobInsertedListener;
-import basics.route.TourActivity;
-import basics.route.VehicleRoute;
-
-class StateManagerImpl implements StateManager, InsertionStartsListener, JobInsertedListener {
-
- static class StatesImpl implements States{
-
- private Map states = new HashMap();
-
- public void putState(String key, State state) {
- states.put(key, state);
- }
-
- @Override
- public State getState(String key) {
- return states.get(key);
- }
-
- }
-
- private Map vehicleRouteStates = new HashMap();
-
- private Map activityStates = new HashMap();
-
- private RouteActivityVisitor routeActivityVisitor = new RouteActivityVisitor();
-
- private ReverseRouteActivityVisitor revRouteActivityVisitor = new ReverseRouteActivityVisitor();
-
- private Collection routeVisitors = new ArrayList();
-
- public void clear(){
- vehicleRouteStates.clear();
- activityStates.clear();
- }
-
- @Override
- public State getActivityState(TourActivity act, String stateType) {
- if(!activityStates.containsKey(act)){
- return getDefaultActState(stateType,act);
- }
- StatesImpl actStates = (StatesImpl) activityStates.get(act);
- State state = actStates.getState(stateType);
- if(state == null){
- return getDefaultActState(stateType,act);
- }
- return state;
- }
-
- public void putActivityState(TourActivity act, String stateType, State state){
- if(!activityStates.containsKey(act)){
- activityStates.put(act, new StatesImpl());
- }
- StatesImpl actStates = (StatesImpl) activityStates.get(act);
- actStates.putState(stateType, state);
- }
-
-
- private State getDefaultActState(String stateType, TourActivity act){
- if(stateType.equals(StateTypes.LOAD)) return new StateImpl(0);
- if(stateType.equals(StateTypes.COSTS)) return new StateImpl(0);
- if(stateType.equals(StateTypes.DURATION)) return new StateImpl(0);
- if(stateType.equals(StateTypes.EARLIEST_OPERATION_START_TIME)) return new StateImpl(act.getTheoreticalEarliestOperationStartTime());
- if(stateType.equals(StateTypes.LATEST_OPERATION_START_TIME)) return new StateImpl(act.getTheoreticalLatestOperationStartTime());
- if(stateType.equals(StateTypes.FUTURE_PICKS)) return new StateImpl(0);
- if(stateType.equals(StateTypes.PAST_DELIVERIES)) return new StateImpl(0);
- return null;
- }
-
- private State getDefaultRouteState(String stateType, VehicleRoute route){
- if(stateType.equals(StateTypes.LOAD)) return new StateImpl(0);
- if(stateType.equals(StateTypes.LOAD_AT_DEPOT)) return new StateImpl(0);
- if(stateType.equals(StateTypes.COSTS)) return new StateImpl(0);
- if(stateType.equals(StateTypes.DURATION)) return new StateImpl(0);
- return null;
- }
-
- @Override
- public State getRouteState(VehicleRoute route, String stateType) {
- if(!vehicleRouteStates.containsKey(route)){
- return getDefaultRouteState(stateType,route);
- }
- StatesImpl routeStates = (StatesImpl) vehicleRouteStates.get(route);
- State state = routeStates.getState(stateType);
- if(state == null){
- return getDefaultRouteState(stateType, route);
- }
- return state;
- }
-
- public void putRouteState(VehicleRoute route, String stateType, State state){
- if(!vehicleRouteStates.containsKey(route)){
- vehicleRouteStates.put(route, new StatesImpl());
- }
- StatesImpl routeStates = (StatesImpl) vehicleRouteStates.get(route);
- routeStates.putState(stateType, state);
- }
-
- @Override
- public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) {
- for(RouteVisitor v : routeVisitors){ v.visit(inRoute); }
- routeActivityVisitor.visit(inRoute);
- revRouteActivityVisitor.visit(inRoute);
- }
-
- @Override
- public void informInsertionStarts(Collection vehicleRoutes,Collection unassignedJobs) {
- for(VehicleRoute route : vehicleRoutes){
- for(RouteVisitor v : routeVisitors){ v.visit(route); }
- routeActivityVisitor.visit(route);
- revRouteActivityVisitor.visit(route);
- }
- }
-
- public void addActivityVisitor(ActivityVisitor activityVistor){
- routeActivityVisitor.addActivityVisitor(activityVistor);
- }
-
- public void addActivityVisitor(ReverseActivityVisitor activityVistor){
- revRouteActivityVisitor.addActivityVisitor(activityVistor);
- }
-
- public void addRouteVisitor(RouteVisitor routeVisitor){
- routeVisitors.add(routeVisitor);
- }
-}
diff --git a/jsprit-core/src/main/java/algorithms/StateUpdater.java b/jsprit-core/src/main/java/algorithms/StateUpdater.java
new file mode 100644
index 00000000..9fd80a19
--- /dev/null
+++ b/jsprit-core/src/main/java/algorithms/StateUpdater.java
@@ -0,0 +1,5 @@
+package algorithms;
+
+public interface StateUpdater {
+
+}
diff --git a/jsprit-core/src/main/java/algorithms/StateUpdates.java b/jsprit-core/src/main/java/algorithms/StateUpdates.java
deleted file mode 100644
index d85f0cee..00000000
--- a/jsprit-core/src/main/java/algorithms/StateUpdates.java
+++ /dev/null
@@ -1,633 +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 .
- ******************************************************************************/
-package algorithms;
-
-import java.util.ArrayList;
-import java.util.Collection;
-
-import org.apache.log4j.Logger;
-
-import algorithms.RuinStrategy.RuinListener;
-import algorithms.StateManager.StateImpl;
-import basics.Delivery;
-import basics.Job;
-import basics.Pickup;
-import basics.Service;
-import basics.VehicleRoutingProblem;
-import basics.VehicleRoutingProblemSolution;
-import basics.algo.InsertionEndsListener;
-import basics.algo.InsertionStartsListener;
-import basics.algo.IterationStartsListener;
-import basics.algo.JobInsertedListener;
-import basics.costs.ForwardTransportCost;
-import basics.costs.ForwardTransportTime;
-import basics.costs.VehicleRoutingActivityCosts;
-import basics.costs.VehicleRoutingTransportCosts;
-import basics.route.DeliveryActivity;
-import basics.route.PickupActivity;
-import basics.route.ServiceActivity;
-import basics.route.TourActivity;
-import basics.route.Vehicle;
-import basics.route.VehicleRoute;
-import basics.route.VehicleType;
-
-class StateUpdates {
-
- static class UpdateCostsAtRouteLevel implements JobInsertedListener, InsertionStartsListener, InsertionEndsListener{
-
- private StateManagerImpl states;
-
- private VehicleRoutingTransportCosts tpCosts;
-
- private VehicleRoutingActivityCosts actCosts;
-
- public UpdateCostsAtRouteLevel(StateManagerImpl states, VehicleRoutingTransportCosts tpCosts, VehicleRoutingActivityCosts actCosts) {
- super();
- this.states = states;
- this.tpCosts = tpCosts;
- this.actCosts = actCosts;
- }
-
- @Override
- public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) {
-// inRoute.getVehicleRouteCostCalculator().addTransportCost(additionalCosts);
- double oldCosts = states.getRouteState(inRoute, StateTypes.COSTS).toDouble();
- oldCosts += additionalCosts;
- states.putRouteState(inRoute, StateTypes.COSTS, new StateImpl(oldCosts));
- }
-
- @Override
- public void informInsertionStarts(Collection vehicleRoutes, Collection unassignedJobs) {
- RouteActivityVisitor forwardInTime = new RouteActivityVisitor();
- forwardInTime.addActivityVisitor(new UpdateCostsAtAllLevels(actCosts, tpCosts, states));
- for(VehicleRoute route : vehicleRoutes){
- forwardInTime.visit(route);
- }
-
- }
-
- @Override
- public void informInsertionEnds(Collection vehicleRoutes) {
-
-// IterateRouteForwardInTime forwardInTime = new IterateRouteForwardInTime(tpCosts);
-// forwardInTime.addListener(new UpdateCostsAtAllLevels(actCosts, tpCosts, states));
-// for(VehicleRoute route : vehicleRoutes){
-// if(route.isEmpty()) continue;
-// route.getVehicleRouteCostCalculator().reset();
-// route.getVehicleRouteCostCalculator().addOtherCost(states.getRouteState(route, StateTypes.COSTS).toDouble());
-// route.getVehicleRouteCostCalculator().price(route.getVehicle());
-// forwardInTime.iterate(route);
-// }
-
- }
-
- }
-
- static class UpdateActivityTimes implements ActivityVisitor{
-
- private Logger log = Logger.getLogger(UpdateActivityTimes.class);
-
- private ActivityTimeTracker timeTracker;
-
- private VehicleRoute route;
-
- public UpdateActivityTimes(ForwardTransportTime transportTime) {
- super();
- timeTracker = new ActivityTimeTracker(transportTime);
- }
-
- @Override
- public void begin(VehicleRoute route) {
- timeTracker.begin(route);
- this.route = route;
- route.getStart().setEndTime(timeTracker.getActEndTime());
- }
-
- @Override
- public void visit(TourActivity activity) {
- timeTracker.visit(activity);
- activity.setArrTime(timeTracker.getActArrTime());
- activity.setEndTime(timeTracker.getActEndTime());
- }
-
- @Override
- public void finish() {
- timeTracker.finish();
- route.getEnd().setArrTime(timeTracker.getActArrTime());
- }
-
- }
-
- static class UpdateCostsAtAllLevels implements ActivityVisitor{
-
- private static Logger log = Logger.getLogger(UpdateCostsAtAllLevels.class);
-
- private VehicleRoutingActivityCosts activityCost;
-
- private ForwardTransportCost transportCost;
-
- private StateManagerImpl states;
-
- private double totalOperationCost = 0.0;
-
- private VehicleRoute vehicleRoute = null;
-
- private TourActivity prevAct = null;
-
- private double startTimeAtPrevAct = 0.0;
-
- private ActivityTimeTracker timeTracker;
-
- public UpdateCostsAtAllLevels(VehicleRoutingActivityCosts activityCost, VehicleRoutingTransportCosts transportCost, StateManagerImpl states) {
- super();
- this.activityCost = activityCost;
- this.transportCost = transportCost;
- this.states = states;
- timeTracker = new ActivityTimeTracker(transportCost);
- }
-
- @Override
- public void begin(VehicleRoute route) {
- vehicleRoute = route;
- vehicleRoute.getVehicleRouteCostCalculator().reset();
- timeTracker.begin(route);
- prevAct = route.getStart();
- startTimeAtPrevAct = timeTracker.getActEndTime();
- }
-
- @Override
- public void visit(TourActivity act) {
- timeTracker.visit(act);
-
- double transportCost = this.transportCost.getTransportCost(prevAct.getLocationId(), act.getLocationId(), startTimeAtPrevAct, vehicleRoute.getDriver(), vehicleRoute.getVehicle());
- double actCost = activityCost.getActivityCost(act, timeTracker.getActArrTime(), vehicleRoute.getDriver(), vehicleRoute.getVehicle());
-
- vehicleRoute.getVehicleRouteCostCalculator().addTransportCost(transportCost);
- vehicleRoute.getVehicleRouteCostCalculator().addActivityCost(actCost);
-
- totalOperationCost += transportCost;
- totalOperationCost += actCost;
-
- states.putActivityState(act, StateTypes.COSTS, new StateImpl(totalOperationCost));
-
- prevAct = act;
- startTimeAtPrevAct = timeTracker.getActEndTime();
- }
-
- @Override
- public void finish() {
- timeTracker.finish();
- double transportCost = this.transportCost.getTransportCost(prevAct.getLocationId(), vehicleRoute.getEnd().getLocationId(), startTimeAtPrevAct, vehicleRoute.getDriver(), vehicleRoute.getVehicle());
- double actCost = activityCost.getActivityCost(vehicleRoute.getEnd(), timeTracker.getActEndTime(), vehicleRoute.getDriver(), vehicleRoute.getVehicle());
-
- vehicleRoute.getVehicleRouteCostCalculator().addTransportCost(transportCost);
- vehicleRoute.getVehicleRouteCostCalculator().addActivityCost(actCost);
-
- totalOperationCost += transportCost;
- totalOperationCost += actCost;
-// totalOperationCost += getFixCosts();
-
- states.putRouteState(vehicleRoute, StateTypes.COSTS, new StateImpl(totalOperationCost));
-
-// this is rather strange and likely to change
- vehicleRoute.getVehicleRouteCostCalculator().price(vehicleRoute.getDriver());
- vehicleRoute.getVehicleRouteCostCalculator().price(vehicleRoute.getVehicle());
- vehicleRoute.getVehicleRouteCostCalculator().finish();
-
- startTimeAtPrevAct = 0.0;
- prevAct = null;
- vehicleRoute = null;
- totalOperationCost = 0.0;
- }
-
- private double getFixCosts() {
- Vehicle vehicle = vehicleRoute.getVehicle();
- if(vehicle == null) return 0.0;
- VehicleType type = vehicle.getType();
- if(type == null) return 0.0;
- return type.getVehicleCostParams().fix;
- }
-
- }
-
- static class UpdateEarliestStartTimeWindowAtActLocations implements ActivityVisitor{
-
- private StateManagerImpl states;
-
- private ActivityTimeTracker timeTracker;
-
- public UpdateEarliestStartTimeWindowAtActLocations(StateManagerImpl states, VehicleRoutingTransportCosts transportCosts) {
- super();
- this.states = states;
- timeTracker = new ActivityTimeTracker(transportCosts);
- }
-
- @Override
- public void begin(VehicleRoute route) {
- timeTracker.begin(route);
- }
-
- @Override
- public void visit(TourActivity activity) {
- timeTracker.visit(activity);
- states.putActivityState(activity, StateTypes.EARLIEST_OPERATION_START_TIME, new StateImpl(Math.max(timeTracker.getActArrTime(), activity.getTheoreticalEarliestOperationStartTime())));
-
- }
-
- @Override
- public void finish() {}
-
- }
-
- static class UpdateLatestOperationStartTimeAtActLocations implements ReverseActivityVisitor{
-
- private static Logger log = Logger.getLogger(UpdateLatestOperationStartTimeAtActLocations.class);
-
- private StateManagerImpl states;
-
- private VehicleRoute route;
-
- private VehicleRoutingTransportCosts transportCosts;
-
- private double latestArrTimeAtPrevAct;
-
- private TourActivity prevAct;
-
- public UpdateLatestOperationStartTimeAtActLocations(StateManagerImpl states, VehicleRoutingTransportCosts tpCosts) {
- super();
- this.states = states;
- this.transportCosts = tpCosts;
- }
-
- @Override
- public void begin(VehicleRoute route) {
- this.route = route;
- latestArrTimeAtPrevAct = route.getEnd().getTheoreticalLatestOperationStartTime();
- prevAct = route.getEnd();
- }
-
- @Override
- public void visit(TourActivity activity) {
- double potentialLatestArrivalTimeAtCurrAct = latestArrTimeAtPrevAct - transportCosts.getBackwardTransportTime(activity.getLocationId(), prevAct.getLocationId(), latestArrTimeAtPrevAct, route.getDriver(),route.getVehicle()) - activity.getOperationTime();
- double latestArrivalTime = Math.min(activity.getTheoreticalLatestOperationStartTime(), potentialLatestArrivalTimeAtCurrAct);
-
- states.putActivityState(activity, StateTypes.LATEST_OPERATION_START_TIME, new StateImpl(latestArrivalTime));
-
- latestArrTimeAtPrevAct = latestArrivalTime;
- prevAct = activity;
- }
-
- @Override
- public void finish() {}
- }
-
- static class UpdateLoadAtAllLevels implements ActivityVisitor{
-
- private double load = 0.0;
-
- private StateManagerImpl states;
-
- private VehicleRoute vehicleRoute;
-
- public UpdateLoadAtAllLevels(StateManagerImpl states) {
- super();
- this.states = states;
- }
-
- @Override
- public void begin(VehicleRoute route) {
- vehicleRoute = route;
- }
-
- @Override
- public void visit(TourActivity activity) {
- load += (double)activity.getCapacityDemand();
- states.putActivityState(activity, StateTypes.LOAD, new StateImpl(load));
- }
-
- @Override
- public void finish() {
- states.putRouteState(vehicleRoute, StateTypes.LOAD, new StateImpl(load));
- load=0;
- vehicleRoute = null;
- }
-
- }
-
- static class UpdateLoadAtRouteLevel implements JobInsertedListener, InsertionStartsListener{
-
- private StateManagerImpl states;
-
- public UpdateLoadAtRouteLevel(StateManagerImpl states) {
- super();
- this.states = states;
- }
-
- @Override
- public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) {
- if(!(job2insert instanceof Service)){
- return;
- }
- double oldLoad = states.getRouteState(inRoute, StateTypes.LOAD).toDouble();
- states.putRouteState(inRoute, StateTypes.LOAD, new StateImpl(oldLoad + job2insert.getCapacityDemand()));
- }
-
- @Override
- public void informInsertionStarts(Collection vehicleRoutes, Collection unassignedJobs) {
- for(VehicleRoute route : vehicleRoutes){
- int load = 0;
- for(Job j : route.getTourActivities().getJobs()){
- load += j.getCapacityDemand();
- }
- states.putRouteState(route, StateTypes.LOAD, new StateImpl(load));
- }
-
- }
-
- }
-
- static class UpdateStates implements JobInsertedListener, RuinListener{
-
- private RouteActivityVisitor routeActivityVisitor;
-
- private ReverseRouteActivityVisitor revRouteActivityVisitor;
-
- public UpdateStates(StateManagerImpl states, VehicleRoutingTransportCosts routingCosts, VehicleRoutingActivityCosts activityCosts) {
- routeActivityVisitor = new RouteActivityVisitor();
- routeActivityVisitor.addActivityVisitor(new UpdateActivityTimes(routingCosts));
- routeActivityVisitor.addActivityVisitor(new UpdateCostsAtAllLevels(activityCosts, routingCosts, states));
- routeActivityVisitor.addActivityVisitor(new UpdateLoadAtAllLevels(states));
-
- revRouteActivityVisitor = new ReverseRouteActivityVisitor();
- revRouteActivityVisitor.addActivityVisitor(new UpdateLatestOperationStartTimeAtActLocations(states, routingCosts));
-
- }
-
- public void update(VehicleRoute route){
- routeActivityVisitor.visit(route);
- revRouteActivityVisitor.visit(route);
- }
-
- @Override
- public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) {
- routeActivityVisitor.visit(inRoute);
- revRouteActivityVisitor.visit(inRoute);
- }
-
- @Override
- public void ruinStarts(Collection routes) {}
-
- @Override
- public void ruinEnds(Collection routes,Collection unassignedJobs) {
- for(VehicleRoute route : routes) {
- routeActivityVisitor.visit(route);
- revRouteActivityVisitor.visit(route);
- }
- }
-
- @Override
- public void removed(Job job, VehicleRoute fromRoute) {}
-
- }
-
- static class UpdateFuturePickupsAtActivityLevel implements ReverseActivityVisitor {
- private StateManagerImpl stateManager;
- private int futurePicks = 0;
- private VehicleRoute route;
-
- public UpdateFuturePickupsAtActivityLevel(StateManagerImpl stateManager) {
- super();
- this.stateManager = stateManager;
- }
-
- @Override
- public void begin(VehicleRoute route) {
- this.route = route;
- }
-
- @Override
- public void visit(TourActivity act) {
- stateManager.putActivityState(act, StateTypes.FUTURE_PICKS, new StateImpl(futurePicks));
- if(act instanceof PickupActivity || act instanceof ServiceActivity){
- futurePicks += act.getCapacityDemand();
- }
- assert futurePicks <= route.getVehicle().getCapacity() : "sum of pickups must not be > vehicleCap";
- assert futurePicks >= 0 : "sum of pickups must not < 0";
- }
-
- @Override
- public void finish() {
- futurePicks = 0;
- route = null;
- }
- }
-
- static class UpdateOccuredDeliveriesAtActivityLevel implements ActivityVisitor {
- private StateManagerImpl stateManager;
- private int deliveries = 0;
- private VehicleRoute route;
-
- public UpdateOccuredDeliveriesAtActivityLevel(StateManagerImpl stateManager) {
- super();
- this.stateManager = stateManager;
- }
-
- @Override
- public void begin(VehicleRoute route) {
- this.route = route;
- }
-
- @Override
- public void visit(TourActivity act) {
- if(act instanceof DeliveryActivity){
- deliveries += Math.abs(act.getCapacityDemand());
- }
- stateManager.putActivityState(act, StateTypes.PAST_DELIVERIES, new StateImpl(deliveries));
- assert deliveries >= 0 : "deliveries < 0";
- assert deliveries <= route.getVehicle().getCapacity() : "deliveries > vehicleCap";
- }
-
- @Override
- public void finish() {
- deliveries = 0;
- route = null;
- }
- }
-
- /**
- * Updates load at activity level. Note that this assumed that StateTypes.LOAD_AT_DEPOT is already updated, i.e. it starts by setting loadAtDepot to StateTypes.LOAD_AT_DEPOT.
- * If StateTypes.LOAD_AT_DEPOT is not set, it starts with 0 load at depot.
- *
- * @author stefan
- *
- */
- static class UpdateLoadAtActivityLevel implements ActivityVisitor {
- private StateManagerImpl stateManager;
- private int currentLoad = 0;
- private VehicleRoute route;
-
- public UpdateLoadAtActivityLevel(StateManagerImpl stateManager) {
- super();
- this.stateManager = stateManager;
- }
-
- @Override
- public void begin(VehicleRoute route) {
- currentLoad = (int) stateManager.getRouteState(route, StateTypes.LOAD_AT_DEPOT).toDouble();
- this.route = route;
- }
-
- @Override
- public void visit(TourActivity act) {
- currentLoad += act.getCapacityDemand();
- stateManager.putActivityState(act, StateTypes.LOAD, new StateImpl(currentLoad));
- assert currentLoad <= route.getVehicle().getCapacity() : "currentLoad at activity must not be > vehicleCapacity";
- assert currentLoad >= 0 : "currentLoad at act must not be < 0";
- }
-
- @Override
- public void finish() {
- currentLoad = 0;
- }
- }
-
- static class ResetStateManager implements IterationStartsListener {
-
- private StateManagerImpl stateManager;
-
- public ResetStateManager(StateManagerImpl stateManager) {
- super();
- this.stateManager = stateManager;
- }
-
- @Override
- public void informIterationStarts(int i, VehicleRoutingProblem problem, Collection solutions) {
- stateManager.clear();
- }
- }
-
- static interface InsertionStarts {
-
- void insertionStarts(VehicleRoute route);
-
- }
-
- static class UpdateLoadsAtStartAndEndOfRouteWhenInsertionStarts implements InsertionStarts {
-
- private StateManagerImpl stateManager;
-
- public UpdateLoadsAtStartAndEndOfRouteWhenInsertionStarts(StateManagerImpl stateManager) {
- super();
- this.stateManager = stateManager;
- }
-
- @Override
- public void insertionStarts(VehicleRoute route) {
- int loadAtDepot = 0;
- int loadAtEnd = 0;
- for(Job j : route.getTourActivities().getJobs()){
- if(j instanceof Delivery){
- loadAtDepot += j.getCapacityDemand();
- }
- else if(j instanceof Pickup || j instanceof Service){
- loadAtEnd += j.getCapacityDemand();
- }
- }
- stateManager.putRouteState(route, StateTypes.LOAD_AT_DEPOT, new StateImpl(loadAtDepot));
- stateManager.putRouteState(route, StateTypes.LOAD, new StateImpl(loadAtEnd));
- }
-
- }
-
- static class UpdateLoadsAtStartAndEndOfRouteWhenJobHasBeenInserted implements JobInsertedListener {
-
- private StateManagerImpl stateManager;
-
- public UpdateLoadsAtStartAndEndOfRouteWhenJobHasBeenInserted(StateManagerImpl stateManager) {
- super();
- this.stateManager = stateManager;
- }
-
- @Override
- public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) {
- if(job2insert instanceof Delivery){
- int loadAtDepot = (int) stateManager.getRouteState(inRoute, StateTypes.LOAD_AT_DEPOT).toDouble();
-// log.info("loadAtDepot="+loadAtDepot);
- stateManager.putRouteState(inRoute, StateTypes.LOAD_AT_DEPOT, new StateImpl(loadAtDepot + job2insert.getCapacityDemand()));
- }
- else if(job2insert instanceof Pickup || job2insert instanceof Service){
- int loadAtEnd = (int) stateManager.getRouteState(inRoute, StateTypes.LOAD).toDouble();
-// log.info("loadAtEnd="+loadAtEnd);
- stateManager.putRouteState(inRoute, StateTypes.LOAD, new StateImpl(loadAtEnd + job2insert.getCapacityDemand()));
- }
- }
-
- }
-
- static class UpdateRouteStatesOnceTheRouteHasBeenChanged implements InsertionStartsListener, JobInsertedListener {
-
- private RouteActivityVisitor forwardInTimeIterator;
-
- private ReverseRouteActivityVisitor backwardInTimeIterator;
-
- private Collection insertionStartsListeners;
-
- private Collection jobInsertionListeners;
-
- public UpdateRouteStatesOnceTheRouteHasBeenChanged(VehicleRoutingTransportCosts routingCosts) {
- forwardInTimeIterator = new RouteActivityVisitor();
- backwardInTimeIterator = new ReverseRouteActivityVisitor();
- insertionStartsListeners = new ArrayList();
- jobInsertionListeners = new ArrayList();
- }
-
- void addVisitor(ActivityVisitor vis){
- forwardInTimeIterator.addActivityVisitor(vis);
- }
-
- void addVisitor(ReverseActivityVisitor revVis){
- backwardInTimeIterator.addActivityVisitor(revVis);
- }
-
- void addInsertionStartsListener(InsertionStarts insertionStartListener){
- insertionStartsListeners.add(insertionStartListener);
- }
-
- void addJobInsertedListener(JobInsertedListener jobInsertedListener){
- jobInsertionListeners.add(jobInsertedListener);
- }
-
- @Override
- public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) {
- for(JobInsertedListener l : jobInsertionListeners){ l.informJobInserted(job2insert, inRoute, additionalCosts, additionalTime); }
- forwardInTimeIterator.visit(inRoute);
- backwardInTimeIterator.visit(inRoute);
- }
-
- @Override
- public void informInsertionStarts(Collection vehicleRoutes, Collection unassignedJobs) {
- for(VehicleRoute route : vehicleRoutes){
- for(InsertionStarts insertionsStartsHandler : insertionStartsListeners){
- insertionsStartsHandler.insertionStarts(route);
- }
- forwardInTimeIterator.visit(route);
- backwardInTimeIterator.visit(route);
- }
- }
-
- }
-}
diff --git a/jsprit-core/src/main/java/algorithms/StateUtils.java b/jsprit-core/src/main/java/algorithms/StateUtils.java
new file mode 100644
index 00000000..86ee258d
--- /dev/null
+++ b/jsprit-core/src/main/java/algorithms/StateUtils.java
@@ -0,0 +1,24 @@
+package algorithms;
+
+import basics.VehicleRoutingProblem;
+
+class StateUtils {
+
+ public static void addCoreStateUpdaters(VehicleRoutingProblem vrp, StateManager stateManager){
+ stateManager.addListener(new UpdateLoadsAtStartAndEndOfRouteWhenInsertionStarts(stateManager));
+ stateManager.addListener(new UpdateLoadsAtStartAndEndOfRouteWhenJobHasBeenInserted(stateManager));
+
+ stateManager.addActivityVisitor(new UpdateActivityTimes(vrp.getTransportCosts()));
+ stateManager.addActivityVisitor(new UpdateLoadAtActivityLevel(stateManager));
+
+ stateManager.addActivityVisitor(new UpdateCostsAtAllLevels(vrp.getActivityCosts(), vrp.getTransportCosts(), stateManager));
+
+ stateManager.addActivityVisitor(new UpdateOccuredDeliveriesAtActivityLevel(stateManager));
+
+ stateManager.addActivityVisitor(new UpdateLatestOperationStartTimeAtActLocations(stateManager, vrp.getTransportCosts()));
+
+ stateManager.addActivityVisitor(new UpdateFuturePickupsAtActivityLevel(stateManager));
+
+ }
+
+}
diff --git a/jsprit-core/src/main/java/algorithms/UpdateActivityTimes.java b/jsprit-core/src/main/java/algorithms/UpdateActivityTimes.java
new file mode 100644
index 00000000..860504c0
--- /dev/null
+++ b/jsprit-core/src/main/java/algorithms/UpdateActivityTimes.java
@@ -0,0 +1,65 @@
+package algorithms;
+
+import org.apache.log4j.Logger;
+
+import util.ActivityTimeTracker;
+
+import basics.costs.ForwardTransportTime;
+import basics.route.ActivityVisitor;
+import basics.route.TourActivity;
+import basics.route.VehicleRoute;
+
+/**
+ * Updates arrival and end times of activities.
+ *
+ * Note that this modifies arrTime and endTime of each activity in a route.
+ *
+ * @author stefan
+ *
+ */
+class UpdateActivityTimes implements ActivityVisitor, StateUpdater{
+
+ private Logger log = Logger.getLogger(UpdateActivityTimes.class);
+
+ private ActivityTimeTracker timeTracker;
+
+ private VehicleRoute route;
+
+ /**
+ * Updates arrival and end times of activities.
+ *
+ *
Note that this modifies arrTime and endTime of each activity in a route.
+ *
+ *
ArrTimes and EndTimes can be retrieved by
+ * activity.getArrTime() and
+ * activity.getEndTime()
+ *
+ * @author stefan
+ *
+ */
+ public UpdateActivityTimes(ForwardTransportTime transportTime) {
+ super();
+ timeTracker = new ActivityTimeTracker(transportTime);
+ }
+
+ @Override
+ public void begin(VehicleRoute route) {
+ timeTracker.begin(route);
+ this.route = route;
+ route.getStart().setEndTime(timeTracker.getActEndTime());
+ }
+
+ @Override
+ public void visit(TourActivity activity) {
+ timeTracker.visit(activity);
+ activity.setArrTime(timeTracker.getActArrTime());
+ activity.setEndTime(timeTracker.getActEndTime());
+ }
+
+ @Override
+ public void finish() {
+ timeTracker.finish();
+ route.getEnd().setArrTime(timeTracker.getActArrTime());
+ }
+
+}
\ No newline at end of file
diff --git a/jsprit-core/src/main/java/algorithms/UpdateCostsAtAllLevels.java b/jsprit-core/src/main/java/algorithms/UpdateCostsAtAllLevels.java
new file mode 100644
index 00000000..a9e57c0a
--- /dev/null
+++ b/jsprit-core/src/main/java/algorithms/UpdateCostsAtAllLevels.java
@@ -0,0 +1,126 @@
+package algorithms;
+
+import org.apache.log4j.Logger;
+
+import util.ActivityTimeTracker;
+
+import algorithms.StateManager.StateImpl;
+import basics.costs.ForwardTransportCost;
+import basics.costs.VehicleRoutingActivityCosts;
+import basics.costs.VehicleRoutingTransportCosts;
+import basics.route.ActivityVisitor;
+import basics.route.TourActivity;
+import basics.route.Vehicle;
+import basics.route.VehicleRoute;
+
+/**
+ * Updates total costs (i.e. transport and activity costs) at route and activity level.
+ *
+ *
Thus it modifies stateManager.getRouteState(route, StateTypes.COSTS) and
+ * stateManager.getActivityState(activity, StateTypes.COSTS)
+ *
+ *
+ * @param activityCost
+ * @param transportCost
+ * @param states
+ */
+class UpdateCostsAtAllLevels implements ActivityVisitor,StateUpdater{
+
+ private static Logger log = Logger.getLogger(UpdateCostsAtAllLevels.class);
+
+ private VehicleRoutingActivityCosts activityCost;
+
+ private ForwardTransportCost transportCost;
+
+ private StateManager states;
+
+ private double totalOperationCost = 0.0;
+
+ private VehicleRoute vehicleRoute = null;
+
+ private TourActivity prevAct = null;
+
+ private double startTimeAtPrevAct = 0.0;
+
+ private ActivityTimeTracker timeTracker;
+
+ /**
+ * Updates total costs (i.e. transport and activity costs) at route and activity level.
+ *
+ *
Thus it modifies stateManager.getRouteState(route, StateTypes.COSTS) and
+ * stateManager.getActivityState(activity, StateTypes.COSTS)
+ *
+ *
+ * @param activityCost
+ * @param transportCost
+ * @param states
+ */
+ public UpdateCostsAtAllLevels(VehicleRoutingActivityCosts activityCost, VehicleRoutingTransportCosts transportCost, StateManager states) {
+ super();
+ this.activityCost = activityCost;
+ this.transportCost = transportCost;
+ this.states = states;
+ timeTracker = new ActivityTimeTracker(transportCost);
+ }
+
+ @Override
+ public void begin(VehicleRoute route) {
+ vehicleRoute = route;
+ vehicleRoute.getVehicleRouteCostCalculator().reset();
+ timeTracker.begin(route);
+ prevAct = route.getStart();
+ startTimeAtPrevAct = timeTracker.getActEndTime();
+ }
+
+ @Override
+ public void visit(TourActivity act) {
+ timeTracker.visit(act);
+
+ double transportCost = this.transportCost.getTransportCost(prevAct.getLocationId(), act.getLocationId(), startTimeAtPrevAct, vehicleRoute.getDriver(), vehicleRoute.getVehicle());
+ double actCost = activityCost.getActivityCost(act, timeTracker.getActArrTime(), vehicleRoute.getDriver(), vehicleRoute.getVehicle());
+
+ vehicleRoute.getVehicleRouteCostCalculator().addTransportCost(transportCost);
+ vehicleRoute.getVehicleRouteCostCalculator().addActivityCost(actCost);
+
+ totalOperationCost += transportCost;
+ totalOperationCost += actCost;
+
+ states.putActivityState(act, StateFactory.COSTS, new StateImpl(totalOperationCost));
+
+ prevAct = act;
+ startTimeAtPrevAct = timeTracker.getActEndTime();
+ }
+
+ @Override
+ public void finish() {
+ timeTracker.finish();
+ double transportCost = this.transportCost.getTransportCost(prevAct.getLocationId(), vehicleRoute.getEnd().getLocationId(), startTimeAtPrevAct, vehicleRoute.getDriver(), vehicleRoute.getVehicle());
+ double actCost = activityCost.getActivityCost(vehicleRoute.getEnd(), timeTracker.getActEndTime(), vehicleRoute.getDriver(), vehicleRoute.getVehicle());
+
+ vehicleRoute.getVehicleRouteCostCalculator().addTransportCost(transportCost);
+ vehicleRoute.getVehicleRouteCostCalculator().addActivityCost(actCost);
+
+ totalOperationCost += transportCost;
+ totalOperationCost += actCost;
+// totalOperationCost += getFixCosts(vehicleRoute.getVehicle());
+
+ states.putRouteState(vehicleRoute, StateFactory.COSTS, new StateImpl(totalOperationCost));
+
+ //this is rather strange and likely to change
+ vehicleRoute.getVehicleRouteCostCalculator().price(vehicleRoute.getDriver());
+ vehicleRoute.getVehicleRouteCostCalculator().price(vehicleRoute.getVehicle());
+ vehicleRoute.getVehicleRouteCostCalculator().finish();
+
+ startTimeAtPrevAct = 0.0;
+ prevAct = null;
+ vehicleRoute = null;
+ totalOperationCost = 0.0;
+ }
+
+ private double getFixCosts(Vehicle vehicle) {
+ if(vehicle == null) return 0.0;
+ if(vehicle.getType() == null) return 0.0;
+ return vehicle.getType().getVehicleCostParams().fix;
+ }
+
+}
\ No newline at end of file
diff --git a/jsprit-core/src/main/java/algorithms/UpdateCostsAtRouteLevel.java b/jsprit-core/src/main/java/algorithms/UpdateCostsAtRouteLevel.java
new file mode 100644
index 00000000..5f6392a9
--- /dev/null
+++ b/jsprit-core/src/main/java/algorithms/UpdateCostsAtRouteLevel.java
@@ -0,0 +1,63 @@
+package algorithms;
+
+import java.util.Collection;
+
+import algorithms.StateManager.StateImpl;
+import basics.Job;
+import basics.algo.InsertionEndsListener;
+import basics.algo.InsertionStartsListener;
+import basics.algo.JobInsertedListener;
+import basics.costs.VehicleRoutingActivityCosts;
+import basics.costs.VehicleRoutingTransportCosts;
+import basics.route.RouteActivityVisitor;
+import basics.route.VehicleRoute;
+
+class UpdateCostsAtRouteLevel implements StateUpdater,JobInsertedListener, InsertionStartsListener, InsertionEndsListener{
+
+ private StateManager states;
+
+ private VehicleRoutingTransportCosts tpCosts;
+
+ private VehicleRoutingActivityCosts actCosts;
+
+ public UpdateCostsAtRouteLevel(StateManager states, VehicleRoutingTransportCosts tpCosts, VehicleRoutingActivityCosts actCosts) {
+ super();
+ this.states = states;
+ this.tpCosts = tpCosts;
+ this.actCosts = actCosts;
+ }
+
+ @Override
+ public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) {
+// inRoute.getVehicleRouteCostCalculator().addTransportCost(additionalCosts);
+ double oldCosts = states.getRouteState(inRoute, StateFactory.COSTS).toDouble();
+ oldCosts += additionalCosts;
+ states.putRouteState(inRoute, StateFactory.COSTS, new StateImpl(oldCosts));
+ }
+
+ @Override
+ public void informInsertionStarts(Collection vehicleRoutes, Collection unassignedJobs) {
+ RouteActivityVisitor forwardInTime = new RouteActivityVisitor();
+ forwardInTime.addActivityVisitor(new UpdateCostsAtAllLevels(actCosts, tpCosts, states));
+ for(VehicleRoute route : vehicleRoutes){
+ forwardInTime.visit(route);
+ }
+
+ }
+
+ @Override
+ public void informInsertionEnds(Collection vehicleRoutes) {
+
+// IterateRouteForwardInTime forwardInTime = new IterateRouteForwardInTime(tpCosts);
+// forwardInTime.addListener(new UpdateCostsAtAllLevels(actCosts, tpCosts, states));
+ for(VehicleRoute route : vehicleRoutes){
+ if(route.isEmpty()) continue;
+ route.getVehicleRouteCostCalculator().reset();
+ route.getVehicleRouteCostCalculator().addOtherCost(states.getRouteState(route, StateFactory.COSTS).toDouble());
+ route.getVehicleRouteCostCalculator().price(route.getVehicle());
+// forwardInTime.iterate(route);
+ }
+
+ }
+
+ }
\ No newline at end of file
diff --git a/jsprit-core/src/main/java/algorithms/UpdateEarliestStartTimeWindowAtActLocations.java b/jsprit-core/src/main/java/algorithms/UpdateEarliestStartTimeWindowAtActLocations.java
new file mode 100644
index 00000000..56c790dd
--- /dev/null
+++ b/jsprit-core/src/main/java/algorithms/UpdateEarliestStartTimeWindowAtActLocations.java
@@ -0,0 +1,37 @@
+package algorithms;
+
+import util.ActivityTimeTracker;
+import algorithms.StateManager.StateImpl;
+import basics.costs.VehicleRoutingTransportCosts;
+import basics.route.ActivityVisitor;
+import basics.route.TourActivity;
+import basics.route.VehicleRoute;
+
+class UpdateEarliestStartTimeWindowAtActLocations implements ActivityVisitor,StateUpdater{
+
+ private StateManager states;
+
+ private ActivityTimeTracker timeTracker;
+
+ public UpdateEarliestStartTimeWindowAtActLocations(StateManager states, VehicleRoutingTransportCosts transportCosts) {
+ super();
+ this.states = states;
+ timeTracker = new ActivityTimeTracker(transportCosts);
+ }
+
+ @Override
+ public void begin(VehicleRoute route) {
+ timeTracker.begin(route);
+ }
+
+ @Override
+ public void visit(TourActivity activity) {
+ timeTracker.visit(activity);
+ states.putActivityState(activity, StateFactory.EARLIEST_OPERATION_START_TIME, new StateImpl(Math.max(timeTracker.getActArrTime(), activity.getTheoreticalEarliestOperationStartTime())));
+
+ }
+
+ @Override
+ public void finish() {}
+
+}
\ No newline at end of file
diff --git a/jsprit-core/src/main/java/algorithms/UpdateFuturePickupsAtActivityLevel.java b/jsprit-core/src/main/java/algorithms/UpdateFuturePickupsAtActivityLevel.java
new file mode 100644
index 00000000..3e402e20
--- /dev/null
+++ b/jsprit-core/src/main/java/algorithms/UpdateFuturePickupsAtActivityLevel.java
@@ -0,0 +1,39 @@
+package algorithms;
+
+import basics.route.PickupActivity;
+import basics.route.ReverseActivityVisitor;
+import basics.route.ServiceActivity;
+import basics.route.TourActivity;
+import basics.route.VehicleRoute;
+
+class UpdateFuturePickupsAtActivityLevel implements ReverseActivityVisitor, StateUpdater {
+ private StateManager stateManager;
+ private int futurePicks = 0;
+ private VehicleRoute route;
+
+ public UpdateFuturePickupsAtActivityLevel(StateManager stateManager) {
+ super();
+ this.stateManager = stateManager;
+ }
+
+ @Override
+ public void begin(VehicleRoute route) {
+ this.route = route;
+ }
+
+ @Override
+ public void visit(TourActivity act) {
+ stateManager.putActivityState(act, StateFactory.FUTURE_PICKS, StateFactory.createState(futurePicks));
+ if(act instanceof PickupActivity || act instanceof ServiceActivity){
+ futurePicks += act.getCapacityDemand();
+ }
+ assert futurePicks <= route.getVehicle().getCapacity() : "sum of pickups must not be > vehicleCap";
+ assert futurePicks >= 0 : "sum of pickups must not < 0";
+ }
+
+ @Override
+ public void finish() {
+ futurePicks = 0;
+ route = null;
+ }
+}
\ No newline at end of file
diff --git a/jsprit-core/src/main/java/algorithms/UpdateLatestOperationStartTimeAtActLocations.java b/jsprit-core/src/main/java/algorithms/UpdateLatestOperationStartTimeAtActLocations.java
new file mode 100644
index 00000000..3e1c0d01
--- /dev/null
+++ b/jsprit-core/src/main/java/algorithms/UpdateLatestOperationStartTimeAtActLocations.java
@@ -0,0 +1,51 @@
+package algorithms;
+
+import org.apache.log4j.Logger;
+
+import algorithms.StateManager.StateImpl;
+import basics.costs.VehicleRoutingTransportCosts;
+import basics.route.ReverseActivityVisitor;
+import basics.route.TourActivity;
+import basics.route.VehicleRoute;
+
+class UpdateLatestOperationStartTimeAtActLocations implements ReverseActivityVisitor, StateUpdater{
+
+ private static Logger log = Logger.getLogger(UpdateLatestOperationStartTimeAtActLocations.class);
+
+ private StateManager states;
+
+ private VehicleRoute route;
+
+ private VehicleRoutingTransportCosts transportCosts;
+
+ private double latestArrTimeAtPrevAct;
+
+ private TourActivity prevAct;
+
+ public UpdateLatestOperationStartTimeAtActLocations(StateManager states, VehicleRoutingTransportCosts tpCosts) {
+ super();
+ this.states = states;
+ this.transportCosts = tpCosts;
+ }
+
+ @Override
+ public void begin(VehicleRoute route) {
+ this.route = route;
+ latestArrTimeAtPrevAct = route.getEnd().getTheoreticalLatestOperationStartTime();
+ prevAct = route.getEnd();
+ }
+
+ @Override
+ public void visit(TourActivity activity) {
+ double potentialLatestArrivalTimeAtCurrAct = latestArrTimeAtPrevAct - transportCosts.getBackwardTransportTime(activity.getLocationId(), prevAct.getLocationId(), latestArrTimeAtPrevAct, route.getDriver(),route.getVehicle()) - activity.getOperationTime();
+ double latestArrivalTime = Math.min(activity.getTheoreticalLatestOperationStartTime(), potentialLatestArrivalTimeAtCurrAct);
+
+ states.putActivityState(activity, StateFactory.LATEST_OPERATION_START_TIME, new StateImpl(latestArrivalTime));
+
+ latestArrTimeAtPrevAct = latestArrivalTime;
+ prevAct = activity;
+ }
+
+ @Override
+ public void finish() {}
+}
\ No newline at end of file
diff --git a/jsprit-core/src/main/java/algorithms/UpdateLoadAtActivityLevel.java b/jsprit-core/src/main/java/algorithms/UpdateLoadAtActivityLevel.java
new file mode 100644
index 00000000..73f9fb76
--- /dev/null
+++ b/jsprit-core/src/main/java/algorithms/UpdateLoadAtActivityLevel.java
@@ -0,0 +1,67 @@
+package algorithms;
+
+import algorithms.StateManager.StateImpl;
+import basics.route.ActivityVisitor;
+import basics.route.TourActivity;
+import basics.route.VehicleRoute;
+
+/**
+ * Updates load at activity level.
+ *
+ * Note that this assumes that StateTypes.LOAD_AT_DEPOT is already updated, i.e. it starts by setting loadAtDepot to StateTypes.LOAD_AT_DEPOT.
+ * If StateTypes.LOAD_AT_DEPOT is not set, it starts with 0 load at depot.
+ *
+ *
Thus it DEPENDS on StateTypes.LOAD_AT_DEPOT
+ *
+ * @author stefan
+ *
+ */
+class UpdateLoadAtActivityLevel implements ActivityVisitor, StateUpdater {
+ private StateManager stateManager;
+ private int currentLoad = 0;
+ private VehicleRoute route;
+
+ /**
+ * Updates load at activity level.
+ *
+ *
Note that this assumes that StateTypes.LOAD_AT_DEPOT is already updated, i.e. it starts by setting loadAtDepot to StateTypes.LOAD_AT_DEPOT.
+ * If StateTypes.LOAD_AT_DEPOT is not set, it starts with 0 load at depot.
+ *
+ *
Thus it DEPENDS on StateTypes.LOAD_AT_DEPOT
+ *
+ *
If you want to update StateTypes.LOAD_AT_DEPOT see {@link UpdateLoadsAtStartAndEndOfRouteWhenInsertionStarts}, {@link UpdateLoadsAtStartAndEndOfRouteWhenJobHasBeenInserted}
+ *
+ *
The loads can be retrieved by
+ * stateManager.getActivityState(activity,StateTypes.LOAD);
+ *
+ *
+ *
+ * @see {@link UpdateLoadsAtStartAndEndOfRouteWhenInsertionStarts}, {@link UpdateLoadsAtStartAndEndOfRouteWhenJobHasBeenInserted}
+ * @author stefan
+ *
+ */
+ public UpdateLoadAtActivityLevel(StateManager stateManager) {
+ super();
+ this.stateManager = stateManager;
+ }
+
+ @Override
+ public void begin(VehicleRoute route) {
+ currentLoad = (int) stateManager.getRouteState(route, StateFactory.LOAD_AT_BEGINNING).toDouble();
+ this.route = route;
+ }
+
+ @Override
+ public void visit(TourActivity act) {
+ currentLoad += act.getCapacityDemand();
+ stateManager.putActivityState(act, StateFactory.LOAD, StateFactory.createState(currentLoad));
+ assert currentLoad <= route.getVehicle().getCapacity() : "currentLoad at activity must not be > vehicleCapacity";
+ assert currentLoad >= 0 : "currentLoad at act must not be < 0";
+ }
+
+ @Override
+ public void finish() {
+// stateManager.putRouteState(route, StateFactory., state)
+ currentLoad = 0;
+ }
+}
\ No newline at end of file
diff --git a/jsprit-core/src/main/java/algorithms/UpdateLoadAtAllLevels.java b/jsprit-core/src/main/java/algorithms/UpdateLoadAtAllLevels.java
new file mode 100644
index 00000000..d38b3cb2
--- /dev/null
+++ b/jsprit-core/src/main/java/algorithms/UpdateLoadAtAllLevels.java
@@ -0,0 +1,39 @@
+package algorithms;
+
+import algorithms.StateManager.StateImpl;
+import basics.route.ActivityVisitor;
+import basics.route.TourActivity;
+import basics.route.VehicleRoute;
+
+class UpdateLoadAtAllLevels implements ActivityVisitor,StateUpdater{
+
+ private double load = 0.0;
+
+ private StateManager states;
+
+ private VehicleRoute vehicleRoute;
+
+ public UpdateLoadAtAllLevels(StateManager states) {
+ super();
+ this.states = states;
+ }
+
+ @Override
+ public void begin(VehicleRoute route) {
+ vehicleRoute = route;
+ }
+
+ @Override
+ public void visit(TourActivity activity) {
+ load += (double)activity.getCapacityDemand();
+ states.putActivityState(activity, StateFactory.LOAD, new StateImpl(load));
+ }
+
+ @Override
+ public void finish() {
+ states.putRouteState(vehicleRoute, StateFactory.LOAD, new StateImpl(load));
+ load=0;
+ vehicleRoute = null;
+ }
+
+}
\ No newline at end of file
diff --git a/jsprit-core/src/main/java/algorithms/UpdateLoadAtRouteLevel.java b/jsprit-core/src/main/java/algorithms/UpdateLoadAtRouteLevel.java
new file mode 100644
index 00000000..a80130af
--- /dev/null
+++ b/jsprit-core/src/main/java/algorithms/UpdateLoadAtRouteLevel.java
@@ -0,0 +1,54 @@
+package algorithms;
+
+import java.util.Collection;
+
+import algorithms.StateManager.StateImpl;
+import basics.Job;
+import basics.Service;
+import basics.algo.InsertionStartsListener;
+import basics.algo.JobInsertedListener;
+import basics.route.VehicleRoute;
+
+/**
+ * Updates load at route level, i.e. modifies StateTypes.LOAD for each route.
+ *
+ * @author stefan
+ *
+ */
+class UpdateLoadAtRouteLevel implements JobInsertedListener, InsertionStartsListener, StateUpdater{
+
+ private StateManager states;
+
+ /**
+ * Updates load at route level, i.e. modifies StateTypes.LOAD for each route.
+ *
+ * @author stefan
+ *
+ */
+ public UpdateLoadAtRouteLevel(StateManager states) {
+ super();
+ this.states = states;
+ }
+
+ @Override
+ public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) {
+ if(!(job2insert instanceof Service)){
+ return;
+ }
+ double oldLoad = states.getRouteState(inRoute, StateFactory.LOAD).toDouble();
+ states.putRouteState(inRoute, StateFactory.LOAD, StateFactory.createState(oldLoad + job2insert.getCapacityDemand()));
+ }
+
+ @Override
+ public void informInsertionStarts(Collection vehicleRoutes, Collection unassignedJobs) {
+ for(VehicleRoute route : vehicleRoutes){
+ int load = 0;
+ for(Job j : route.getTourActivities().getJobs()){
+ load += j.getCapacityDemand();
+ }
+ states.putRouteState(route, StateFactory.LOAD, new StateImpl(load));
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/jsprit-core/src/main/java/algorithms/UpdateLoadsAtStartAndEndOfRouteWhenInsertionStarts.java b/jsprit-core/src/main/java/algorithms/UpdateLoadsAtStartAndEndOfRouteWhenInsertionStarts.java
new file mode 100644
index 00000000..8b652430
--- /dev/null
+++ b/jsprit-core/src/main/java/algorithms/UpdateLoadsAtStartAndEndOfRouteWhenInsertionStarts.java
@@ -0,0 +1,62 @@
+package algorithms;
+
+import java.util.Collection;
+
+import algorithms.StateManager.StateImpl;
+import basics.Delivery;
+import basics.Job;
+import basics.Pickup;
+import basics.Service;
+import basics.algo.InsertionStartsListener;
+import basics.route.VehicleRoute;
+
+/**
+ * Initializes the load of each route/vehicle at start- and end-location before insertion starts.
+ *
+ * StateTypes.LOAD_AT_DEPOT and StateTypes.LOAD are modified for each route
+ *
These states can be retrieved by
+ * stateManager.getRouteState(route, StateTypes.LOAD_AT_DEPOT) for LOAD_AT_DEPOT and
+ * stateManager.getRouteState(route, StateTypes.LOAD) for LOAD (i.e. load at end)
+ *
+ * @param stateManager
+ */
+class UpdateLoadsAtStartAndEndOfRouteWhenInsertionStarts implements InsertionStartsListener {
+
+ private StateManager stateManager;
+
+ /**
+ * Initializes the load of each route/vehicle at start- and end-location before insertion starts.
+ *
+ *
StateTypes.LOAD_AT_DEPOT and StateTypes.LOAD are modified for each route
+ *
These states can be retrieved by
+ * stateManager.getRouteState(route, StateTypes.LOAD_AT_DEPOT) for LOAD_AT_DEPOT and
+ * stateManager.getRouteState(route, StateTypes.LOAD) for LOAD (i.e. load at end)
+ *
+ * @param stateManager
+ */
+ public UpdateLoadsAtStartAndEndOfRouteWhenInsertionStarts(StateManager stateManager) {
+ super();
+ this.stateManager = stateManager;
+ }
+
+ void insertionStarts(VehicleRoute route) {
+ int loadAtDepot = 0;
+ int loadAtEnd = 0;
+ for(Job j : route.getTourActivities().getJobs()){
+ if(j instanceof Delivery){
+ loadAtDepot += j.getCapacityDemand();
+ }
+ else if(j instanceof Pickup || j instanceof Service){
+ loadAtEnd += j.getCapacityDemand();
+ }
+ }
+ stateManager.putRouteState(route, StateFactory.LOAD_AT_BEGINNING, StateFactory.createState(loadAtDepot));
+ stateManager.putRouteState(route, StateFactory.LOAD_AT_END, StateFactory.createState(loadAtEnd));
+ }
+
+ @Override
+ public void informInsertionStarts(Collection vehicleRoutes, Collection unassignedJobs) {
+ for(VehicleRoute route : vehicleRoutes){ insertionStarts(route); }
+ }
+
+}
\ No newline at end of file
diff --git a/jsprit-core/src/main/java/algorithms/UpdateLoadsAtStartAndEndOfRouteWhenJobHasBeenInserted.java b/jsprit-core/src/main/java/algorithms/UpdateLoadsAtStartAndEndOfRouteWhenJobHasBeenInserted.java
new file mode 100644
index 00000000..e73fa7b2
--- /dev/null
+++ b/jsprit-core/src/main/java/algorithms/UpdateLoadsAtStartAndEndOfRouteWhenJobHasBeenInserted.java
@@ -0,0 +1,52 @@
+package algorithms;
+
+import algorithms.StateManager.StateImpl;
+import basics.Delivery;
+import basics.Job;
+import basics.Pickup;
+import basics.Service;
+import basics.algo.JobInsertedListener;
+import basics.route.VehicleRoute;
+
+/**
+ * Updates loads at start and end of a route if a job has been inserted in that route.
+ *
+ * These states can be retrieved by
+ * stateManager.getRouteState(route, StateTypes.LOAD_AT_DEPOT) for LOAD_AT_DEPOT and
+ * stateManager.getRouteState(route, StateTypes.LOAD) for LOAD (i.e. load at end)
+ *
+ * @param stateManager
+ */
+class UpdateLoadsAtStartAndEndOfRouteWhenJobHasBeenInserted implements JobInsertedListener, StateUpdater {
+
+ private StateManager stateManager;
+
+ /**
+ * Updates loads at start and end of a route if a job has been inserted in that route.
+ *
+ *
These states can be retrieved by
+ * stateManager.getRouteState(route, StateTypes.LOAD_AT_DEPOT) for LOAD_AT_DEPOT and
+ * stateManager.getRouteState(route, StateTypes.LOAD) for LOAD (i.e. load at end)
+ *
+ * @param stateManager
+ */
+ public UpdateLoadsAtStartAndEndOfRouteWhenJobHasBeenInserted(StateManager stateManager) {
+ super();
+ this.stateManager = stateManager;
+ }
+
+ @Override
+ public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) {
+ if(job2insert instanceof Delivery){
+ int loadAtDepot = (int) stateManager.getRouteState(inRoute, StateFactory.LOAD_AT_BEGINNING).toDouble();
+// log.info("loadAtDepot="+loadAtDepot);
+ stateManager.putRouteState(inRoute, StateFactory.LOAD_AT_BEGINNING, StateFactory.createState(loadAtDepot + job2insert.getCapacityDemand()));
+ }
+ else if(job2insert instanceof Pickup || job2insert instanceof Service){
+ int loadAtEnd = (int) stateManager.getRouteState(inRoute, StateFactory.LOAD_AT_END).toDouble();
+// log.info("loadAtEnd="+loadAtEnd);
+ stateManager.putRouteState(inRoute, StateFactory.LOAD_AT_END, StateFactory.createState(loadAtEnd + job2insert.getCapacityDemand()));
+ }
+ }
+
+ }
\ No newline at end of file
diff --git a/jsprit-core/src/main/java/algorithms/UpdateMaxLoad.java b/jsprit-core/src/main/java/algorithms/UpdateMaxLoad.java
new file mode 100644
index 00000000..9975ae8f
--- /dev/null
+++ b/jsprit-core/src/main/java/algorithms/UpdateMaxLoad.java
@@ -0,0 +1,69 @@
+package algorithms;
+
+import basics.route.ActivityVisitor;
+import basics.route.TourActivity;
+import basics.route.VehicleRoute;
+
+/**
+ * Updates load at activity level.
+ *
+ *
Note that this assumes that StateTypes.LOAD_AT_DEPOT is already updated, i.e. it starts by setting loadAtDepot to StateTypes.LOAD_AT_DEPOT.
+ * If StateTypes.LOAD_AT_DEPOT is not set, it starts with 0 load at depot.
+ *
+ *
Thus it DEPENDS on StateTypes.LOAD_AT_DEPOT
+ *
+ * @author stefan
+ *
+ */
+class UpdateMaxLoad implements ActivityVisitor, StateUpdater {
+ private StateManager stateManager;
+ private int currentLoad = 0;
+ private VehicleRoute route;
+ private int maxLoad = 0;
+
+ /**
+ * Updates load at activity level.
+ *
+ *
Note that this assumes that StateTypes.LOAD_AT_DEPOT is already updated, i.e. it starts by setting loadAtDepot to StateTypes.LOAD_AT_DEPOT.
+ * If StateTypes.LOAD_AT_DEPOT is not set, it starts with 0 load at depot.
+ *
+ *
Thus it DEPENDS on StateTypes.LOAD_AT_DEPOT
+ *
+ *
If you want to update StateTypes.LOAD_AT_DEPOT see {@link UpdateLoadsAtStartAndEndOfRouteWhenInsertionStarts}, {@link UpdateLoadsAtStartAndEndOfRouteWhenJobHasBeenInserted}
+ *
+ *
The loads can be retrieved by
+ * stateManager.getActivityState(activity,StateTypes.LOAD);
+ *
+ *
+ *
+ * @see {@link UpdateLoadsAtStartAndEndOfRouteWhenInsertionStarts}, {@link UpdateLoadsAtStartAndEndOfRouteWhenJobHasBeenInserted}
+ * @author stefan
+ *
+ */
+ public UpdateMaxLoad(StateManager stateManager) {
+ super();
+ this.stateManager = stateManager;
+ }
+
+ @Override
+ public void begin(VehicleRoute route) {
+ currentLoad = (int) stateManager.getRouteState(route, StateFactory.LOAD_AT_BEGINNING).toDouble();
+ maxLoad = currentLoad;
+ this.route = route;
+ }
+
+ @Override
+ public void visit(TourActivity act) {
+ currentLoad += act.getCapacityDemand();
+ maxLoad = Math.max(maxLoad, currentLoad);
+ assert currentLoad <= route.getVehicle().getCapacity() : "currentLoad at activity must not be > vehicleCapacity";
+ assert currentLoad >= 0 : "currentLoad at act must not be < 0";
+ }
+
+ @Override
+ public void finish() {
+ stateManager.putRouteState(route, StateFactory.MAXLOAD, StateFactory.createState(maxLoad));
+ currentLoad = 0;
+ maxLoad = 0;
+ }
+}
\ No newline at end of file
diff --git a/jsprit-core/src/main/java/algorithms/UpdateOccuredDeliveriesAtActivityLevel.java b/jsprit-core/src/main/java/algorithms/UpdateOccuredDeliveriesAtActivityLevel.java
new file mode 100644
index 00000000..8e58a0c8
--- /dev/null
+++ b/jsprit-core/src/main/java/algorithms/UpdateOccuredDeliveriesAtActivityLevel.java
@@ -0,0 +1,39 @@
+package algorithms;
+
+import algorithms.StateManager.StateImpl;
+import basics.route.ActivityVisitor;
+import basics.route.DeliveryActivity;
+import basics.route.TourActivity;
+import basics.route.VehicleRoute;
+
+class UpdateOccuredDeliveriesAtActivityLevel implements ActivityVisitor, StateUpdater {
+ private StateManager stateManager;
+ private int deliveries = 0;
+ private VehicleRoute route;
+
+ public UpdateOccuredDeliveriesAtActivityLevel(StateManager stateManager) {
+ super();
+ this.stateManager = stateManager;
+ }
+
+ @Override
+ public void begin(VehicleRoute route) {
+ this.route = route;
+ }
+
+ @Override
+ public void visit(TourActivity act) {
+ if(act instanceof DeliveryActivity){
+ deliveries += Math.abs(act.getCapacityDemand());
+ }
+ stateManager.putActivityState(act, StateFactory.PAST_DELIVERIES, StateFactory.createState(deliveries));
+ assert deliveries >= 0 : "deliveries < 0";
+ assert deliveries <= route.getVehicle().getCapacity() : "deliveries > vehicleCap";
+ }
+
+ @Override
+ public void finish() {
+ deliveries = 0;
+ route = null;
+ }
+}
\ No newline at end of file
diff --git a/jsprit-core/src/main/java/algorithms/VariablePlusFixedSolutionCostCalculatorFactory.java b/jsprit-core/src/main/java/algorithms/VariablePlusFixedSolutionCostCalculatorFactory.java
new file mode 100644
index 00000000..b24a5df9
--- /dev/null
+++ b/jsprit-core/src/main/java/algorithms/VariablePlusFixedSolutionCostCalculatorFactory.java
@@ -0,0 +1,31 @@
+package algorithms;
+
+import basics.VehicleRoutingProblemSolution;
+import basics.algo.SolutionCostCalculator;
+import basics.route.VehicleRoute;
+
+public class VariablePlusFixedSolutionCostCalculatorFactory {
+
+ private StateManager stateManager;
+
+ public VariablePlusFixedSolutionCostCalculatorFactory(StateManager stateManager) {
+ super();
+ this.stateManager = stateManager;
+ }
+
+ public SolutionCostCalculator createCalculator(){
+ return new SolutionCostCalculator() {
+
+ @Override
+ public double getCosts(VehicleRoutingProblemSolution solution) {
+ double c = 0.0;
+ for(VehicleRoute r : solution.getRoutes()){
+ c += stateManager.getRouteState(r, StateFactory.COSTS).toDouble();
+ c += r.getVehicle().getType().getVehicleCostParams().fix;
+ }
+ return c;
+ }
+ };
+ }
+
+}
diff --git a/jsprit-core/src/main/java/algorithms/VehicleFleetManager.java b/jsprit-core/src/main/java/algorithms/VehicleFleetManager.java
deleted file mode 100644
index d0467077..00000000
--- a/jsprit-core/src/main/java/algorithms/VehicleFleetManager.java
+++ /dev/null
@@ -1,84 +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 .
- ******************************************************************************/
-package algorithms;
-
-import java.util.Collection;
-
-import basics.route.Vehicle;
-
-interface VehicleFleetManager {
-
- static class TypeKey {
-
- public final String type;
- public final String locationId;
-
- public TypeKey(String typeId, String locationId) {
- super();
- this.type = typeId;
- this.locationId = locationId;
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result
- + ((locationId == null) ? 0 : locationId.hashCode());
- result = prime * result + ((type == null) ? 0 : type.hashCode());
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- TypeKey other = (TypeKey) obj;
- if (locationId == null) {
- if (other.locationId != null)
- return false;
- } else if (!locationId.equals(other.locationId))
- return false;
- if (type == null) {
- if (other.type != null)
- return false;
- } else if (!type.equals(other.type))
- return false;
- return true;
- }
-
-
-
- }
-
- abstract void lock(Vehicle vehicle);
-
- abstract void unlock(Vehicle vehicle);
-
- abstract boolean isLocked(Vehicle vehicle);
-
- abstract void unlockAll();
-
- abstract Collection getAvailableVehicles();
-
- Collection getAvailableVehicles(String withoutThisType, String locationId);
-
-}
diff --git a/jsprit-core/src/main/java/algorithms/VehicleRoutingAlgorithmBuilder.java b/jsprit-core/src/main/java/algorithms/VehicleRoutingAlgorithmBuilder.java
new file mode 100644
index 00000000..57800da8
--- /dev/null
+++ b/jsprit-core/src/main/java/algorithms/VehicleRoutingAlgorithmBuilder.java
@@ -0,0 +1,44 @@
+package algorithms;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import basics.VehicleRoutingAlgorithm;
+import basics.VehicleRoutingProblem;
+import basics.algo.SearchStrategyManager;
+import basics.algo.VehicleRoutingAlgorithmListener;
+import basics.route.VehicleFleetManager;
+
+public class VehicleRoutingAlgorithmBuilder {
+
+ private VehicleRoutingProblem vrp;
+
+ private SearchStrategyManager searchStrategyManager;
+
+ private StateManager stateManager;
+
+ private Collection listeners = new ArrayList();
+
+ private VehicleFleetManager fleetManager;
+
+ public VehicleRoutingAlgorithmBuilder(VehicleRoutingProblem vrp, SearchStrategyManager searchStrategyManager, StateManager stateManager, VehicleFleetManager vehicleFleetManager) {
+ super();
+ this.vrp = vrp;
+ this.searchStrategyManager = searchStrategyManager;
+ this.stateManager = stateManager;
+ this.fleetManager = vehicleFleetManager;
+ }
+
+ public void addListener(VehicleRoutingAlgorithmListener listener){
+ listeners.add(listener);
+ }
+
+ public VehicleRoutingAlgorithm build(){
+ VehicleRoutingAlgorithm algorithm = new VehicleRoutingAlgorithm(vrp, searchStrategyManager);
+ algorithm.getAlgorithmListeners().addListener(stateManager);
+ algorithm.getSearchStrategyManager().addSearchStrategyModuleListener(stateManager);
+ algorithm.getSearchStrategyManager().addSearchStrategyModuleListener(new RemoveEmptyVehicles(fleetManager));
+ return algorithm;
+ }
+
+}
diff --git a/jsprit-core/src/main/java/algorithms/VehicleRoutingAlgorithms.java b/jsprit-core/src/main/java/algorithms/VehicleRoutingAlgorithms.java
index 4cd33742..bd8e6db4 100644
--- a/jsprit-core/src/main/java/algorithms/VehicleRoutingAlgorithms.java
+++ b/jsprit-core/src/main/java/algorithms/VehicleRoutingAlgorithms.java
@@ -31,7 +31,6 @@ import org.apache.commons.configuration.HierarchicalConfiguration;
import org.apache.commons.configuration.XMLConfiguration;
import org.apache.log4j.Logger;
-import algorithms.HardConstraints.ConstraintManager;
import algorithms.VehicleRoutingAlgorithms.TypedMap.AbstractKey;
import algorithms.VehicleRoutingAlgorithms.TypedMap.AcceptorKey;
import algorithms.VehicleRoutingAlgorithms.TypedMap.InsertionStrategyKey;
@@ -65,7 +64,10 @@ import basics.algo.VehicleRoutingAlgorithmListeners.PrioritizedVRAListener;
import basics.algo.VehicleRoutingAlgorithmListeners.Priority;
import basics.io.AlgorithmConfig;
import basics.io.AlgorithmConfigXmlReader;
+import basics.route.FiniteFleetManagerFactory;
+import basics.route.InfiniteFleetManagerFactory;
import basics.route.Vehicle;
+import basics.route.VehicleFleetManager;
import basics.route.VehicleRoute;
@@ -437,23 +439,23 @@ public class VehicleRoutingAlgorithms {
final VehicleFleetManager vehicleFleetManager = createFleetManager(vrp);
//create state-manager
- final StateManagerImpl stateManager = new StateManagerImpl();
+ final StateManager stateManager = new StateManager();
/*
* define constraints
*/
//constraint manager
ConstraintManager constraintManager = new ConstraintManager();
- constraintManager.addConstraint(new HardConstraints.HardTimeWindowActivityLevelConstraint(stateManager, vrp.getTransportCosts()));
+ constraintManager.addConstraint(new HardTimeWindowActivityLevelConstraint(stateManager, vrp.getTransportCosts()));
if(vrp.getProblemConstraints().contains(Constraint.DELIVERIES_FIRST)){
- constraintManager.addConstraint(new HardConstraints.HardPickupAndDeliveryBackhaulActivityLevelConstraint(stateManager));
+ constraintManager.addConstraint(new HardPickupAndDeliveryBackhaulActivityLevelConstraint(stateManager));
}
else{
- constraintManager.addConstraint(new HardConstraints.HardPickupAndDeliveryActivityLevelConstraint(stateManager));
+ constraintManager.addConstraint(new HardPickupAndDeliveryActivityLevelConstraint(stateManager));
}
- constraintManager.addConstraint(new HardConstraints.HardPickupAndDeliveryLoadConstraint(stateManager));
+ constraintManager.addConstraint(new HardPickupAndDeliveryLoadRouteLevelConstraint(stateManager));
//construct initial solution creator
AlgorithmStartsListener createInitialSolution = createInitialSolution(config,vrp,vehicleFleetManager,stateManager,algorithmListeners,definedClasses,executorService,nuOfThreads,constraintManager);
@@ -491,24 +493,22 @@ public class VehicleRoutingAlgorithms {
* define stateUpdates
*/
- //reset stateManager
- algorithmListeners.add(new PrioritizedVRAListener(Priority.LOW, new StateUpdates.ResetStateManager(stateManager)));
- //update states
-// metaAlgorithm.getSearchStrategyManager().addSearchStrategyModuleListener(new UpdateStates(stateManager, vrp.getTransportCosts(), vrp.getActivityCosts()));
- StateUpdates.UpdateRouteStatesOnceTheRouteHasBeenChanged routeChangedListener = new StateUpdates.UpdateRouteStatesOnceTheRouteHasBeenChanged(vrp.getTransportCosts());
+ stateManager.addListener(new UpdateLoadsAtStartAndEndOfRouteWhenInsertionStarts(stateManager));
+ stateManager.addListener(new UpdateLoadsAtStartAndEndOfRouteWhenJobHasBeenInserted(stateManager));
+
+ stateManager.addActivityVisitor(new UpdateActivityTimes(vrp.getTransportCosts()));
+ stateManager.addActivityVisitor(new UpdateLoadAtActivityLevel(stateManager));
- routeChangedListener.addInsertionStartsListener(new StateUpdates.UpdateLoadsAtStartAndEndOfRouteWhenInsertionStarts(stateManager));
- routeChangedListener.addJobInsertedListener(new StateUpdates.UpdateLoadsAtStartAndEndOfRouteWhenJobHasBeenInserted(stateManager));
+ stateManager.addActivityVisitor(new UpdateCostsAtAllLevels(vrp.getActivityCosts(), vrp.getTransportCosts(), stateManager));
- routeChangedListener.addVisitor(new StateUpdates.UpdateActivityTimes(vrp.getTransportCosts()));
- routeChangedListener.addVisitor(new StateUpdates.UpdateLoadAtActivityLevel(stateManager));
- routeChangedListener.addVisitor(new StateUpdates.UpdateCostsAtAllLevels(vrp.getActivityCosts(), vrp.getTransportCosts(), stateManager));
+ stateManager.addActivityVisitor(new UpdateOccuredDeliveriesAtActivityLevel(stateManager));
+ stateManager.addActivityVisitor(new UpdateLatestOperationStartTimeAtActLocations(stateManager, vrp.getTransportCosts()));
+ stateManager.addActivityVisitor(new UpdateFuturePickupsAtActivityLevel(stateManager));
+
- routeChangedListener.addVisitor(new StateUpdates.UpdateOccuredDeliveriesAtActivityLevel(stateManager));
- routeChangedListener.addVisitor(new StateUpdates.UpdateLatestOperationStartTimeAtActLocations(stateManager, vrp.getTransportCosts()));
- routeChangedListener.addVisitor(new StateUpdates.UpdateFuturePickupsAtActivityLevel(stateManager));
+ metaAlgorithm.getSearchStrategyManager().addSearchStrategyModuleListener(stateManager);
+ metaAlgorithm.getAlgorithmListeners().addListener(stateManager);
- metaAlgorithm.getSearchStrategyManager().addSearchStrategyModuleListener(routeChangedListener);
metaAlgorithm.getSearchStrategyManager().addSearchStrategyModuleListener(new RemoveEmptyVehicles(vehicleFleetManager));
metaAlgorithm.getSearchStrategyManager().addSearchStrategyModuleListener(new ResetAndIniFleetManager(vehicleFleetManager));
metaAlgorithm.getSearchStrategyManager().addSearchStrategyModuleListener(new VehicleSwitched(vehicleFleetManager));
@@ -526,16 +526,16 @@ public class VehicleRoutingAlgorithms {
return metaAlgorithm;
}
- private static SolutionCostCalculator getCostCalculator(final StateManagerImpl stateManager) {
+ private static SolutionCostCalculator getCostCalculator(final StateManager stateManager) {
SolutionCostCalculator calc = new SolutionCostCalculator() {
@Override
- public void calculateCosts(VehicleRoutingProblemSolution solution) {
+ public double getCosts(VehicleRoutingProblemSolution solution) {
double costs = 0.0;
for(VehicleRoute route : solution.getRoutes()){
- costs += stateManager.getRouteState(route, StateTypes.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) {
@@ -549,11 +549,11 @@ public class VehicleRoutingAlgorithms {
private static VehicleFleetManager createFleetManager(final VehicleRoutingProblem vrp) {
if(vrp.getFleetSize().equals(FleetSize.INFINITE)){
- return new InfiniteVehicles(vrp.getVehicles());
+ return new InfiniteFleetManagerFactory(vrp.getVehicles()).createFleetManager();
}
else if(vrp.getFleetSize().equals(FleetSize.FINITE)){
- return new VehicleFleetManagerImpl(vrp.getVehicles());
+ return new FiniteFleetManagerFactory(vrp.getVehicles()).createFleetManager();
}
throw new IllegalStateException("fleet size can only be infinite or finite. " +
"makes sure your config file contains one of these options");
@@ -626,7 +626,7 @@ public class VehicleRoutingAlgorithms {
metaAlgorithm.getAlgorithmListeners().addAll(algorithmListeners);
}
- private static AlgorithmStartsListener createInitialSolution(XMLConfiguration config, final VehicleRoutingProblem vrp, VehicleFleetManager vehicleFleetManager, final StateManagerImpl routeStates, Set algorithmListeners, TypedMap definedClasses, ExecutorService executorService, int nuOfThreads, ConstraintManager constraintManager) {
+ private static AlgorithmStartsListener createInitialSolution(XMLConfiguration config, final VehicleRoutingProblem vrp, VehicleFleetManager vehicleFleetManager, final StateManager routeStates, Set algorithmListeners, TypedMap definedClasses, ExecutorService executorService, int nuOfThreads, ConstraintManager constraintManager) {
List modConfigs = config.configurationsAt("construction.insertion");
if(modConfigs == null) return null;
if(modConfigs.isEmpty()) return null;
@@ -651,9 +651,11 @@ public class VehicleRoutingAlgorithms {
@Override
public void informAlgorithmStarts(VehicleRoutingProblem problem, VehicleRoutingAlgorithm algorithm, Collection solutions) {
- CreateInitialSolution createInitialSolution = new CreateInitialSolution(finalInsertionStrategy, getCostCalculator(routeStates));
- createInitialSolution.setGenerateAsMuchAsRoutesAsVehiclesExist(false);
- VehicleRoutingProblemSolution vrpSol = createInitialSolution.createInitialSolution(vrp);
+ InsertionInitialSolutionFactory insertionInitialSolutionFactory = new InsertionInitialSolutionFactory(finalInsertionStrategy, getCostCalculator(routeStates));
+// CreateInitialSolution createInitialSolution = new CreateInitialSolution(finalInsertionStrategy, getCostCalculator(routeStates));
+//
+// createInitialSolution.setGenerateAsMuchAsRoutesAsVehiclesExist(false);
+ VehicleRoutingProblemSolution vrpSol = insertionInitialSolutionFactory.createSolution(vrp);
solutions.add(vrpSol);
}
};
@@ -721,7 +723,7 @@ public class VehicleRoutingAlgorithms {
}
private static SearchStrategyModule buildModule(HierarchicalConfiguration moduleConfig, final VehicleRoutingProblem vrp, VehicleFleetManager vehicleFleetManager,
- final StateManagerImpl routeStates, Set algorithmListeners, TypedMap definedClasses, ExecutorService executorService, int nuOfThreads, ConstraintManager constraintManager) {
+ final StateManager routeStates, Set algorithmListeners, TypedMap definedClasses, ExecutorService executorService, int nuOfThreads, ConstraintManager constraintManager) {
String moduleName = moduleConfig.getString("[@name]");
if(moduleName == null) throw new IllegalStateException("module(-name) is missing.");
String moduleId = moduleConfig.getString("[@id]");
@@ -823,7 +825,7 @@ public class VehicleRoutingAlgorithms {
"\n\tgendreauPostOpt");
}
- private static RuinStrategy getRadialRuin(final VehicleRoutingProblem vrp, final StateManagerImpl routeStates, TypedMap definedClasses, ModKey modKey, double shareToRuin, JobDistance jobDistance) {
+ private static RuinStrategy getRadialRuin(final VehicleRoutingProblem vrp, final StateManager routeStates, TypedMap definedClasses, ModKey modKey, double shareToRuin, JobDistance jobDistance) {
RuinStrategyKey stratKey = new RuinStrategyKey(modKey);
RuinStrategy ruin = definedClasses.get(stratKey);
if(ruin == null){
@@ -833,7 +835,7 @@ public class VehicleRoutingAlgorithms {
return ruin;
}
- private static RuinStrategy getRandomRuin(final VehicleRoutingProblem vrp, final StateManagerImpl routeStates, TypedMap definedClasses, ModKey modKey, double shareToRuin) {
+ private static RuinStrategy getRandomRuin(final VehicleRoutingProblem vrp, final StateManager routeStates, TypedMap definedClasses, ModKey modKey, double shareToRuin) {
RuinStrategyKey stratKey = new RuinStrategyKey(modKey);
RuinStrategy ruin = definedClasses.get(stratKey);
if(ruin == null){
@@ -843,10 +845,12 @@ public class VehicleRoutingAlgorithms {
return ruin;
}
- private static InsertionStrategy createInsertionStrategy(HierarchicalConfiguration moduleConfig, VehicleRoutingProblem vrp,VehicleFleetManager vehicleFleetManager, StateManagerImpl routeStates, List algorithmListeners, ExecutorService executorService, int nuOfThreads, ConstraintManager constraintManager) {
+ private static InsertionStrategy createInsertionStrategy(HierarchicalConfiguration moduleConfig, VehicleRoutingProblem vrp,VehicleFleetManager vehicleFleetManager, StateManager routeStates, List algorithmListeners, ExecutorService executorService, int nuOfThreads, ConstraintManager constraintManager) {
InsertionStrategy insertion = InsertionFactory.createInsertion(vrp, moduleConfig, vehicleFleetManager, routeStates, algorithmListeners, executorService, nuOfThreads, constraintManager);
return insertion;
}
+
+
}
diff --git a/jsprit-core/src/main/java/algorithms/VehicleSwitched.java b/jsprit-core/src/main/java/algorithms/VehicleSwitched.java
index 4983a4a0..a9aa86bd 100644
--- a/jsprit-core/src/main/java/algorithms/VehicleSwitched.java
+++ b/jsprit-core/src/main/java/algorithms/VehicleSwitched.java
@@ -17,6 +17,7 @@
package algorithms;
import basics.route.Vehicle;
+import basics.route.VehicleFleetManager;
import basics.route.VehicleRoute;
diff --git a/jsprit-core/src/main/java/algorithms/CalculatesVehTypeDepServiceInsertion.java b/jsprit-core/src/main/java/algorithms/VehicleTypeDependentJobInsertionCalculator.java
similarity index 73%
rename from jsprit-core/src/main/java/algorithms/CalculatesVehTypeDepServiceInsertion.java
rename to jsprit-core/src/main/java/algorithms/VehicleTypeDependentJobInsertionCalculator.java
index 63ca251d..b729b94a 100644
--- a/jsprit-core/src/main/java/algorithms/CalculatesVehTypeDepServiceInsertion.java
+++ b/jsprit-core/src/main/java/algorithms/VehicleTypeDependentJobInsertionCalculator.java
@@ -25,20 +25,21 @@ import algorithms.InsertionData.NoInsertionFound;
import basics.Job;
import basics.route.Driver;
import basics.route.Vehicle;
+import basics.route.VehicleFleetManager;
import basics.route.VehicleImpl.NoVehicle;
import basics.route.VehicleRoute;
-final class CalculatesVehTypeDepServiceInsertion implements JobInsertionCalculator{
+final class VehicleTypeDependentJobInsertionCalculator implements JobInsertionCostsCalculator{
- private Logger logger = Logger.getLogger(CalculatesVehTypeDepServiceInsertion.class);
+ private Logger logger = Logger.getLogger(VehicleTypeDependentJobInsertionCalculator.class);
private final VehicleFleetManager fleetManager;
- private final JobInsertionCalculator insertionCalculator;
+ private final JobInsertionCostsCalculator insertionCalculator;
- public CalculatesVehTypeDepServiceInsertion(final VehicleFleetManager fleetManager, final JobInsertionCalculator jobInsertionCalc) {
+ public VehicleTypeDependentJobInsertionCalculator(final VehicleFleetManager fleetManager, final JobInsertionCostsCalculator jobInsertionCalc) {
this.fleetManager = fleetManager;
this.insertionCalculator = jobInsertionCalc;
logger.info("inialise " + this);
@@ -49,10 +50,10 @@ final class CalculatesVehTypeDepServiceInsertion implements JobInsertionCalculat
return "[name=vehicleTypeDependentServiceInsertion]";
}
- public InsertionData calculate(final VehicleRoute currentRoute, final Job jobToInsert, final Vehicle vehicle, double newVehicleDepartureTime, final Driver driver, final double bestKnownCost) {
+ public InsertionData getInsertionData(final VehicleRoute currentRoute, final Job jobToInsert, final Vehicle vehicle, double newVehicleDepartureTime, final Driver driver, final double bestKnownCost) {
Vehicle selectedVehicle = currentRoute.getVehicle();
Driver selectedDriver = currentRoute.getDriver();
- InsertionData bestIData = InsertionData.noInsertionFound();
+ InsertionData bestIData = InsertionData.createEmptyInsertionData();
double bestKnownCost_ = bestKnownCost;
Collection relevantVehicles = new ArrayList();
if(!(selectedVehicle instanceof NoVehicle)) {
@@ -65,7 +66,7 @@ final class CalculatesVehTypeDepServiceInsertion implements JobInsertionCalculat
for(Vehicle v : relevantVehicles){
double depTime = v.getEarliestDeparture();
- InsertionData iData = insertionCalculator.calculate(currentRoute, jobToInsert, v, depTime, selectedDriver, bestKnownCost_);
+ InsertionData iData = insertionCalculator.getInsertionData(currentRoute, jobToInsert, v, depTime, selectedDriver, bestKnownCost_);
if(iData instanceof NoInsertionFound) {
if(bestIData instanceof NoInsertionFound) bestIData = iData;
continue;
diff --git a/jsprit-core/src/main/java/basics/algo/InsertionListeners.java b/jsprit-core/src/main/java/basics/algo/InsertionListeners.java
new file mode 100644
index 00000000..63afa67b
--- /dev/null
+++ b/jsprit-core/src/main/java/basics/algo/InsertionListeners.java
@@ -0,0 +1,42 @@
+package basics.algo;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import basics.Job;
+import basics.route.VehicleRoute;
+
+public class InsertionListeners {
+
+ private Collection startListeners = new ArrayList();
+
+ private Collection jobInsertedListeners = new ArrayList();
+
+ private Collection endListeners = new ArrayList();
+
+ public void addListener(InsertionListener insertionListener){
+ if(insertionListener instanceof InsertionStartsListener) startListeners.add((InsertionStartsListener) insertionListener);
+ else if(insertionListener instanceof JobInsertedListener) jobInsertedListeners.add((JobInsertedListener) insertionListener);
+ else if(insertionListener instanceof InsertionEndsListener) endListeners.add((InsertionEndsListener) insertionListener);
+ else throw new IllegalStateException("cannot add this type of insertionListener");
+ }
+
+ public void removeListener(InsertionListener insertionListener){
+ if(insertionListener instanceof InsertionStartsListener) startListeners.remove((InsertionStartsListener) insertionListener);
+ else if(insertionListener instanceof JobInsertedListener) jobInsertedListeners.remove((JobInsertedListener) insertionListener);
+ else if(insertionListener instanceof InsertionEndsListener) endListeners.remove((InsertionEndsListener) insertionListener);
+ else throw new IllegalStateException("cannot remove this type of insertionListener");
+ }
+
+ public void insertionStarts(Collection vehicleRoutes, Collection unassignedJobs){
+ for(InsertionStartsListener l : startListeners) l.informInsertionStarts(vehicleRoutes, unassignedJobs);
+ }
+
+ public void jobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime){
+ for(JobInsertedListener l : jobInsertedListeners) l.informJobInserted(job2insert, inRoute, additionalCosts, additionalTime);
+ }
+
+ public void insertionEnds(Collection vehicleRoutes){
+ for(InsertionEndsListener l : endListeners){ l.informInsertionEnds(vehicleRoutes); }
+ }
+}
diff --git a/jsprit-core/src/main/java/basics/algo/InsertionStartsListener.java b/jsprit-core/src/main/java/basics/algo/InsertionStartsListener.java
index 7ae743f9..0923a02f 100644
--- a/jsprit-core/src/main/java/basics/algo/InsertionStartsListener.java
+++ b/jsprit-core/src/main/java/basics/algo/InsertionStartsListener.java
@@ -25,4 +25,5 @@ import basics.route.VehicleRoute;
public interface InsertionStartsListener extends InsertionListener {
public void informInsertionStarts(Collection vehicleRoutes, Collection unassignedJobs);
+
}
diff --git a/jsprit-core/src/main/java/basics/algo/RuinListener.java b/jsprit-core/src/main/java/basics/algo/RuinListener.java
new file mode 100644
index 00000000..bb75ca78
--- /dev/null
+++ b/jsprit-core/src/main/java/basics/algo/RuinListener.java
@@ -0,0 +1,39 @@
+package basics.algo;
+
+import java.util.Collection;
+
+import basics.Job;
+import basics.route.VehicleRoute;
+
+/**
+ * Listener that listens to the ruin-process. It informs whoever is interested about start, end and about a removal of a job.
+ *
+ * @author schroeder
+ *
+ */
+public interface RuinListener extends SearchStrategyModuleListener{
+
+ /**
+ * informs about ruin-start.
+ *
+ * @param routes
+ */
+ public void ruinStarts(Collection routes);
+
+ /**
+ * informs about ruin-end.
+ *
+ * @param routes
+ * @param unassignedJobs
+ */
+ public void ruinEnds(Collection routes, Collection unassignedJobs);
+
+ /**
+ * informs if a {@link Job} has been removed from a {@link VehicleRoute}.
+ *
+ * @param job
+ * @param fromRoute
+ */
+ public void removed(Job job, VehicleRoute fromRoute);
+
+}
\ No newline at end of file
diff --git a/jsprit-core/src/main/java/basics/algo/RuinListeners.java b/jsprit-core/src/main/java/basics/algo/RuinListeners.java
new file mode 100644
index 00000000..fc442cc9
--- /dev/null
+++ b/jsprit-core/src/main/java/basics/algo/RuinListeners.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (C) 2013 Stefan Schroeder
+ *
+ * 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.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributors:
+ * Stefan Schroeder - initial API and implementation
+ ******************************************************************************/
+package basics.algo;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+
+import basics.Job;
+import basics.route.VehicleRoute;
+
+public class RuinListeners {
+
+ private Collection ruinListeners = new ArrayList();
+
+ public void ruinStarts(Collection routes){
+ for(RuinListener l : ruinListeners) l.ruinStarts(routes);
+ }
+
+ public void ruinEnds(Collection routes, Collection unassignedJobs){
+ for(RuinListener l : ruinListeners) l.ruinEnds(routes, unassignedJobs);
+ }
+
+ public void removed(Job job, VehicleRoute fromRoute){
+ for(RuinListener l : ruinListeners) l.removed(job, fromRoute);
+ }
+
+ public void addListener(RuinListener ruinListener){
+ ruinListeners.add(ruinListener);
+ }
+
+ public void removeListener(RuinListener ruinListener){
+ ruinListeners.remove(ruinListener);
+ }
+
+ public Collection getListeners(){
+ return Collections.unmodifiableCollection(ruinListeners);
+ }
+}
diff --git a/jsprit-core/src/main/java/basics/algo/SearchStrategy.java b/jsprit-core/src/main/java/basics/algo/SearchStrategy.java
index 3fd56556..c63ecc2e 100644
--- a/jsprit-core/src/main/java/basics/algo/SearchStrategy.java
+++ b/jsprit-core/src/main/java/basics/algo/SearchStrategy.java
@@ -125,7 +125,8 @@ public class SearchStrategy {
VehicleRoutingProblemSolution newSolution = module.runAndGetSolution(lastSolution);
lastSolution = newSolution;
}
- solutionCostCalculator.calculateCosts(lastSolution);
+ double costs = solutionCostCalculator.getCosts(lastSolution);
+ lastSolution.setCost(costs);
boolean solutionAccepted = solutionAcceptor.acceptSolution(solutions, lastSolution);
DiscoveredSolution discoveredSolution = new DiscoveredSolution(lastSolution, solutionAccepted, getName());
return discoveredSolution;
diff --git a/jsprit-core/src/main/java/basics/algo/SolutionCostCalculator.java b/jsprit-core/src/main/java/basics/algo/SolutionCostCalculator.java
index f7958a0e..db67b2ca 100644
--- a/jsprit-core/src/main/java/basics/algo/SolutionCostCalculator.java
+++ b/jsprit-core/src/main/java/basics/algo/SolutionCostCalculator.java
@@ -21,10 +21,11 @@ import basics.VehicleRoutingProblemSolution;
public interface SolutionCostCalculator {
/**
- * This assumes that the solution is modified by setting its costs
- * solution.setCost(costs);
+ * Returns costs of solution.
+ *
* @param solution
+ * @return TODO
*/
- public void calculateCosts(VehicleRoutingProblemSolution solution);
+ public double getCosts(VehicleRoutingProblemSolution solution);
}
diff --git a/jsprit-core/src/main/java/algorithms/ActivityVisitor.java b/jsprit-core/src/main/java/basics/route/ActivityVisitor.java
similarity index 89%
rename from jsprit-core/src/main/java/algorithms/ActivityVisitor.java
rename to jsprit-core/src/main/java/basics/route/ActivityVisitor.java
index 0ac3d53f..6ad321f3 100644
--- a/jsprit-core/src/main/java/algorithms/ActivityVisitor.java
+++ b/jsprit-core/src/main/java/basics/route/ActivityVisitor.java
@@ -14,12 +14,10 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see .
******************************************************************************/
-package algorithms;
+package basics.route;
-import basics.route.TourActivity;
-import basics.route.VehicleRoute;
-interface ActivityVisitor {
+public interface ActivityVisitor {
public void begin(VehicleRoute route);
diff --git a/jsprit-core/src/main/java/basics/route/FiniteFleetManagerFactory.java b/jsprit-core/src/main/java/basics/route/FiniteFleetManagerFactory.java
new file mode 100644
index 00000000..05c01461
--- /dev/null
+++ b/jsprit-core/src/main/java/basics/route/FiniteFleetManagerFactory.java
@@ -0,0 +1,20 @@
+package basics.route;
+
+import java.util.Collection;
+
+
+public class FiniteFleetManagerFactory implements VehicleFleetManagerFactory{
+
+ private Collection vehicles;
+
+ public FiniteFleetManagerFactory(Collection vehicles) {
+ super();
+ this.vehicles = vehicles;
+ }
+
+ @Override
+ public VehicleFleetManager createFleetManager() {
+ return new VehicleFleetManagerImpl(vehicles);
+ }
+
+}
diff --git a/jsprit-core/src/main/java/basics/route/InfiniteFleetManagerFactory.java b/jsprit-core/src/main/java/basics/route/InfiniteFleetManagerFactory.java
new file mode 100644
index 00000000..f4345b8a
--- /dev/null
+++ b/jsprit-core/src/main/java/basics/route/InfiniteFleetManagerFactory.java
@@ -0,0 +1,20 @@
+package basics.route;
+
+import java.util.Collection;
+
+
+public class InfiniteFleetManagerFactory implements VehicleFleetManagerFactory{
+
+ private Collection vehicles;
+
+ public InfiniteFleetManagerFactory(Collection vehicles) {
+ super();
+ this.vehicles = vehicles;
+ }
+
+ @Override
+ public VehicleFleetManager createFleetManager() {
+ return new InfiniteVehicles(vehicles);
+ }
+
+}
diff --git a/jsprit-core/src/main/java/algorithms/InfiniteVehicles.java b/jsprit-core/src/main/java/basics/route/InfiniteVehicles.java
similarity index 74%
rename from jsprit-core/src/main/java/algorithms/InfiniteVehicles.java
rename to jsprit-core/src/main/java/basics/route/InfiniteVehicles.java
index aff00583..41470de7 100644
--- a/jsprit-core/src/main/java/algorithms/InfiniteVehicles.java
+++ b/jsprit-core/src/main/java/basics/route/InfiniteVehicles.java
@@ -14,7 +14,7 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see .
******************************************************************************/
-package algorithms;
+package basics.route;
import java.util.ArrayList;
import java.util.Collection;
@@ -24,26 +24,14 @@ import java.util.Map;
import org.apache.log4j.Logger;
-import basics.route.Vehicle;
class InfiniteVehicles implements VehicleFleetManager{
-
-// static class TypeKeyComparator implements Comparator{
-//
-// @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 Map types = new HashMap();
+ private Map types = new HashMap();
- private List sortedTypes = new ArrayList();
+ private List sortedTypes = new ArrayList();
public InfiniteVehicles(Collection vehicles){
extractTypes(vehicles);
@@ -57,12 +45,11 @@ class InfiniteVehicles implements VehicleFleetManager{
private void extractTypes(Collection vehicles) {
for(Vehicle v : vehicles){
- TypeKey typeKey = new TypeKey(v.getType().getTypeId(),v.getLocationId());
+ VehicleTypeKey typeKey = new VehicleTypeKey(v.getType().getTypeId(),v.getLocationId());
types.put(typeKey,v);
sortedTypes.add(typeKey);
}
-// Collections.sort(sortedTypes, new TypeKeyComparator());
}
@@ -95,8 +82,8 @@ class InfiniteVehicles implements VehicleFleetManager{
@Override
public Collection getAvailableVehicles(String withoutThisType, String locationId) {
Collection vehicles = new ArrayList();
- TypeKey thisKey = new TypeKey(withoutThisType,locationId);
- for(TypeKey key : types.keySet()){
+ VehicleTypeKey thisKey = new VehicleTypeKey(withoutThisType,locationId);
+ for(VehicleTypeKey key : types.keySet()){
if(!key.equals(thisKey)){
vehicles.add(types.get(key));
}
diff --git a/jsprit-core/src/main/java/algorithms/ReverseActivityVisitor.java b/jsprit-core/src/main/java/basics/route/ReverseActivityVisitor.java
similarity index 89%
rename from jsprit-core/src/main/java/algorithms/ReverseActivityVisitor.java
rename to jsprit-core/src/main/java/basics/route/ReverseActivityVisitor.java
index 03902866..90896cd0 100644
--- a/jsprit-core/src/main/java/algorithms/ReverseActivityVisitor.java
+++ b/jsprit-core/src/main/java/basics/route/ReverseActivityVisitor.java
@@ -14,12 +14,10 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see .
******************************************************************************/
-package algorithms;
+package basics.route;
-import basics.route.TourActivity;
-import basics.route.VehicleRoute;
-interface ReverseActivityVisitor {
+public interface ReverseActivityVisitor {
public void begin(VehicleRoute route);
diff --git a/jsprit-core/src/main/java/algorithms/ReverseRouteActivityVisitor.java b/jsprit-core/src/main/java/basics/route/ReverseRouteActivityVisitor.java
similarity index 92%
rename from jsprit-core/src/main/java/algorithms/ReverseRouteActivityVisitor.java
rename to jsprit-core/src/main/java/basics/route/ReverseRouteActivityVisitor.java
index 08ead908..ddb9508c 100644
--- a/jsprit-core/src/main/java/algorithms/ReverseRouteActivityVisitor.java
+++ b/jsprit-core/src/main/java/basics/route/ReverseRouteActivityVisitor.java
@@ -14,16 +14,14 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see .
******************************************************************************/
-package algorithms;
+package basics.route;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
-import basics.route.TourActivity;
-import basics.route.VehicleRoute;
-class ReverseRouteActivityVisitor implements RouteVisitor{
+public class ReverseRouteActivityVisitor implements RouteVisitor{
private Collection visitors = new ArrayList();
diff --git a/jsprit-core/src/main/java/algorithms/RouteActivityVisitor.java b/jsprit-core/src/main/java/basics/route/RouteActivityVisitor.java
similarity index 92%
rename from jsprit-core/src/main/java/algorithms/RouteActivityVisitor.java
rename to jsprit-core/src/main/java/basics/route/RouteActivityVisitor.java
index 625bbc32..cef22424 100644
--- a/jsprit-core/src/main/java/algorithms/RouteActivityVisitor.java
+++ b/jsprit-core/src/main/java/basics/route/RouteActivityVisitor.java
@@ -14,15 +14,13 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see .
******************************************************************************/
-package algorithms;
+package basics.route;
import java.util.ArrayList;
import java.util.Collection;
-import basics.route.TourActivity;
-import basics.route.VehicleRoute;
-class RouteActivityVisitor implements RouteVisitor{
+public class RouteActivityVisitor implements RouteVisitor{
private Collection visitors = new ArrayList();
diff --git a/jsprit-core/src/main/java/algorithms/RouteVisitor.java b/jsprit-core/src/main/java/basics/route/RouteVisitor.java
similarity index 92%
rename from jsprit-core/src/main/java/algorithms/RouteVisitor.java
rename to jsprit-core/src/main/java/basics/route/RouteVisitor.java
index e82f6216..df7669c8 100644
--- a/jsprit-core/src/main/java/algorithms/RouteVisitor.java
+++ b/jsprit-core/src/main/java/basics/route/RouteVisitor.java
@@ -14,11 +14,10 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see .
******************************************************************************/
-package algorithms;
+package basics.route;
-import basics.route.VehicleRoute;
-interface RouteVisitor {
+public interface RouteVisitor {
public void visit(VehicleRoute route);
diff --git a/jsprit-core/src/main/java/basics/route/TourActivities.java b/jsprit-core/src/main/java/basics/route/TourActivities.java
index c7a1eaf5..00c01f3f 100644
--- a/jsprit-core/src/main/java/basics/route/TourActivities.java
+++ b/jsprit-core/src/main/java/basics/route/TourActivities.java
@@ -113,6 +113,12 @@ public class TourActivities {
return Collections.unmodifiableSet(jobs);
}
+ /**
+ * Returns true if job is in jobList, otherwise false.
+ *
+ * @param job
+ * @return
+ */
public boolean servesJob(Job job) {
return jobs.contains(job);
}
@@ -146,13 +152,24 @@ public class TourActivities {
}
}
}
- if(jobRemoved != activityRemoved) throw new IllegalStateException("job removed, but belonging activity not.");
+ assert jobRemoved == activityRemoved : "job removed, but belonging activity not.";
return activityRemoved;
}
+ /**
+ * Inserts the specified activity add the specified insertionIndex. Shifts the element currently at that position (if any) and
+ * any subsequent elements to the right (adds one to their indices).
+ * If specified activity instanceof JobActivity, it adds job to jobList.
+ *
If insertionIndex > tourActivitiies.size(), it just adds the specified act at the end.
+ *
+ * @param insertionIndex
+ * @param act
+ * @throws IndexOutOfBoundsException if insertionIndex < 0;
+ */
public void addActivity(int insertionIndex, TourActivity act) {
- assert insertionIndex >= 0 : "insertionIndex == 0, this cannot be";
- if(tourActivities.contains(act)) throw new IllegalStateException("act " + act + " already in tour. cannot add act twice.");
+
+ assert insertionIndex >= 0 : "insertionIndex < 0, this cannot be";
+
/*
* if 1 --> between start and act(0) --> act(0)
* if 2 && 2 <= acts.size --> between act(0) and act(1) --> act(1)
@@ -166,9 +183,15 @@ public class TourActivities {
}
/**
+<<<<<<< HEAD
* adds activity.
*
* @throw {@link IllegalStateException} if same activity is added twice.
+=======
+ * Adds specified activity at the end of activity-list.
+ *
If act instanceof JobActivity, it adds underlying job also.
+ * @throws IllegalStateException if activity-list already contains act.
+>>>>>>> refs/remotes/choose_remote_name/relaxAPI
* @param act
*/
public void addActivity(TourActivity act){
@@ -184,6 +207,11 @@ public class TourActivities {
}
}
+ /**
+ * Returns number of jobs.
+ *
+ * @return
+ */
public int jobSize() {
return jobs.size();
}
diff --git a/jsprit-core/src/main/java/algorithms/StateTypes.java b/jsprit-core/src/main/java/basics/route/VehicleFleetManager.java
similarity index 62%
rename from jsprit-core/src/main/java/algorithms/StateTypes.java
rename to jsprit-core/src/main/java/basics/route/VehicleFleetManager.java
index 1625e7ce..d71d2f7b 100644
--- a/jsprit-core/src/main/java/algorithms/StateTypes.java
+++ b/jsprit-core/src/main/java/basics/route/VehicleFleetManager.java
@@ -14,27 +14,23 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see .
******************************************************************************/
-package algorithms;
+package basics.route;
+
+import java.util.Collection;
-class StateTypes {
+public interface VehicleFleetManager {
-// final static StateId LOAD = new StateIdImpl("load");
-
- final static String LOAD = "load";
-
- final static String LOAD_AT_DEPOT = "loadAtDepot";
-
- final static String DURATION = "duration";
-
- final static String LATEST_OPERATION_START_TIME = "latestOST";
-
- final static String EARLIEST_OPERATION_START_TIME = "earliestOST";
+ public abstract void lock(Vehicle vehicle);
+
+ public abstract void unlock(Vehicle vehicle);
+
+ public abstract boolean isLocked(Vehicle vehicle);
+
+ public abstract void unlockAll();
+
+ public abstract Collection getAvailableVehicles();
+
+ public Collection getAvailableVehicles(String withoutThisType, String locationId);
- static final String COSTS = "costs";
-
- final static String FUTURE_PICKS = "futurePicks";
-
- final static String PAST_DELIVERIES = "pastDeliveries";
-
}
diff --git a/jsprit-core/src/main/java/basics/route/VehicleFleetManagerFactory.java b/jsprit-core/src/main/java/basics/route/VehicleFleetManagerFactory.java
new file mode 100644
index 00000000..29a3980a
--- /dev/null
+++ b/jsprit-core/src/main/java/basics/route/VehicleFleetManagerFactory.java
@@ -0,0 +1,7 @@
+package basics.route;
+
+public interface VehicleFleetManagerFactory {
+
+ public VehicleFleetManager createFleetManager();
+
+}
diff --git a/jsprit-core/src/main/java/algorithms/VehicleFleetManagerImpl.java b/jsprit-core/src/main/java/basics/route/VehicleFleetManagerImpl.java
similarity index 89%
rename from jsprit-core/src/main/java/algorithms/VehicleFleetManagerImpl.java
rename to jsprit-core/src/main/java/basics/route/VehicleFleetManagerImpl.java
index 2f5c07c9..f3d8569b 100644
--- a/jsprit-core/src/main/java/algorithms/VehicleFleetManagerImpl.java
+++ b/jsprit-core/src/main/java/basics/route/VehicleFleetManagerImpl.java
@@ -14,7 +14,7 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see .
******************************************************************************/
-package algorithms;
+package basics.route;
import java.util.ArrayList;
import java.util.Collection;
@@ -27,12 +27,11 @@ import java.util.Set;
import org.apache.log4j.Logger;
-import basics.route.PenaltyVehicleType;
-import basics.route.Vehicle;
import basics.route.VehicleImpl.NoVehicle;
+
class VehicleFleetManagerImpl implements VehicleFleetManager {
public VehicleFleetManagerImpl newInstance(Collection vehicles){
@@ -54,11 +53,11 @@ class VehicleFleetManagerImpl implements VehicleFleetManager {
static class TypeContainer {
- private TypeKey type;
+ private VehicleTypeKey type;
private ArrayList vehicleList;
- public TypeContainer(TypeKey type) {
+ public TypeContainer(VehicleTypeKey type) {
super();
this.type = type;
vehicleList = new ArrayList();
@@ -92,9 +91,9 @@ class VehicleFleetManagerImpl implements VehicleFleetManager {
private Set lockedVehicles;
- private Map typeMapOfAvailableVehicles;
+ private Map typeMapOfAvailableVehicles;
- private Map penaltyVehicles = new HashMap();
+ private Map penaltyVehicles = new HashMap();
// private Map typeMapOfAvailablePenaltyVehicles;
@@ -122,8 +121,8 @@ class VehicleFleetManagerImpl implements VehicleFleetManager {
}
private void makeMap() {
- typeMapOfAvailableVehicles = new HashMap();
- penaltyVehicles = new HashMap();
+ typeMapOfAvailableVehicles = new HashMap();
+ penaltyVehicles = new HashMap();
for(Vehicle v : vehicles){
addVehicle(v);
}
@@ -135,11 +134,11 @@ class VehicleFleetManagerImpl implements VehicleFleetManager {
}
String typeId = v.getType().getTypeId();
if(v.getType() instanceof PenaltyVehicleType){
- TypeKey typeKey = new TypeKey(typeId,v.getLocationId());
+ VehicleTypeKey typeKey = new VehicleTypeKey(typeId,v.getLocationId());
penaltyVehicles.put(typeKey, v);
}
else{
- TypeKey typeKey = new TypeKey(v.getType().getTypeId(),v.getLocationId());
+ VehicleTypeKey typeKey = new VehicleTypeKey(v.getType().getTypeId(),v.getLocationId());
if(!typeMapOfAvailableVehicles.containsKey(typeKey)){
typeMapOfAvailableVehicles.put(typeKey, new TypeContainer(typeKey));
}
@@ -150,7 +149,7 @@ class VehicleFleetManagerImpl implements VehicleFleetManager {
private void removeVehicle(Vehicle v){
//it might be better to introduce a class PenaltyVehicle
if(!(v.getType() instanceof PenaltyVehicleType)){
- TypeKey key = new TypeKey(v.getType().getTypeId(),v.getLocationId());
+ VehicleTypeKey key = new VehicleTypeKey(v.getType().getTypeId(),v.getLocationId());
if(typeMapOfAvailableVehicles.containsKey(key)){
typeMapOfAvailableVehicles.get(key).remove(v);
}
@@ -167,7 +166,7 @@ class VehicleFleetManagerImpl implements VehicleFleetManager {
@Override
public Collection getAvailableVehicles() {
List vehicles = new ArrayList();
- for(TypeKey key : typeMapOfAvailableVehicles.keySet()){
+ for(VehicleTypeKey key : typeMapOfAvailableVehicles.keySet()){
if(!typeMapOfAvailableVehicles.get(key).isEmpty()){
vehicles.add(typeMapOfAvailableVehicles.get(key).getVehicle());
}
@@ -193,8 +192,8 @@ class VehicleFleetManagerImpl implements VehicleFleetManager {
@Override
public Collection getAvailableVehicles(String withoutThisType, String withThisLocationId) {
List vehicles = new ArrayList();
- TypeKey thisKey = new TypeKey(withoutThisType,withThisLocationId);
- for(TypeKey key : typeMapOfAvailableVehicles.keySet()){
+ VehicleTypeKey thisKey = new VehicleTypeKey(withoutThisType,withThisLocationId);
+ for(VehicleTypeKey key : typeMapOfAvailableVehicles.keySet()){
if(key.equals(thisKey)) continue;
if(!typeMapOfAvailableVehicles.get(key).isEmpty()){
vehicles.add(typeMapOfAvailableVehicles.get(key).getVehicle());
diff --git a/jsprit-core/src/main/java/basics/route/VehicleTypeKey.java b/jsprit-core/src/main/java/basics/route/VehicleTypeKey.java
new file mode 100644
index 00000000..56dae41c
--- /dev/null
+++ b/jsprit-core/src/main/java/basics/route/VehicleTypeKey.java
@@ -0,0 +1,48 @@
+package basics.route;
+
+class VehicleTypeKey {
+
+ public final String type;
+ public final String locationId;
+
+ VehicleTypeKey(String typeId, String locationId) {
+ super();
+ this.type = typeId;
+ this.locationId = locationId;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result
+ + ((locationId == null) ? 0 : locationId.hashCode());
+ result = prime * result + ((type == null) ? 0 : type.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ VehicleTypeKey other = (VehicleTypeKey) obj;
+ if (locationId == null) {
+ if (other.locationId != null)
+ return false;
+ } else if (!locationId.equals(other.locationId))
+ return false;
+ if (type == null) {
+ if (other.type != null)
+ return false;
+ } else if (!type.equals(other.type))
+ return false;
+ return true;
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/jsprit-core/src/main/java/algorithms/ActivityTimeTracker.java b/jsprit-core/src/main/java/util/ActivityTimeTracker.java
similarity index 96%
rename from jsprit-core/src/main/java/algorithms/ActivityTimeTracker.java
rename to jsprit-core/src/main/java/util/ActivityTimeTracker.java
index 8c6e4aab..6c0a7361 100644
--- a/jsprit-core/src/main/java/algorithms/ActivityTimeTracker.java
+++ b/jsprit-core/src/main/java/util/ActivityTimeTracker.java
@@ -14,13 +14,14 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see .
******************************************************************************/
-package algorithms;
+package util;
import basics.costs.ForwardTransportTime;
+import basics.route.ActivityVisitor;
import basics.route.TourActivity;
import basics.route.VehicleRoute;
-class ActivityTimeTracker implements ActivityVisitor{
+public class ActivityTimeTracker implements ActivityVisitor{
private ForwardTransportTime transportTime;
diff --git a/jsprit-core/src/main/java/util/Solutions.java b/jsprit-core/src/main/java/util/Solutions.java
index 12d69e0b..a206f05a 100644
--- a/jsprit-core/src/main/java/util/Solutions.java
+++ b/jsprit-core/src/main/java/util/Solutions.java
@@ -22,6 +22,7 @@ import basics.VehicleRoutingProblemSolution;
public class Solutions {
+ @Deprecated
public static VehicleRoutingProblemSolution getBest(Collection solutions){
VehicleRoutingProblemSolution best = null;
for(VehicleRoutingProblemSolution s : solutions){
@@ -30,5 +31,15 @@ public class Solutions {
}
return best;
}
+
+
+ public static VehicleRoutingProblemSolution bestOf(Collection solutions){
+ VehicleRoutingProblemSolution best = null;
+ for(VehicleRoutingProblemSolution s : solutions){
+ if(best == null) best = s;
+ else if(s.getCost() < best.getCost()) best = s;
+ }
+ return best;
+ }
}
diff --git a/jsprit-core/src/test/java/algorithms/AverageJobDistanceTest.java b/jsprit-core/src/test/java/algorithms/AverageJobDistanceTest.java
index ec375f72..6a81431c 100644
--- a/jsprit-core/src/test/java/algorithms/AverageJobDistanceTest.java
+++ b/jsprit-core/src/test/java/algorithms/AverageJobDistanceTest.java
@@ -42,13 +42,13 @@ public class AverageJobDistanceTest {
Shipment s1 = Shipment.Builder.newInstance("s1", 1).setPickupLocation("0,0").setDeliveryLocation("10,10").build();
Shipment s2 = Shipment.Builder.newInstance("s2", 1).setPickupLocation("0,0").setDeliveryLocation("10,10").build();
- double dist = new AvgJobDistance(routingCosts).calculateDistance(s1, s2);
+ double dist = new AvgJobDistance(routingCosts).getDistance(s1, s2);
for(int i=0;i<10;i++){
for(int j=0;j<10;j++){
Shipment other1 = Shipment.Builder.newInstance("s1", 1).setPickupLocation("0,0").setDeliveryLocation(i+","+j).build();
Shipment other2 = Shipment.Builder.newInstance("s2", 1).setPickupLocation("0,0").setDeliveryLocation("10,10").build();
- double dist2 = new AvgJobDistance(routingCosts).calculateDistance(other1, other2);
+ double dist2 = new AvgJobDistance(routingCosts).getDistance(other1, other2);
System.out.println("("+i+","+j+"), dist=" + dist + ", dist2=" + dist2);
assertTrue(dist<=dist2+dist2*0.001);
}
@@ -62,7 +62,7 @@ public class AverageJobDistanceTest {
Service s1 = Service.Builder.newInstance("s1", 1).setLocationId("10,0").build();
Service s2 = Service.Builder.newInstance("s2", 1).setLocationId("10,0").build();
- double dist = new AvgJobDistance(routingCosts).calculateDistance(s1, s2);
+ double dist = new AvgJobDistance(routingCosts).getDistance(s1, s2);
assertEquals(0.0,dist,0.01);
}
}
diff --git a/jsprit-core/src/test/java/algorithms/BuildCVRPAlgoFromScratchTest.java b/jsprit-core/src/test/java/algorithms/BuildCVRPAlgoFromScratchTest.java
index 00659c2e..a21b575b 100644
--- a/jsprit-core/src/test/java/algorithms/BuildCVRPAlgoFromScratchTest.java
+++ b/jsprit-core/src/test/java/algorithms/BuildCVRPAlgoFromScratchTest.java
@@ -24,9 +24,6 @@ import org.junit.Before;
import org.junit.Test;
import util.Solutions;
-import algorithms.HardConstraints.HardActivityLevelConstraint;
-import algorithms.StateUpdates.UpdateCostsAtRouteLevel;
-import algorithms.StateUpdates.UpdateLoadAtRouteLevel;
import algorithms.acceptors.AcceptNewIfBetterThanWorst;
import algorithms.selectors.SelectBest;
import basics.VehicleRoutingAlgorithm;
@@ -37,7 +34,9 @@ import basics.algo.SearchStrategy;
import basics.algo.SearchStrategyManager;
import basics.algo.SolutionCostCalculator;
import basics.io.VrpXMLReader;
+import basics.route.InfiniteFleetManagerFactory;
import basics.route.TourActivity;
+import basics.route.VehicleFleetManager;
import basics.route.VehicleRoute;
public class BuildCVRPAlgoFromScratchTest {
@@ -52,19 +51,21 @@ public class BuildCVRPAlgoFromScratchTest {
new VrpXMLReader(builder).read("src/test/resources/vrpnc1-jsprit.xml");
vrp = builder.build();
- final StateManagerImpl stateManager = new StateManagerImpl();
+ final StateManager stateManager = new StateManager();
HardActivityLevelConstraint hardActLevelConstraint = new HardActivityLevelConstraint() {
@Override
- public boolean fulfilled(InsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
- return true;
+ public ConstraintsStatus fulfilled(InsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
+ return ConstraintsStatus.FULFILLED;
}
};
- ActivityInsertionCostsCalculator marginalCalculus = new LocalActivityInsertionCostsCalculator(vrp.getTransportCosts(), vrp.getActivityCosts(), hardActLevelConstraint);
- ServiceInsertionCalculator serviceInsertion = new ServiceInsertionCalculator(vrp.getTransportCosts(), marginalCalculus, new HardConstraints.HardLoadConstraint(stateManager));
+
+
+ ActivityInsertionCostsCalculator marginalCalculus = new LocalActivityInsertionCostsCalculator(vrp.getTransportCosts(), vrp.getActivityCosts());
+ ServiceInsertionCalculator serviceInsertion = new ServiceInsertionCalculator(vrp.getTransportCosts(), marginalCalculus, new HardLoadConstraint(stateManager), hardActLevelConstraint);
- VehicleFleetManager fleetManager = new InfiniteVehicles(vrp.getVehicles());
- JobInsertionCalculator finalServiceInsertion = new CalculatesVehTypeDepServiceInsertion(fleetManager, serviceInsertion);
+ VehicleFleetManager fleetManager = new InfiniteFleetManagerFactory(vrp.getVehicles()).createFleetManager();
+ JobInsertionCostsCalculator finalServiceInsertion = new VehicleTypeDependentJobInsertionCalculator(fleetManager, serviceInsertion);
BestInsertion bestInsertion = new BestInsertion(finalServiceInsertion);
@@ -74,12 +75,12 @@ public class BuildCVRPAlgoFromScratchTest {
SolutionCostCalculator solutionCostCalculator = new SolutionCostCalculator() {
@Override
- public void calculateCosts(VehicleRoutingProblemSolution solution) {
+ public double getCosts(VehicleRoutingProblemSolution solution) {
double costs = 0.0;
for(VehicleRoute route : solution.getRoutes()){
- costs += stateManager.getRouteState(route, StateTypes.COSTS).toDouble();
+ costs += stateManager.getRouteState(route, StateFactory.COSTS).toDouble();
}
- solution.setCost(costs);
+ return costs;
}
};
@@ -111,7 +112,9 @@ public class BuildCVRPAlgoFromScratchTest {
vra.getSearchStrategyManager().addSearchStrategyModuleListener(new UpdateCostsAtRouteLevel(stateManager, vrp.getTransportCosts(), vrp.getActivityCosts()));
vra.getSearchStrategyManager().addSearchStrategyModuleListener(new UpdateLoadAtRouteLevel(stateManager));
- VehicleRoutingProblemSolution iniSolution = new CreateInitialSolution(bestInsertion, solutionCostCalculator).createInitialSolution(vrp);
+
+ VehicleRoutingProblemSolution iniSolution = new InsertionInitialSolutionFactory(bestInsertion, solutionCostCalculator).createSolution(vrp);
+
// System.out.println("ini: costs="+iniSolution.getCost()+";#routes="+iniSolution.getRoutes().size());
vra.addInitialSolution(iniSolution);
diff --git a/jsprit-core/src/test/java/algorithms/BuildPDVRPAlgoFromScratchTest.java b/jsprit-core/src/test/java/algorithms/BuildPDVRPAlgoFromScratchTest.java
index 138f0e83..588d5751 100644
--- a/jsprit-core/src/test/java/algorithms/BuildPDVRPAlgoFromScratchTest.java
+++ b/jsprit-core/src/test/java/algorithms/BuildPDVRPAlgoFromScratchTest.java
@@ -22,12 +22,8 @@ import org.apache.log4j.Logger;
import org.junit.Before;
import org.junit.Test;
-import algorithms.HardConstraints.HardActivityLevelConstraintManager;
+import util.Solutions;
import algorithms.StateManager.StateImpl;
-import algorithms.StateUpdates.UpdateActivityTimes;
-import algorithms.StateUpdates.UpdateCostsAtAllLevels;
-import algorithms.StateUpdates.UpdateEarliestStartTimeWindowAtActLocations;
-import algorithms.StateUpdates.UpdateLatestOperationStartTimeAtActLocations;
import algorithms.acceptors.AcceptNewIfBetterThanWorst;
import algorithms.selectors.SelectBest;
import basics.Delivery;
@@ -42,6 +38,10 @@ import basics.algo.SearchStrategy;
import basics.algo.SearchStrategyManager;
import basics.algo.SolutionCostCalculator;
import basics.io.VrpXMLReader;
+import basics.route.InfiniteFleetManagerFactory;
+import basics.route.ReverseRouteActivityVisitor;
+import basics.route.RouteActivityVisitor;
+import basics.route.VehicleFleetManager;
import basics.route.VehicleRoute;
public class BuildPDVRPAlgoFromScratchTest {
@@ -59,19 +59,20 @@ public class BuildPDVRPAlgoFromScratchTest {
new VrpXMLReader(builder).read("src/test/resources/pd_solomon_r101.xml");
vrp = builder.build();
- final StateManagerImpl stateManager = new StateManagerImpl();
+ final StateManager stateManager = new StateManager();
- HardActivityLevelConstraintManager actLevelConstraintAccumulator = new HardActivityLevelConstraintManager();
- actLevelConstraintAccumulator.addConstraint(new HardConstraints.HardPickupAndDeliveryActivityLevelConstraint(stateManager));
- actLevelConstraintAccumulator.addConstraint(new HardConstraints.HardTimeWindowActivityLevelConstraint(stateManager, vrp.getTransportCosts()));
+ ConstraintManager actLevelConstraintAccumulator = new ConstraintManager();
+ actLevelConstraintAccumulator.addConstraint(new HardPickupAndDeliveryActivityLevelConstraint(stateManager));
+ actLevelConstraintAccumulator.addConstraint(new HardTimeWindowActivityLevelConstraint(stateManager, vrp.getTransportCosts()));
- ActivityInsertionCostsCalculator marginalCalculus = new LocalActivityInsertionCostsCalculator(vrp.getTransportCosts(), vrp.getActivityCosts(), actLevelConstraintAccumulator);
+ ActivityInsertionCostsCalculator marginalCalculus = new LocalActivityInsertionCostsCalculator(vrp.getTransportCosts(), vrp.getActivityCosts());
+
+ ServiceInsertionCalculator serviceInsertion = new ServiceInsertionCalculator(vrp.getTransportCosts(), marginalCalculus, new HardPickupAndDeliveryLoadRouteLevelConstraint(stateManager), actLevelConstraintAccumulator);
- ServiceInsertionCalculator serviceInsertion = new ServiceInsertionCalculator(vrp.getTransportCosts(), marginalCalculus, new HardConstraints.HardPickupAndDeliveryLoadConstraint(stateManager));
// CalculatesServiceInsertion serviceInsertion = new CalculatesServiceInsertion(vrp.getTransportCosts(), marginalCalculus, new HardConstraints.HardLoadConstraint(stateManager));
- VehicleFleetManager fleetManager = new InfiniteVehicles(vrp.getVehicles());
- JobInsertionCalculator finalServiceInsertion = new CalculatesVehTypeDepServiceInsertion(fleetManager, serviceInsertion);
+ VehicleFleetManager fleetManager = new InfiniteFleetManagerFactory(vrp.getVehicles()).createFleetManager();
+ JobInsertionCostsCalculator finalServiceInsertion = new VehicleTypeDependentJobInsertionCalculator(fleetManager, serviceInsertion);
BestInsertion bestInsertion = new BestInsertion(finalServiceInsertion);
@@ -81,12 +82,12 @@ public class BuildPDVRPAlgoFromScratchTest {
SolutionCostCalculator solutionCostCalculator = new SolutionCostCalculator() {
@Override
- public void calculateCosts(VehicleRoutingProblemSolution solution) {
+ public double getCosts(VehicleRoutingProblemSolution solution) {
double costs = 0.0;
for(VehicleRoute route : solution.getRoutes()){
- costs += stateManager.getRouteState(route, StateTypes.COSTS).toDouble();
+ costs += stateManager.getRouteState(route, StateFactory.COSTS).toDouble();
}
- solution.setCost(costs);
+ return costs;
}
};
@@ -103,9 +104,8 @@ public class BuildPDVRPAlgoFromScratchTest {
strategyManager.addStrategy(randomStrategy, 0.5);
vra = new VehicleRoutingAlgorithm(vrp, strategyManager);
-
-
- vra.getAlgorithmListeners().addListener(new StateUpdates.ResetStateManager(stateManager));
+
+ vra.getAlgorithmListeners().addListener(stateManager);
final RouteActivityVisitor iterateForward = new RouteActivityVisitor();
@@ -113,12 +113,12 @@ public class BuildPDVRPAlgoFromScratchTest {
iterateForward.addActivityVisitor(new UpdateEarliestStartTimeWindowAtActLocations(stateManager, vrp.getTransportCosts()));
iterateForward.addActivityVisitor(new UpdateCostsAtAllLevels(vrp.getActivityCosts(), vrp.getTransportCosts(), stateManager));
- iterateForward.addActivityVisitor(new StateUpdates.UpdateOccuredDeliveriesAtActivityLevel(stateManager));
- iterateForward.addActivityVisitor(new StateUpdates.UpdateLoadAtActivityLevel(stateManager));
+ iterateForward.addActivityVisitor(new UpdateOccuredDeliveriesAtActivityLevel(stateManager));
+ iterateForward.addActivityVisitor(new UpdateLoadAtActivityLevel(stateManager));
final ReverseRouteActivityVisitor iterateBackward = new ReverseRouteActivityVisitor();
iterateBackward.addActivityVisitor(new UpdateLatestOperationStartTimeAtActLocations(stateManager, vrp.getTransportCosts()));
- iterateBackward.addActivityVisitor(new StateUpdates.UpdateFuturePickupsAtActivityLevel(stateManager));
+ iterateBackward.addActivityVisitor(new UpdateFuturePickupsAtActivityLevel(stateManager));
InsertionStartsListener loadVehicleInDepot = new InsertionStartsListener() {
@@ -136,8 +136,8 @@ public class BuildPDVRPAlgoFromScratchTest {
loadAtEnd += j.getCapacityDemand();
}
}
- stateManager.putRouteState(route, StateTypes.LOAD_AT_DEPOT, new StateImpl(loadAtDepot));
- stateManager.putRouteState(route, StateTypes.LOAD, new StateImpl(loadAtEnd));
+ stateManager.putRouteState(route, StateFactory.LOAD_AT_BEGINNING, new StateImpl(loadAtDepot));
+ stateManager.putRouteState(route, StateFactory.LOAD, new StateImpl(loadAtEnd));
iterateForward.visit(route);
iterateBackward.visit(route);
}
@@ -154,14 +154,14 @@ public class BuildPDVRPAlgoFromScratchTest {
// log.info("insert job " + job2insert.getClass().toString() + " job " + job2insert + "" + job2insert.getCapacityDemand() + " in route " + inRoute.getTourActivities());
if(job2insert instanceof Delivery){
- int loadAtDepot = (int) stateManager.getRouteState(inRoute, StateTypes.LOAD_AT_DEPOT).toDouble();
+ int loadAtDepot = (int) stateManager.getRouteState(inRoute, StateFactory.LOAD_AT_BEGINNING).toDouble();
// log.info("loadAtDepot="+loadAtDepot);
- stateManager.putRouteState(inRoute, StateTypes.LOAD_AT_DEPOT, new StateImpl(loadAtDepot + job2insert.getCapacityDemand()));
+ stateManager.putRouteState(inRoute, StateFactory.LOAD_AT_BEGINNING, StateFactory.createState(loadAtDepot + job2insert.getCapacityDemand()));
}
if(job2insert instanceof Pickup){
- int loadAtEnd = (int) stateManager.getRouteState(inRoute, StateTypes.LOAD).toDouble();
+ int loadAtEnd = (int) stateManager.getRouteState(inRoute, StateFactory.LOAD_AT_END).toDouble();
// log.info("loadAtEnd="+loadAtEnd);
- stateManager.putRouteState(inRoute, StateTypes.LOAD, new StateImpl(loadAtEnd + job2insert.getCapacityDemand()));
+ stateManager.putRouteState(inRoute, StateFactory.LOAD_AT_END, StateFactory.createState(loadAtEnd + job2insert.getCapacityDemand()));
}
iterateForward.visit(inRoute);
iterateBackward.visit(inRoute);
@@ -171,7 +171,8 @@ public class BuildPDVRPAlgoFromScratchTest {
bestInsertion.addListener(loadVehicleInDepot);
bestInsertion.addListener(updateLoadAfterJobHasBeenInserted);
- VehicleRoutingProblemSolution iniSolution = new CreateInitialSolution(bestInsertion, solutionCostCalculator).createInitialSolution(vrp);
+ VehicleRoutingProblemSolution iniSolution = new InsertionInitialSolutionFactory(bestInsertion, solutionCostCalculator).createSolution(vrp);
+
// System.out.println("ini: costs="+iniSolution.getCost()+";#routes="+iniSolution.getRoutes().size());
vra.addInitialSolution(iniSolution);
@@ -183,7 +184,7 @@ public class BuildPDVRPAlgoFromScratchTest {
@Test
public void test(){
Collection 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");
}
diff --git a/jsprit-core/src/test/java/algorithms/BuildPDVRPWithShipmentsAlgoFromScratchTest.java b/jsprit-core/src/test/java/algorithms/BuildPDVRPWithShipmentsAlgoFromScratchTest.java
index f18fbbc4..ff87f1dd 100644
--- a/jsprit-core/src/test/java/algorithms/BuildPDVRPWithShipmentsAlgoFromScratchTest.java
+++ b/jsprit-core/src/test/java/algorithms/BuildPDVRPWithShipmentsAlgoFromScratchTest.java
@@ -23,12 +23,7 @@ import org.junit.Before;
import org.junit.Test;
import util.Solutions;
-import algorithms.HardConstraints.HardActivityLevelConstraintManager;
import algorithms.StateManager.StateImpl;
-import algorithms.StateUpdates.UpdateActivityTimes;
-import algorithms.StateUpdates.UpdateCostsAtAllLevels;
-import algorithms.StateUpdates.UpdateEarliestStartTimeWindowAtActLocations;
-import algorithms.StateUpdates.UpdateLatestOperationStartTimeAtActLocations;
import algorithms.acceptors.AcceptNewIfBetterThanWorst;
import algorithms.selectors.SelectBest;
import basics.Delivery;
@@ -46,7 +41,11 @@ import basics.algo.SearchStrategyManager;
import basics.algo.SolutionCostCalculator;
import basics.io.VrpXMLReader;
import basics.io.VrpXMLWriter;
+import basics.route.InfiniteFleetManagerFactory;
+import basics.route.ReverseRouteActivityVisitor;
+import basics.route.RouteActivityVisitor;
import basics.route.TourActivity;
+import basics.route.VehicleFleetManager;
import basics.route.VehicleRoute;
public class BuildPDVRPWithShipmentsAlgoFromScratchTest {
@@ -76,25 +75,26 @@ public class BuildPDVRPWithShipmentsAlgoFromScratchTest {
vrp = builder.build();
- final StateManagerImpl stateManager = new StateManagerImpl();
+ final StateManager stateManager = new StateManager();
- HardActivityLevelConstraintManager actLevelConstraintAccumulator = new HardActivityLevelConstraintManager();
- actLevelConstraintAccumulator.addConstraint(new HardConstraints.HardTimeWindowActivityLevelConstraint(stateManager, vrp.getTransportCosts()));
- actLevelConstraintAccumulator.addConstraint(new HardConstraints.HardPickupAndDeliveryActivityLevelConstraint(stateManager));
- actLevelConstraintAccumulator.addConstraint(new HardConstraints.HardPickupAndDeliveryShipmentActivityLevelConstraint(stateManager));
+ ConstraintManager constraintManager = new ConstraintManager();
+ constraintManager.addConstraint(new HardTimeWindowActivityLevelConstraint(stateManager, vrp.getTransportCosts()));
+ constraintManager.addConstraint(new HardPickupAndDeliveryActivityLevelConstraint(stateManager));
+ constraintManager.addConstraint(new HardPickupAndDeliveryShipmentActivityLevelConstraint(stateManager));
+ constraintManager.addConstraint(new HardPickupAndDeliveryLoadRouteLevelConstraint(stateManager));
- ActivityInsertionCostsCalculator marginalCalculus = new LocalActivityInsertionCostsCalculator(vrp.getTransportCosts(), vrp.getActivityCosts(), actLevelConstraintAccumulator);
+ ActivityInsertionCostsCalculator marginalCalculus = new LocalActivityInsertionCostsCalculator(vrp.getTransportCosts(), vrp.getActivityCosts());
- ShipmentInsertionCalculator shipmentInsertion = new ShipmentInsertionCalculator(vrp.getTransportCosts(), marginalCalculus, new HardConstraints.HardPickupAndDeliveryLoadConstraint(stateManager));
+ ShipmentInsertionCalculator shipmentInsertion = new ShipmentInsertionCalculator(vrp.getTransportCosts(), marginalCalculus, constraintManager, constraintManager);
- ServiceInsertionCalculator serviceInsertion = new ServiceInsertionCalculator(vrp.getTransportCosts(), marginalCalculus, new HardConstraints.HardLoadConstraint(stateManager));
+ ServiceInsertionCalculator serviceInsertion = new ServiceInsertionCalculator(vrp.getTransportCosts(), marginalCalculus, constraintManager, constraintManager);
JobCalculatorSwitcher switcher = new JobCalculatorSwitcher();
switcher.put(Shipment.class, shipmentInsertion);
switcher.put(Service.class, serviceInsertion);
- VehicleFleetManager fleetManager = new InfiniteVehicles(vrp.getVehicles());
- JobInsertionCalculator finalServiceInsertion = new CalculatesVehTypeDepServiceInsertion(fleetManager, switcher);
+ VehicleFleetManager fleetManager = new InfiniteFleetManagerFactory(vrp.getVehicles()).createFleetManager();
+ JobInsertionCostsCalculator finalServiceInsertion = new VehicleTypeDependentJobInsertionCalculator(fleetManager, switcher);
BestInsertion bestInsertion = new BestInsertion(finalServiceInsertion);
@@ -104,12 +104,12 @@ public class BuildPDVRPWithShipmentsAlgoFromScratchTest {
SolutionCostCalculator solutionCostCalculator = new SolutionCostCalculator() {
@Override
- public void calculateCosts(VehicleRoutingProblemSolution solution) {
+ public double getCosts(VehicleRoutingProblemSolution solution) {
double costs = 0.0;
for(VehicleRoute route : solution.getRoutes()){
- costs += stateManager.getRouteState(route, StateTypes.COSTS).toDouble();
+ costs += stateManager.getRouteState(route, StateFactory.COSTS).toDouble();
}
- solution.setCost(costs);
+ return costs;
}
};
@@ -127,8 +127,7 @@ public class BuildPDVRPWithShipmentsAlgoFromScratchTest {
vra = new VehicleRoutingAlgorithm(vrp, strategyManager);
-
- vra.getAlgorithmListeners().addListener(new StateUpdates.ResetStateManager(stateManager));
+ vra.getAlgorithmListeners().addListener(stateManager);
final RouteActivityVisitor iterateForward = new RouteActivityVisitor();
@@ -136,12 +135,12 @@ public class BuildPDVRPWithShipmentsAlgoFromScratchTest {
iterateForward.addActivityVisitor(new UpdateEarliestStartTimeWindowAtActLocations(stateManager, vrp.getTransportCosts()));
iterateForward.addActivityVisitor(new UpdateCostsAtAllLevels(vrp.getActivityCosts(), vrp.getTransportCosts(), stateManager));
- iterateForward.addActivityVisitor(new StateUpdates.UpdateOccuredDeliveriesAtActivityLevel(stateManager));
- iterateForward.addActivityVisitor(new StateUpdates.UpdateLoadAtActivityLevel(stateManager));
+ iterateForward.addActivityVisitor(new UpdateOccuredDeliveriesAtActivityLevel(stateManager));
+ iterateForward.addActivityVisitor(new UpdateLoadAtActivityLevel(stateManager));
final ReverseRouteActivityVisitor iterateBackward = new ReverseRouteActivityVisitor();
iterateBackward.addActivityVisitor(new UpdateLatestOperationStartTimeAtActLocations(stateManager, vrp.getTransportCosts()));
- iterateBackward.addActivityVisitor(new StateUpdates.UpdateFuturePickupsAtActivityLevel(stateManager));
+ iterateBackward.addActivityVisitor(new UpdateFuturePickupsAtActivityLevel(stateManager));
InsertionStartsListener loadVehicleInDepot = new InsertionStartsListener() {
@@ -159,8 +158,8 @@ public class BuildPDVRPWithShipmentsAlgoFromScratchTest {
loadAtEnd += j.getCapacityDemand();
}
}
- stateManager.putRouteState(route, StateTypes.LOAD_AT_DEPOT, new StateImpl(loadAtDepot));
- stateManager.putRouteState(route, StateTypes.LOAD, new StateImpl(loadAtEnd));
+ stateManager.putRouteState(route, StateFactory.LOAD_AT_BEGINNING, new StateImpl(loadAtDepot));
+ stateManager.putRouteState(route, StateFactory.LOAD, new StateImpl(loadAtEnd));
iterateForward.visit(route);
iterateBackward.visit(route);
}
@@ -177,14 +176,14 @@ public class BuildPDVRPWithShipmentsAlgoFromScratchTest {
// log.info("insert job " + job2insert.getClass().toString() + " job " + job2insert + "" + job2insert.getCapacityDemand() + " in route " + inRoute.getTourActivities());
if(job2insert instanceof Delivery){
- int loadAtDepot = (int) stateManager.getRouteState(inRoute, StateTypes.LOAD_AT_DEPOT).toDouble();
+ int loadAtDepot = (int) stateManager.getRouteState(inRoute, StateFactory.LOAD_AT_BEGINNING).toDouble();
// log.info("loadAtDepot="+loadAtDepot);
- stateManager.putRouteState(inRoute, StateTypes.LOAD_AT_DEPOT, new StateImpl(loadAtDepot + job2insert.getCapacityDemand()));
+ stateManager.putRouteState(inRoute, StateFactory.LOAD_AT_BEGINNING, new StateImpl(loadAtDepot + job2insert.getCapacityDemand()));
}
if(job2insert instanceof Pickup){
- int loadAtEnd = (int) stateManager.getRouteState(inRoute, StateTypes.LOAD).toDouble();
+ int loadAtEnd = (int) stateManager.getRouteState(inRoute, StateFactory.LOAD_AT_END).toDouble();
// log.info("loadAtEnd="+loadAtEnd);
- stateManager.putRouteState(inRoute, StateTypes.LOAD, new StateImpl(loadAtEnd + job2insert.getCapacityDemand()));
+ stateManager.putRouteState(inRoute, StateFactory.LOAD_AT_END, new StateImpl(loadAtEnd + job2insert.getCapacityDemand()));
}
iterateForward.visit(inRoute);
iterateBackward.visit(inRoute);
@@ -194,11 +193,11 @@ public class BuildPDVRPWithShipmentsAlgoFromScratchTest {
bestInsertion.addListener(loadVehicleInDepot);
bestInsertion.addListener(updateLoadAfterJobHasBeenInserted);
- VehicleRoutingProblemSolution iniSolution = new CreateInitialSolution(bestInsertion, solutionCostCalculator).createInitialSolution(vrp);
+ VehicleRoutingProblemSolution iniSolution = new InsertionInitialSolutionFactory(bestInsertion, solutionCostCalculator).createSolution(vrp);
// System.out.println("ini: costs="+iniSolution.getCost()+";#routes="+iniSolution.getRoutes().size());
vra.addInitialSolution(iniSolution);
- vra.setNuOfIterations(1000);
+ vra.setNuOfIterations(100);
vra.setPrematureBreak(100);
}
diff --git a/jsprit-core/src/test/java/algorithms/CalcVehicleTypeDependentServiceInsertionTest.java b/jsprit-core/src/test/java/algorithms/CalcVehicleTypeDependentServiceInsertionTest.java
index 46ae53a6..8a6cbd27 100644
--- a/jsprit-core/src/test/java/algorithms/CalcVehicleTypeDependentServiceInsertionTest.java
+++ b/jsprit-core/src/test/java/algorithms/CalcVehicleTypeDependentServiceInsertionTest.java
@@ -29,6 +29,7 @@ import org.junit.Test;
import basics.Service;
import basics.route.TimeWindow;
import basics.route.Vehicle;
+import basics.route.VehicleFleetManager;
import basics.route.VehicleImpl;
import basics.route.VehicleRoute;
import basics.route.VehicleTypeImpl;
@@ -71,28 +72,28 @@ public class CalcVehicleTypeDependentServiceInsertionTest {
@Test
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 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.calculate(vehicleRoute, service, veh2, veh2.getEarliestDeparture(), null, Double.MAX_VALUE)).thenReturn(iDataVeh2);
- when(calc.calculate(vehicleRoute, service, veh2, veh2.getEarliestDeparture(), null, 10.0)).thenReturn(iDataVeh2);
- CalculatesVehTypeDepServiceInsertion insertion = new CalculatesVehTypeDepServiceInsertion(fleetManager,calc);
- InsertionData iData = insertion.calculate(vehicleRoute, service, null, 0.0, null, Double.MAX_VALUE);
+ when(calc.getInsertionData(vehicleRoute, service, veh1, veh1.getEarliestDeparture(), null, Double.MAX_VALUE)).thenReturn(iDataVeh1);
+ when(calc.getInsertionData(vehicleRoute, service, veh2, veh2.getEarliestDeparture(), null, Double.MAX_VALUE)).thenReturn(iDataVeh2);
+ when(calc.getInsertionData(vehicleRoute, service, veh2, veh2.getEarliestDeparture(), null, 10.0)).thenReturn(iDataVeh2);
+ VehicleTypeDependentJobInsertionCalculator insertion = new VehicleTypeDependentJobInsertionCalculator(fleetManager,calc);
+ InsertionData iData = insertion.getInsertionData(vehicleRoute, service, null, 0.0, null, Double.MAX_VALUE);
assertThat(iData.getSelectedVehicle(), is(veh1));
}
@Test
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 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.calculate(vehicleRoute, service, veh2, veh2.getEarliestDeparture(), null, Double.MAX_VALUE)).thenReturn(iDataVeh2);
- when(calc.calculate(vehicleRoute, service, veh2, veh2.getEarliestDeparture(), null, 20.0)).thenReturn(iDataVeh2);
- CalculatesVehTypeDepServiceInsertion insertion = new CalculatesVehTypeDepServiceInsertion(fleetManager,calc);
- InsertionData iData = insertion.calculate(vehicleRoute, service, null, 0.0, null, Double.MAX_VALUE);
+ when(calc.getInsertionData(vehicleRoute, service, veh1, veh1.getEarliestDeparture(), null, Double.MAX_VALUE)).thenReturn(iDataVeh1);
+ when(calc.getInsertionData(vehicleRoute, service, veh2, veh2.getEarliestDeparture(), null, Double.MAX_VALUE)).thenReturn(iDataVeh2);
+ when(calc.getInsertionData(vehicleRoute, service, veh2, veh2.getEarliestDeparture(), null, 20.0)).thenReturn(iDataVeh2);
+ VehicleTypeDependentJobInsertionCalculator insertion = new VehicleTypeDependentJobInsertionCalculator(fleetManager,calc);
+ InsertionData iData = insertion.getInsertionData(vehicleRoute, service, null, 0.0, null, Double.MAX_VALUE);
assertThat(iData.getSelectedVehicle(), is(veh2));
}
diff --git a/jsprit-core/src/test/java/algorithms/GendreauPostOptTest.java b/jsprit-core/src/test/java/algorithms/GendreauPostOptTest.java
index 01701200..481e56d4 100644
--- a/jsprit-core/src/test/java/algorithms/GendreauPostOptTest.java
+++ b/jsprit-core/src/test/java/algorithms/GendreauPostOptTest.java
@@ -29,7 +29,6 @@ import org.junit.Test;
import util.Coordinate;
import util.ManhattanDistanceCalculator;
import util.RouteUtils;
-import algorithms.StateUpdates.UpdateStates;
import basics.Job;
import basics.Service;
import basics.VehicleRoutingProblem;
@@ -38,10 +37,12 @@ import basics.costs.VehicleRoutingActivityCosts;
import basics.costs.VehicleRoutingTransportCosts;
import basics.route.Driver;
import basics.route.DriverImpl;
+import basics.route.FiniteFleetManagerFactory;
import basics.route.ServiceActivity;
import basics.route.TimeWindow;
import basics.route.TourActivities;
import basics.route.Vehicle;
+import basics.route.VehicleFleetManager;
import basics.route.VehicleImpl;
import basics.route.VehicleRoute;
import basics.route.VehicleTypeImpl;
@@ -68,13 +69,13 @@ public class GendreauPostOptTest {
Service job3;
- private StateManagerImpl states;
+ private StateManager states;
private List vehicles;
- private VehicleFleetManagerImpl fleetManager;
+ private VehicleFleetManager fleetManager;
- private JobInsertionCalculator insertionCalc;
+ private JobInsertionCostsCalculator insertionCalc;
@Before
public void setUp(){
@@ -143,17 +144,20 @@ public class GendreauPostOptTest {
vehicles = Arrays.asList(lightVehicle1,lightVehicle2, heavyVehicle);
// Collection vehicles = Arrays.asList(lightVehicle1,lightVehicle2, heavyVehicle);
- fleetManager = new VehicleFleetManagerImpl(vehicles);
- states = new StateManagerImpl();
+ fleetManager = new FiniteFleetManagerFactory(vehicles).createFleetManager();
+ states = new StateManager();
activityCosts = new ExampleActivityCostFunction();
- ServiceInsertionCalculator standardServiceInsertion = new ServiceInsertionCalculator(cost, new LocalActivityInsertionCostsCalculator(cost, activityCosts, new HardConstraints.HardTimeWindowActivityLevelConstraint(states, cost)), new HardConstraints.HardLoadConstraint(states));
+
+ ServiceInsertionCalculator standardServiceInsertion = new ServiceInsertionCalculator(cost, new LocalActivityInsertionCostsCalculator(cost, activityCosts), new HardLoadConstraint(states), new HardTimeWindowActivityLevelConstraint(states, cost));
+
+
- CalculatesServiceInsertionConsideringFixCost withFixCost = new CalculatesServiceInsertionConsideringFixCost(standardServiceInsertion, states);
+ JobInsertionConsideringFixCostsCalculator withFixCost = new JobInsertionConsideringFixCostsCalculator(standardServiceInsertion, states);
withFixCost.setWeightOfFixCost(1.2);
- insertionCalc = new CalculatesVehTypeDepServiceInsertion(fleetManager, withFixCost);
+ insertionCalc = new VehicleTypeDependentJobInsertionCalculator(fleetManager, withFixCost);
// updater = new TourStateUpdater(states, cost, activityCosts);
@@ -182,14 +186,16 @@ public class GendreauPostOptTest {
routes.add(route);
// routes.add(new VehicleRoute(getEmptyTour(),getDriver(),getNoVehicle()));
// routes.add(new VehicleRoute(getEmptyTour(),getDriver(),getNoVehicle()));
-
- VehicleRoutingProblemSolution sol = new VehicleRoutingProblemSolution(routes, states.getRouteState(route, StateTypes.COSTS).toDouble() + getFixedCosts(routes));
+
+
+ VehicleRoutingProblemSolution sol = new VehicleRoutingProblemSolution(routes, states.getRouteState(route, StateFactory.COSTS).toDouble() + getFixedCosts(routes));
+
assertEquals(110.0, sol.getCost(), 0.5);
RuinRadial radialRuin = new RuinRadial(vrp, 0.2, new JobDistanceAvgCosts(vrp.getTransportCosts()));
- radialRuin.addListener(stateUpdater);
+// radialRuin.addListener(stateUpdater);
InsertionStrategy insertionStrategy = new BestInsertion(insertionCalc);
insertionStrategy.addListener(stateUpdater);
@@ -211,10 +217,12 @@ public class GendreauPostOptTest {
return c;
}
- private double getCosts(VehicleRoutingProblemSolution newSolution, StateManagerImpl states) {
+ private double getCosts(VehicleRoutingProblemSolution newSolution, StateManager states) {
double c = 0.0;
for(VehicleRoute r : newSolution.getRoutes()){
- c += states.getRouteState(r, StateTypes.COSTS).toDouble() + r.getVehicle().getType().getVehicleCostParams().fix;
+
+ c += states.getRouteState(r, StateFactory.COSTS).toDouble() + r.getVehicle().getType().getVehicleCostParams().fix;
+
}
return c;
}
diff --git a/jsprit-core/src/test/java/algorithms/RefuseCollectionTest.java b/jsprit-core/src/test/java/algorithms/RefuseCollectionTest.java
index 0a79471e..7af0822c 100644
--- a/jsprit-core/src/test/java/algorithms/RefuseCollectionTest.java
+++ b/jsprit-core/src/test/java/algorithms/RefuseCollectionTest.java
@@ -186,8 +186,8 @@ public class RefuseCollectionTest {
vra.setPrematureBreak(100);
Collection solutions = vra.searchSolutions();
- assertEquals(397.0,Solutions.getBest(solutions).getCost(),0.01);
- assertEquals(2,Solutions.getBest(solutions).getRoutes().size());
+ assertEquals(397.0,Solutions.bestOf(solutions).getCost(),0.01);
+ assertEquals(2,Solutions.bestOf(solutions).getRoutes().size());
}
diff --git a/jsprit-core/src/test/java/algorithms/ShipmentInsertionCalculatorTest.java b/jsprit-core/src/test/java/algorithms/ShipmentInsertionCalculatorTest.java
index 5dac938a..199ff6bc 100644
--- a/jsprit-core/src/test/java/algorithms/ShipmentInsertionCalculatorTest.java
+++ b/jsprit-core/src/test/java/algorithms/ShipmentInsertionCalculatorTest.java
@@ -8,8 +8,7 @@ import org.junit.Test;
import util.Coordinate;
import util.Locations;
import util.ManhattanCosts;
-import algorithms.HardConstraints.HardActivityLevelConstraint;
-import algorithms.HardConstraints.HardRouteLevelConstraint;
+import algorithms.HardActivityLevelConstraint.ConstraintsStatus;
import basics.Shipment;
import basics.costs.VehicleRoutingActivityCosts;
import basics.costs.VehicleRoutingTransportCosts;
@@ -37,8 +36,8 @@ public class ShipmentInsertionCalculatorTest {
HardActivityLevelConstraint hardActivityLevelConstraint = new HardActivityLevelConstraint() {
@Override
- public boolean fulfilled(InsertionContext iFacts, TourActivity prevAct,TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
- return true;
+ public ConstraintsStatus fulfilled(InsertionContext iFacts, TourActivity prevAct,TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
+ return ConstraintsStatus.FULFILLED;
}
};
@@ -73,12 +72,12 @@ public class ShipmentInsertionCalculatorTest {
routingCosts = new ManhattanCosts(locations);
VehicleType type = VehicleTypeImpl.Builder.newInstance("t", 1).setCostPerDistance(1).build();
vehicle = VehicleImpl.Builder.newInstance("v").setLocationId("0,0").setType(type).build();
- activityInsertionCostsCalculator = new LocalActivityInsertionCostsCalculator(routingCosts, activityCosts, hardActivityLevelConstraint);
+ activityInsertionCostsCalculator = new LocalActivityInsertionCostsCalculator(routingCosts, activityCosts);
createInsertionCalculator(hardRouteLevelConstraint);
}
private void createInsertionCalculator(HardRouteLevelConstraint hardRouteLevelConstraint) {
- insertionCalculator = new ShipmentInsertionCalculator(routingCosts, activityInsertionCostsCalculator, hardRouteLevelConstraint);
+ insertionCalculator = new ShipmentInsertionCalculator(routingCosts, activityInsertionCostsCalculator, hardRouteLevelConstraint, hardActivityLevelConstraint);
}
@Test
@@ -86,7 +85,7 @@ public class ShipmentInsertionCalculatorTest {
Shipment shipment = Shipment.Builder.newInstance("s", 1).setPickupLocation("0,10").setDeliveryLocation("10,0").build();
VehicleRoute route = VehicleRoute.emptyRoute();
- InsertionData iData = insertionCalculator.calculate(route, shipment, vehicle, 0.0, null, Double.MAX_VALUE);
+ InsertionData iData = insertionCalculator.getInsertionData(route, shipment, vehicle, 0.0, null, Double.MAX_VALUE);
assertEquals(40.0,iData.getInsertionCost(),0.05);
}
@@ -97,7 +96,7 @@ public class ShipmentInsertionCalculatorTest {
VehicleRoute route = VehicleRoute.emptyRoute();
new Inserter(new InsertionListeners()).insertJob(shipment, new InsertionData(0,0,0,vehicle,null), route);
- InsertionData iData = insertionCalculator.calculate(route, shipment2, vehicle, 0.0, null, Double.MAX_VALUE);
+ InsertionData iData = insertionCalculator.getInsertionData(route, shipment2, vehicle, 0.0, null, Double.MAX_VALUE);
assertEquals(0.0,iData.getInsertionCost(),0.05);
assertEquals(1,iData.getPickupInsertionIndex());
assertEquals(2,iData.getDeliveryInsertionIndex());
@@ -117,8 +116,8 @@ public class ShipmentInsertionCalculatorTest {
}
});
- InsertionData iData = insertionCalculator.calculate(route, shipment2, vehicle, 0.0, null, Double.MAX_VALUE);
- assertEquals(InsertionData.noInsertionFound(),iData);
+ InsertionData iData = insertionCalculator.getInsertionData(route, shipment2, vehicle, 0.0, null, Double.MAX_VALUE);
+ assertEquals(InsertionData.createEmptyInsertionData(),iData);
}
@@ -134,7 +133,7 @@ public class ShipmentInsertionCalculatorTest {
inserter.insertJob(shipment, new InsertionData(0,0,0,vehicle,null), route);
inserter.insertJob(shipment2, new InsertionData(0,1,2,vehicle,null),route);
- InsertionData iData = insertionCalculator.calculate(route, shipment3, vehicle, 0.0, null, Double.MAX_VALUE);
+ InsertionData iData = insertionCalculator.getInsertionData(route, shipment3, vehicle, 0.0, null, Double.MAX_VALUE);
assertEquals(0.0,iData.getInsertionCost(),0.05);
assertEquals(0,iData.getPickupInsertionIndex());
assertEquals(1,iData.getDeliveryInsertionIndex());
@@ -151,7 +150,7 @@ public class ShipmentInsertionCalculatorTest {
inserter.insertJob(shipment, new InsertionData(0,0,0,vehicle,null), route);
inserter.insertJob(shipment2, new InsertionData(0,1,2,vehicle,null),route);
- InsertionData iData = insertionCalculator.calculate(route, shipment3, vehicle, 0.0, null, Double.MAX_VALUE);
+ InsertionData iData = insertionCalculator.getInsertionData(route, shipment3, vehicle, 0.0, null, Double.MAX_VALUE);
assertEquals(2.0,iData.getInsertionCost(),0.05);
assertEquals(0,iData.getPickupInsertionIndex());
assertEquals(1,iData.getDeliveryInsertionIndex());
diff --git a/jsprit-core/src/test/java/algorithms/StateUpdates.java b/jsprit-core/src/test/java/algorithms/StateUpdates.java
new file mode 100644
index 00000000..475f3405
--- /dev/null
+++ b/jsprit-core/src/test/java/algorithms/StateUpdates.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * 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 .
+ ******************************************************************************/
+package algorithms;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import basics.Job;
+import basics.algo.InsertionStartsListener;
+import basics.algo.JobInsertedListener;
+import basics.costs.VehicleRoutingActivityCosts;
+import basics.costs.VehicleRoutingTransportCosts;
+import basics.route.ReverseRouteActivityVisitor;
+import basics.route.RouteActivityVisitor;
+import basics.route.VehicleRoute;
+
+
+
+class UpdateStates implements JobInsertedListener, InsertionStartsListener{
+
+ private RouteActivityVisitor routeActivityVisitor;
+
+ private ReverseRouteActivityVisitor revRouteActivityVisitor;
+
+ private InsertionListeners insertionListeners = new InsertionListeners();
+
+ public UpdateStates(StateManager states, VehicleRoutingTransportCosts routingCosts, VehicleRoutingActivityCosts activityCosts) {
+ routeActivityVisitor = new RouteActivityVisitor();
+ routeActivityVisitor.addActivityVisitor(new UpdateActivityTimes(routingCosts));
+ routeActivityVisitor.addActivityVisitor(new UpdateCostsAtAllLevels(activityCosts, routingCosts, states));
+ routeActivityVisitor.addActivityVisitor(new UpdateLoadAtAllLevels(states));
+ routeActivityVisitor.addActivityVisitor(new UpdateMaxLoad(states));
+ revRouteActivityVisitor = new ReverseRouteActivityVisitor();
+ revRouteActivityVisitor.addActivityVisitor(new UpdateLatestOperationStartTimeAtActLocations(states, routingCosts));
+ insertionListeners.addListener(new UpdateLoadsAtStartAndEndOfRouteWhenInsertionStarts(states));
+ insertionListeners.addListener(new UpdateLoadsAtStartAndEndOfRouteWhenJobHasBeenInserted(states));
+ }
+
+ public void update(VehicleRoute route){
+ List routes = Arrays.asList(route);
+ insertionListeners.informInsertionStarts(routes, Collections.EMPTY_LIST);
+ routeActivityVisitor.visit(route);
+ revRouteActivityVisitor.visit(route);
+ }
+
+ @Override
+ public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) {
+ insertionListeners.informJobInserted(job2insert, inRoute, additionalCosts, additionalTime);
+ routeActivityVisitor.visit(inRoute);
+ revRouteActivityVisitor.visit(inRoute);
+ }
+
+ @Override
+ public void informInsertionStarts(Collection vehicleRoutes,Collection unassignedJobs) {
+ insertionListeners.informInsertionStarts(vehicleRoutes, unassignedJobs);
+ for(VehicleRoute route : vehicleRoutes) {
+ routeActivityVisitor.visit(route);
+ revRouteActivityVisitor.visit(route);
+ }
+ }
+
+ }
+
+
diff --git a/jsprit-core/src/test/java/algorithms/TestAlgorithmReader.java b/jsprit-core/src/test/java/algorithms/TestAlgorithmReader.java
index 37b70a48..95ee0f54 100644
--- a/jsprit-core/src/test/java/algorithms/TestAlgorithmReader.java
+++ b/jsprit-core/src/test/java/algorithms/TestAlgorithmReader.java
@@ -40,6 +40,7 @@ import basics.Job;
import basics.VehicleRoutingAlgorithm;
import basics.VehicleRoutingProblem;
import basics.VehicleRoutingProblemSolution;
+import basics.algo.RuinListener;
import basics.algo.SearchStrategy;
import basics.algo.SearchStrategyModule;
import basics.algo.SearchStrategyModuleListener;
diff --git a/jsprit-core/src/test/java/algorithms/TestCalculatesServiceInsertion.java b/jsprit-core/src/test/java/algorithms/TestCalculatesServiceInsertion.java
index b6c3e7fd..06c53806 100644
--- a/jsprit-core/src/test/java/algorithms/TestCalculatesServiceInsertion.java
+++ b/jsprit-core/src/test/java/algorithms/TestCalculatesServiceInsertion.java
@@ -28,7 +28,6 @@ import org.apache.log4j.Logger;
import org.junit.Before;
import org.junit.Test;
-import algorithms.StateUpdates.UpdateStates;
import basics.Job;
import basics.Service;
import basics.costs.VehicleRoutingTransportCosts;
@@ -59,7 +58,7 @@ public class TestCalculatesServiceInsertion {
private Service third;
- private StateManagerImpl states;
+ private StateManager states;
private NoDriver driver;
@@ -149,11 +148,13 @@ public class TestCalculatesServiceInsertion {
jobs.add(second);
jobs.add(third);
- states = new StateManagerImpl();
+ states = new StateManager();
ExampleActivityCostFunction activityCosts = new ExampleActivityCostFunction();
- serviceInsertion = new ServiceInsertionCalculator(costs, new LocalActivityInsertionCostsCalculator(costs, activityCosts, new HardConstraints.HardTimeWindowActivityLevelConstraint(states, costs)), new HardConstraints.HardLoadConstraint(states));
+
+ serviceInsertion = new ServiceInsertionCalculator(costs, new LocalActivityInsertionCostsCalculator(costs, activityCosts), new HardLoadConstraint(states), new HardTimeWindowActivityLevelConstraint(states, costs));
+
stateUpdater = new UpdateStates(states, costs, activityCosts);
@@ -172,7 +173,7 @@ public class TestCalculatesServiceInsertion {
VehicleRoute route = VehicleRoute.newInstance(tour,driver,vehicle);
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(0, iData.getDeliveryInsertionIndex());
}
@@ -185,7 +186,7 @@ public class TestCalculatesServiceInsertion {
VehicleRoute route = VehicleRoute.newInstance(tour,driver,vehicle);
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(0, iData.getDeliveryInsertionIndex());
}
@@ -200,7 +201,7 @@ public class TestCalculatesServiceInsertion {
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(1, iData.getDeliveryInsertionIndex());
}
@@ -215,7 +216,7 @@ public class TestCalculatesServiceInsertion {
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(1, iData.getDeliveryInsertionIndex());
}
@@ -229,7 +230,7 @@ public class TestCalculatesServiceInsertion {
VehicleRoute route = VehicleRoute.newInstance(tour,driver,vehicle);
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(2, iData.getDeliveryInsertionIndex());
}
@@ -245,7 +246,7 @@ public class TestCalculatesServiceInsertion {
// route.addActivity(states.getActivity(third,true));
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(2, iData.getDeliveryInsertionIndex());
}
diff --git a/jsprit-core/src/test/java/algorithms/TestCalculatesServiceInsertionOnRouteLevel.java b/jsprit-core/src/test/java/algorithms/TestCalculatesServiceInsertionOnRouteLevel.java
index bd27da7a..6e26383f 100644
--- a/jsprit-core/src/test/java/algorithms/TestCalculatesServiceInsertionOnRouteLevel.java
+++ b/jsprit-core/src/test/java/algorithms/TestCalculatesServiceInsertionOnRouteLevel.java
@@ -30,7 +30,6 @@ import org.junit.Test;
import util.Coordinate;
import util.ManhattanDistanceCalculator;
-import algorithms.StateUpdates.UpdateStates;
import basics.Job;
import basics.Service;
import basics.costs.VehicleRoutingTransportCosts;
@@ -48,7 +47,7 @@ import basics.route.VehicleRoute;
public class TestCalculatesServiceInsertionOnRouteLevel {
- CalculatesServiceInsertionOnRouteLevel serviceInsertion;
+ ServiceInsertionOnRouteLevelCalculator serviceInsertion;
VehicleRoutingTransportCosts costs;
@@ -62,7 +61,7 @@ public class TestCalculatesServiceInsertionOnRouteLevel {
private Service third;
- private StateManagerImpl states;
+ private StateManager states;
private NoDriver driver;
@@ -140,11 +139,11 @@ public class TestCalculatesServiceInsertionOnRouteLevel {
jobs.add(second);
jobs.add(third);
- states = new StateManagerImpl();
+ states = new StateManager();
ExampleActivityCostFunction activityCosts = new ExampleActivityCostFunction();
- ActivityInsertionCostsCalculator actInsertionCostCalculator = new RouteLevelActivityInsertionCostsEstimator(costs, activityCosts, new HardConstraints.HardTimeWindowActivityLevelConstraint(states, costs), states);
- serviceInsertion = new CalculatesServiceInsertionOnRouteLevel(costs,activityCosts, new HardConstraints.HardLoadConstraint(states), actInsertionCostCalculator);
+ ActivityInsertionCostsCalculator actInsertionCostCalculator = new RouteLevelActivityInsertionCostsEstimator(costs, activityCosts, states);
+ serviceInsertion = new ServiceInsertionOnRouteLevelCalculator(costs,activityCosts, actInsertionCostCalculator, new HardLoadConstraint(states), new HardTimeWindowActivityLevelConstraint(states, costs));
serviceInsertion.setNuOfActsForwardLooking(4);
serviceInsertion.setStates(states);
@@ -165,7 +164,7 @@ public class TestCalculatesServiceInsertionOnRouteLevel {
VehicleRoute route = VehicleRoute.newInstance(tour,driver,vehicle);
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(0, iData.getDeliveryInsertionIndex());
}
@@ -179,7 +178,7 @@ public class TestCalculatesServiceInsertionOnRouteLevel {
VehicleRoute route = VehicleRoute.newInstance(tour,driver,vehicle);
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(1, iData.getDeliveryInsertionIndex());
}
@@ -193,7 +192,7 @@ public class TestCalculatesServiceInsertionOnRouteLevel {
VehicleRoute route = VehicleRoute.newInstance(tour,driver,vehicle);
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(1, iData.getDeliveryInsertionIndex());
}
@@ -207,7 +206,7 @@ public class TestCalculatesServiceInsertionOnRouteLevel {
VehicleRoute route = VehicleRoute.newInstance(tour,driver,vehicle);
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(2, iData.getDeliveryInsertionIndex());
}
@@ -221,7 +220,7 @@ public class TestCalculatesServiceInsertionOnRouteLevel {
VehicleRoute route = VehicleRoute.newInstance(tour,driver,vehicle);
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(2, iData.getDeliveryInsertionIndex());
}
diff --git a/jsprit-core/src/test/java/algorithms/TestIterateRouteForwardInTime.java b/jsprit-core/src/test/java/algorithms/TestIterateRouteForwardInTime.java
deleted file mode 100644
index 9512765d..00000000
--- a/jsprit-core/src/test/java/algorithms/TestIterateRouteForwardInTime.java
+++ /dev/null
@@ -1,214 +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 .
- ******************************************************************************/
-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 algorithms.StateUpdates.UpdateActivityTimes;
-import algorithms.StateUpdates.UpdateCostsAtAllLevels;
-import algorithms.StateUpdates.UpdateEarliestStartTimeWindowAtActLocations;
-import algorithms.StateUpdates.UpdateLoadAtAllLevels;
-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;
-
- StateManagerImpl 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 services = new ArrayList();
- 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 StateManagerImpl();
- }
-
- @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,StateTypes.LOAD).toDouble(), 0.01);
- assertEquals(10.0, stateManager.getActivityState(secondAct,StateTypes.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, StateTypes.COSTS).toDouble(),0.05);
- assertEquals(5.0, stateManager.getActivityState(firstAct, StateTypes.LOAD).toDouble(),0.05);
- assertEquals(10.0, stateManager.getActivityState(firstAct, StateTypes.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, StateTypes.COSTS).toDouble(),0.05);
- assertEquals(10.0, stateManager.getActivityState(secondAct, StateTypes.LOAD).toDouble(),0.05);
- assertEquals(30.0, stateManager.getActivityState(secondAct, StateTypes.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,StateTypes.COSTS).toDouble(), 0.05);
- assertEquals(40.0, vehicleRoute.getEnd().getArrTime(),0.05);
- assertEquals(50.0, vehicleRoute.getEnd().getTheoreticalLatestOperationStartTime(),0.05);
- }
-
-}
diff --git a/jsprit-core/src/test/java/algorithms/TestJobDistanceAvgCosts.java b/jsprit-core/src/test/java/algorithms/TestJobDistanceAvgCosts.java
index 9f8a5216..c4caa271 100644
--- a/jsprit-core/src/test/java/algorithms/TestJobDistanceAvgCosts.java
+++ b/jsprit-core/src/test/java/algorithms/TestJobDistanceAvgCosts.java
@@ -56,7 +56,7 @@ public class TestJobDistanceAvgCosts {
}
};
JobDistanceAvgCosts c = new JobDistanceAvgCosts(costs);
- c.calculateDistance(Service.Builder.newInstance("1", 1).setLocationId("foo").build(), Service.Builder.newInstance("2", 2).setLocationId("foo").build());
+ c.getDistance(Service.Builder.newInstance("1", 1).setLocationId("foo").build(), Service.Builder.newInstance("2", 2).setLocationId("foo").build());
}
@Test(expected=NullPointerException.class)
@@ -92,7 +92,7 @@ public class TestJobDistanceAvgCosts {
}
};
JobDistanceAvgCosts c = new JobDistanceAvgCosts(costs);
- c.calculateDistance(Service.Builder.newInstance("1", 1).setLocationId("loc").build(), Service.Builder.newInstance("2", 2).setLocationId("loc").build());
+ c.getDistance(Service.Builder.newInstance("1", 1).setLocationId("loc").build(), Service.Builder.newInstance("2", 2).setLocationId("loc").build());
}
}
diff --git a/jsprit-core/src/test/java/algorithms/TestTourStateUpdaterWithService.java b/jsprit-core/src/test/java/algorithms/TestTourStateUpdaterWithService.java
index 31014486..476167b0 100644
--- a/jsprit-core/src/test/java/algorithms/TestTourStateUpdaterWithService.java
+++ b/jsprit-core/src/test/java/algorithms/TestTourStateUpdaterWithService.java
@@ -26,7 +26,6 @@ import org.junit.Test;
import util.Coordinate;
import util.ManhattanDistanceCalculator;
-import algorithms.StateUpdates.UpdateStates;
import basics.Job;
import basics.Service;
import basics.costs.VehicleRoutingTransportCosts;
@@ -53,7 +52,7 @@ public class TestTourStateUpdaterWithService {
UpdateStates updateStates;
- StateManagerImpl states;
+ StateManager states;
private VehicleRoute vehicleRoute;
@@ -100,9 +99,9 @@ public class TestTourStateUpdaterWithService {
services.add(firstService);
services.add(secondService);
- states = new StateManagerImpl();
+ states = new StateManager();
- VehicleTypeImpl type = VehicleTypeImpl.Builder.newInstance("test", 0).build();
+ VehicleTypeImpl type = VehicleTypeImpl.Builder.newInstance("test", 10).build();
vehicle = VehicleImpl.Builder.newInstance("testvehicle").setType(type).setLocationId("0,0")
.setEarliestStart(0.0).setLatestArrival(50.0).build();
@@ -119,8 +118,8 @@ public class TestTourStateUpdaterWithService {
@Test
public void testCalculatedCost() {
updateStates.update(vehicleRoute);
- assertEquals(40.0, states.getRouteState(vehicleRoute,StateTypes.COSTS).toDouble(), 0.05);
- assertEquals(10, states.getRouteState(vehicleRoute, StateTypes.LOAD).toDouble(), 0.05);
+ assertEquals(40.0, states.getRouteState(vehicleRoute,StateFactory.COSTS).toDouble(), 0.05);
+ assertEquals(10, states.getRouteState(vehicleRoute, StateFactory.LOAD).toDouble(), 0.05);
}
@Test
@@ -136,27 +135,27 @@ public class TestTourStateUpdaterWithService {
@Test
public void testStatesOfAct1(){
updateStates.update(vehicleRoute);
- assertEquals(10.0, states.getActivityState(tour.getActivities().get(0), StateTypes.COSTS).toDouble(),0.05);
- assertEquals(5.0, states.getActivityState(tour.getActivities().get(0), StateTypes.LOAD).toDouble(),0.05);
+ assertEquals(10.0, states.getActivityState(tour.getActivities().get(0), StateFactory.COSTS).toDouble(),0.05);
+ assertEquals(5.0, states.getActivityState(tour.getActivities().get(0), StateFactory.LOAD).toDouble(),0.05);
// assertEquals(10.0, states.getActivityState(tour.getActivities().get(0), StateTypes.EARLIEST_OPERATION_START_TIME).toDouble(),0.05);
- assertEquals(20.0, states.getActivityState(tour.getActivities().get(0), StateTypes.LATEST_OPERATION_START_TIME).toDouble(),0.05);
+ assertEquals(20.0, states.getActivityState(tour.getActivities().get(0), StateFactory.LATEST_OPERATION_START_TIME).toDouble(),0.05);
}
@Test
public void testStatesOfAct2(){
updateStates.update(vehicleRoute);
- assertEquals(30.0, states.getActivityState(tour.getActivities().get(1), StateTypes.COSTS).toDouble(),0.05);
- assertEquals(10.0, states.getActivityState(tour.getActivities().get(1), StateTypes.LOAD).toDouble(),0.05);
+ assertEquals(30.0, states.getActivityState(tour.getActivities().get(1), StateFactory.COSTS).toDouble(),0.05);
+ assertEquals(10.0, states.getActivityState(tour.getActivities().get(1), StateFactory.LOAD).toDouble(),0.05);
// assertEquals(10.0, states.getActivityState(tour.getActivities().get(0), StateTypes.EARLIEST_OPERATION_START_TIME).toDouble(),0.05);
- assertEquals(40.0, states.getActivityState(tour.getActivities().get(1), StateTypes.LATEST_OPERATION_START_TIME).toDouble(),0.05);
+ assertEquals(40.0, states.getActivityState(tour.getActivities().get(1), StateFactory.LATEST_OPERATION_START_TIME).toDouble(),0.05);
}
@Test
public void testStatesOfAct3(){
updateStates.update(vehicleRoute);
- assertEquals(40.0, states.getRouteState(vehicleRoute, StateTypes.COSTS).toDouble(), 0.05);
+ assertEquals(40.0, states.getRouteState(vehicleRoute, StateFactory.COSTS).toDouble(), 0.05);
assertEquals(40.0, vehicleRoute.getEnd().getArrTime(),0.05);
assertEquals(50.0, vehicleRoute.getEnd().getTheoreticalLatestOperationStartTime(),0.05);
}
diff --git a/jsprit-core/src/test/java/algorithms/TestVehicleFleetManager.java b/jsprit-core/src/test/java/algorithms/TestVehicleFleetManager.java
index c909e72d..5b6fa031 100644
--- a/jsprit-core/src/test/java/algorithms/TestVehicleFleetManager.java
+++ b/jsprit-core/src/test/java/algorithms/TestVehicleFleetManager.java
@@ -21,8 +21,10 @@ import java.util.Collection;
import java.util.List;
import junit.framework.TestCase;
+import basics.route.FiniteFleetManagerFactory;
import basics.route.PenaltyVehicleType;
import basics.route.Vehicle;
+import basics.route.VehicleFleetManager;
import basics.route.VehicleImpl;
import basics.route.VehicleTypeImpl;
@@ -42,7 +44,7 @@ public class TestVehicleFleetManager extends TestCase{
vehicles.add(v1);
vehicles.add(v2);
- fleetManager = new VehicleFleetManagerImpl(vehicles);
+ fleetManager = new FiniteFleetManagerFactory(vehicles).createFleetManager();
}
public void testGetVehicles(){
@@ -94,7 +96,7 @@ public class TestVehicleFleetManager extends TestCase{
vehicles.add(v1);
vehicles.add(v2);
vehicles.add(penalty4standard);
- VehicleFleetManager fleetManager = new VehicleFleetManagerImpl(vehicles);
+ VehicleFleetManager fleetManager = new FiniteFleetManagerFactory(vehicles).createFleetManager();
Collection availableVehicles = fleetManager.getAvailableVehicles();
assertEquals(2, availableVehicles.size());
@@ -115,7 +117,7 @@ public class TestVehicleFleetManager extends TestCase{
vehicles.add(v2);
vehicles.add(penalty4standard);
vehicles.add(v3);
- VehicleFleetManager fleetManager = new VehicleFleetManagerImpl(vehicles);
+ VehicleFleetManager fleetManager = new FiniteFleetManagerFactory(vehicles).createFleetManager();
fleetManager.lock(v1);
fleetManager.lock(v2);
Collection availableVehicles = fleetManager.getAvailableVehicles();
@@ -133,7 +135,7 @@ public class TestVehicleFleetManager extends TestCase{
vehicles.add(v1);
vehicles.add(v2);
vehicles.add(penalty4standard);
- VehicleFleetManager fleetManager = new VehicleFleetManagerImpl(vehicles);
+ VehicleFleetManager fleetManager = new FiniteFleetManagerFactory(vehicles).createFleetManager();
fleetManager.lock(v1);
fleetManager.lock(v2);
Collection availableVehicles = fleetManager.getAvailableVehicles();
diff --git a/jsprit-core/src/test/resources/pd_solomon_c101_sol.xml b/jsprit-core/src/test/resources/pd_solomon_c101_sol.xml
index c8bcecc8..1d5bfbc5 100644
--- a/jsprit-core/src/test/resources/pd_solomon_c101_sol.xml
+++ b/jsprit-core/src/test/resources/pd_solomon_c101_sol.xml
@@ -2534,83 +2534,18 @@
- 853.276595840535
+ 1484.6058277010336
- 571.5178932313771
+ 654.4873603381584
noDriver
solomonVehicle
0.0
-
- 20
- 0.0
- 0.0
-
-
- 21
- 0.0
- 0.0
-
-
- 23
- 0.0
- 0.0
-
-
- 28
- 0.0
- 0.0
-
-
- 17
- 0.0
- 0.0
-
-
- 15
- 0.0
- 0.0
-
-
- 11
- 0.0
- 0.0
-
10
0.0
0.0
-
- 8
- 0.0
- 0.0
-
-
- 13
- 0.0
- 0.0
-
-
- 26
- 0.0
- 0.0
-
-
- 18
- 0.0
- 0.0
-
-
- 22
- 0.0
- 0.0
-
-
- 19
- 0.0
- 0.0
-
7
0.0
@@ -2622,107 +2557,72 @@
0.0
- 75
+ 22
0.0
0.0
- 95
+ 21
0.0
0.0
- 92
+ 20
0.0
0.0
- 4
+ 50
0.0
0.0
- 96
+ 52
0.0
0.0
- 2
+ 42
0.0
0.0
- 93
+ 41
0.0
0.0
- 94
+ 45
0.0
0.0
- 98
+ 48
0.0
0.0
- 97
+ 44
0.0
0.0
- 99
+ 46
0.0
0.0
- 1
+ 40
0.0
0.0
- 3
+ 51
0.0
0.0
- 9
- 0.0
- 0.0
-
-
- 100
- 0.0
- 0.0
-
-
- 6
- 0.0
- 0.0
-
-
- 30
- 0.0
- 0.0
-
-
- 36
- 0.0
- 0.0
-
-
- 25
- 0.0
- 0.0
-
-
- 27
- 0.0
- 0.0
-
-
- 24
+ 31
0.0
0.0
@@ -2736,440 +2636,330 @@
0.0
0.0
+
+ 36
+ 0.0
+ 0.0
+
33
0.0
0.0
- 29
+ 65
0.0
0.0
- 53
+ 63
0.0
0.0
- 81
+ 66
0.0
0.0
- 71
+ 62
0.0
0.0
- 77
+ 68
0.0
0.0
- 79
+ 54
0.0
0.0
- 80
+ 58
0.0
0.0
- 78
- 0.0
- 0.0
-
-
- 70
- 0.0
- 0.0
-
-
- 76
- 0.0
- 0.0
-
-
- 73
- 0.0
- 0.0
-
-
- 38
- 0.0
- 0.0
-
-
- 39
- 0.0
- 0.0
-
-
- 16
- 0.0
- 0.0
-
-
- 14
- 0.0
- 0.0
-
-
- 37
- 0.0
- 0.0
-
-
- 35
- 0.0
- 0.0
-
-
- 12
+ 100
0.0
0.0
- 35
+ 100
38.07886552931954
38.07886552931954
-
- 37
- 43.90981742416484
- 43.90981742416484
+
+ 92
+ 76.15773105863909
+ 76.15773105863909
-
- 39
- 49.29498223129934
- 49.29498223129934
+
+ 82
+ 76.15773105863909
+ 76.15773105863909
-
- 38
- 54.29498223129934
- 54.29498223129934
-
-
- 16
- 103.53927124027987
- 103.53927124027987
-
-
- 14
- 105.53927124027987
- 105.53927124027987
-
-
- 12
- 108.53927124027987
- 108.53927124027987
-
-
- 73
- 195.22260297135722
- 195.22260297135722
-
-
- 70
- 198.22260297135722
- 198.22260297135722
-
-
- 76
- 205.2936707832227
- 205.2936707832227
-
-
- 78
- 207.2936707832227
- 207.2936707832227
-
-
- 71
- 214.2936707832227
- 214.2936707832227
-
-
- 77
- 222.89599605026532
- 222.89599605026532
-
-
- 79
- 223.89599605026532
- 223.89599605026532
-
-
- 80
- 229.28116085739984
- 229.28116085739984
-
-
- 81
- 239.28116085739984
- 239.28116085739984
+
+ 53
+ 76.15773105863909
+ 76.15773105863909
53
- 290.084704040922
- 290.084704040922
+ 121.33515905094515
+ 121.33515905094515
- 32
- 338.8801956359454
- 338.8801956359454
-
-
- 33
- 340.8801956359454
- 340.8801956359454
-
-
- 36
- 346.71114753079075
- 346.71114753079075
-
-
- 34
- 349.71114753079075
- 349.71114753079075
-
-
- 29
- 362.71114753079075
- 362.71114753079075
-
-
- 24
- 367.71114753079075
- 367.71114753079075
-
-
- 25
- 369.71114753079075
- 369.71114753079075
-
-
- 27
- 371.71114753079075
- 371.71114753079075
-
-
- 30
- 375.95378821791
- 375.95378821791
-
-
- 9
- 399.38453724563
- 399.38453724563
-
-
- 6
- 401.62060522312976
- 401.62060522312976
-
-
- 100
- 423.55231742259105
- 423.55231742259105
-
-
- 97
- 428.55231742259105
- 428.55231742259105
-
-
- 93
- 433.55231742259105
- 433.55231742259105
+ 82
+ 180.16542337127606
+ 180.16542337127606
92
- 435.55231742259105
- 435.55231742259105
+ 211.2137727637961
+ 211.2137727637961
+
+
+ 39
+ 255.4178449743968
+ 255.4178449743968
+
+
+ 35
+ 255.4178449743968
+ 255.4178449743968
- 94
- 439.15786869805504
- 439.15786869805504
+ 35
+ 293.4967105037163
+ 293.4967105037163
- 95
- 442.76341997351904
- 442.76341997351904
+ 39
+ 304.6770503912153
+ 304.6770503912153
+
+
+ 60
+ 344.988339132708
+ 344.988339132708
+
+
+ 56
+ 344.988339132708
+ 344.988339132708
+
+
+ 57
+ 344.988339132708
+ 344.988339132708
+
+
+ 59
+ 344.988339132708
+ 344.988339132708
+
+
+ 55
+ 344.988339132708
+ 344.988339132708
- 96
- 444.76341997351904
- 444.76341997351904
+ 55
+ 380.0454354186242
+ 380.0454354186242
- 99
- 449.76341997351904
- 449.76341997351904
+ 59
+ 384.0454354186242
+ 384.0454354186242
- 98
- 455.59437186836436
- 455.59437186836436
+ 57
+ 386.0454354186242
+ 386.0454354186242
- 2
- 469.5227601455485
- 469.5227601455485
+ 56
+ 396.0454354186242
+ 396.0454354186242
- 1
- 471.5227601455485
- 471.5227601455485
+ 60
+ 401.0454354186242
+ 401.0454354186242
- 75
- 474.5227601455485
- 474.5227601455485
+ 58
+ 404.0454354186242
+ 404.0454354186242
- 4
- 478.76540083266775
- 478.76540083266775
+ 54
+ 410.44855965605706
+ 410.44855965605706
- 7
- 481.59382795741396
- 481.59382795741396
+ 68
+ 430.67230807221375
+ 430.67230807221375
- 3
- 483.59382795741396
- 483.59382795741396
+ 62
+ 437.7433758840792
+ 437.7433758840792
- 5
- 484.59382795741396
- 484.59382795741396
+ 66
+ 440.7433758840792
+ 440.7433758840792
- 8
- 489.59382795741396
- 489.59382795741396
+ 63
+ 446.57432777892456
+ 446.57432777892456
- 10
- 493.19937923287796
- 493.19937923287796
+ 65
+ 448.57432777892456
+ 448.57432777892456
+
+
+ 37
+ 461.38057625379025
+ 461.38057625379025
+
+
+ 38
+ 461.38057625379025
+ 461.38057625379025
- 11
- 496.19937923287796
- 496.19937923287796
+ 38
+ 502.61163250996685
+ 502.61163250996685
- 13
- 510.51720029615433
- 510.51720029615433
+ 37
+ 504.61163250996685
+ 504.61163250996685
- 15
- 515.9023651032888
- 515.9023651032888
+ 33
+ 510.61163250996685
+ 510.61163250996685
- 19
- 520.9023651032888
- 520.9023651032888
+ 36
+ 516.4425844048121
+ 516.4425844048121
- 18
- 525.9023651032888
- 525.9023651032888
+ 34
+ 519.4425844048121
+ 519.4425844048121
- 17
- 528.9023651032888
- 528.9023651032888
+ 32
+ 524.8277492119466
+ 524.8277492119466
- 28
- 549.5178932313771
- 549.5178932313771
+ 31
+ 529.8277492119466
+ 529.8277492119466
- 26
- 551.5178932313771
- 551.5178932313771
+ 51
+ 545.6391375127886
+ 545.6391375127886
- 23
- 554.5178932313771
- 554.5178932313771
+ 40
+ 555.6391375127886
+ 555.6391375127886
- 22
- 557.5178932313771
- 557.5178932313771
+ 46
+ 561.0243023199231
+ 561.0243023199231
- 21
- 559.5178932313771
- 559.5178932313771
+ 44
+ 563.8527294446693
+ 563.8527294446693
+
+
+ 48
+ 567.8527294446693
+ 567.8527294446693
+
+
+ 45
+ 569.8527294446693
+ 569.8527294446693
+
+
+ 41
+ 575.2378942518038
+ 575.2378942518038
+
+
+ 42
+ 577.2378942518038
+ 577.2378942518038
+
+
+ 52
+ 585.7818979971214
+ 585.7818979971214
+
+
+ 50
+ 588.9441756572897
+ 588.9441756572897
20
- 561.5178932313771
- 561.5178932313771
+ 607.3832645718755
+ 607.3832645718755
- 571.5178932313771
+
+ 21
+ 609.3832645718755
+ 609.3832645718755
+
+
+ 22
+ 611.3832645718755
+ 611.3832645718755
+
+
+ 5
+ 630.4882377464183
+ 630.4882377464183
+
+
+ 7
+ 632.7243057239182
+ 632.7243057239182
+
+
+ 10
+ 637.7243057239182
+ 637.7243057239182
+
+ 654.4873603381584
- 281.7587026091579
+ 830.1184673628752
noDriver
solomonVehicle
0.0
- 45
- 0.0
- 0.0
-
-
- 46
- 0.0
- 0.0
-
-
- 41
- 0.0
- 0.0
-
-
- 42
- 0.0
- 0.0
-
-
- 48
- 0.0
- 0.0
-
-
- 51
- 0.0
- 0.0
-
-
- 49
- 0.0
- 0.0
-
-
- 52
- 0.0
- 0.0
-
-
- 40
+ 67
0.0
0.0
@@ -3179,7 +2969,7 @@
0.0
- 50
+ 49
0.0
0.0
@@ -3189,142 +2979,52 @@
0.0
- 44
+ 8
0.0
0.0
- 57
+ 6
0.0
0.0
- 60
+ 11
0.0
0.0
- 55
+ 9
0.0
0.0
- 69
+ 15
0.0
0.0
- 56
+ 18
0.0
0.0
- 58
+ 3
0.0
0.0
- 66
+ 4
0.0
0.0
- 54
+ 75
0.0
0.0
- 59
- 0.0
- 0.0
-
-
- 68
- 0.0
- 0.0
-
-
- 74
- 0.0
- 0.0
-
-
- 65
- 0.0
- 0.0
-
-
- 64
- 0.0
- 0.0
-
-
- 63
- 0.0
- 0.0
-
-
- 62
- 0.0
- 0.0
-
-
- 72
- 0.0
- 0.0
-
-
- 61
- 0.0
- 0.0
-
-
- 67
- 0.0
- 0.0
-
-
- 82
- 0.0
- 0.0
-
-
- 85
- 0.0
- 0.0
-
-
- 91
- 0.0
- 0.0
-
-
- 86
- 0.0
- 0.0
-
-
- 89
- 0.0
- 0.0
-
-
- 87
- 0.0
- 0.0
-
-
- 88
- 0.0
- 0.0
-
-
- 84
- 0.0
- 0.0
-
-
- 90
+ 1
0.0
0.0
@@ -3334,221 +3034,521 @@
0.0
- 31
+ 88
+ 0.0
+ 0.0
+
+
+ 74
+ 0.0
+ 0.0
+
+
+ 72
+ 0.0
+ 0.0
+
+
+ 69
+ 0.0
+ 0.0
+
+
+ 64
+ 0.0
+ 0.0
+
+
+ 61
+ 0.0
+ 0.0
+
+
+ 76
+ 0.0
+ 0.0
+
+
+ 78
+ 0.0
+ 0.0
+
+
+ 97
+ 0.0
+ 0.0
+
+
+ 95
+ 0.0
+ 0.0
+
+
+ 2
+ 0.0
+ 0.0
+
+
+ 99
+ 0.0
+ 0.0
+
+
+ 96
+ 0.0
+ 0.0
+
+
+ 94
+ 0.0
+ 0.0
+
+
+ 98
+ 0.0
+ 0.0
+
+
+ 19
0.0
0.0
- 31
- 33.54101966249684
- 33.54101966249684
+ 19
+ 39.05124837953327
+ 39.05124837953327
- 91
- 89.44271909999159
- 89.44271909999159
+ 98
+ 82.34097002336
+ 82.34097002336
- 88
- 94.44271909999159
- 94.44271909999159
+ 94
+ 92.24046495997166
+ 92.24046495997166
- 85
- 97.44271909999159
- 97.44271909999159
+ 96
+ 97.62562976710616
+ 97.62562976710616
- 84
- 100.27114622473778
- 100.27114622473778
+ 99
+ 102.62562976710616
+ 102.62562976710616
- 82
- 106.10209811958308
- 106.10209811958308
+ 2
+ 116.76776539083711
+ 116.76776539083711
+
+
+ 93
+ 137.38329351892543
+ 137.38329351892543
+
+
+ 71
+ 137.38329351892543
+ 137.38329351892543
+
+
+ 73
+ 137.38329351892543
+ 137.38329351892543
+
+
+ 81
+ 137.38329351892543
+ 137.38329351892543
- 83
- 109.10209811958308
- 109.10209811958308
+ 81
+ 184.8174584214511
+ 184.8174584214511
- 86
- 115.10209811958308
- 115.10209811958308
+ 73
+ 193.41978368849374
+ 193.41978368849374
- 87
- 116.10209811958308
- 116.10209811958308
+ 71
+ 199.25073558333904
+ 199.25073558333904
- 89
- 119.70764939504707
- 119.70764939504707
+ 93
+ 257.56025453179205
+ 257.56025453179205
- 90
- 123.95029008216636
- 123.95029008216636
+ 95
+ 263.3912064266374
+ 263.3912064266374
- 63
- 141.9780464594863
- 141.9780464594863
+ 97
+ 268.7763712337719
+ 268.7763712337719
+
+
+ 77
+ 309.0876599752646
+ 309.0876599752646
+
+
+ 80
+ 309.0876599752646
+ 309.0876599752646
+
+
+ 70
+ 309.0876599752646
+ 309.0876599752646
+
+
+ 79
+ 309.0876599752646
+ 309.0876599752646
- 65
- 143.9780464594863
- 143.9780464594863
+ 79
+ 360.16603113175313
+ 360.16603113175313
- 67
- 144.9780464594863
- 144.9780464594863
+ 70
+ 368.16603113175313
+ 368.16603113175313
- 66
- 149.9780464594863
- 149.9780464594863
+ 80
+ 379.3463710192521
+ 379.3463710192521
- 62
- 152.9780464594863
- 152.9780464594863
+ 77
+ 385.17732291409743
+ 385.17732291409743
- 74
- 155.9780464594863
- 155.9780464594863
+ 78
+ 390.17732291409743
+ 390.17732291409743
- 72
- 160.9780464594863
- 160.9780464594863
+ 76
+ 392.17732291409743
+ 392.17732291409743
61
- 163.9780464594863
- 163.9780464594863
+ 432.48861165559015
+ 432.48861165559015
64
- 165.9780464594863
- 165.9780464594863
+ 434.48861165559015
+ 434.48861165559015
69
- 171.8089983543316
- 171.8089983543316
+ 440.3195635504355
+ 440.3195635504355
- 68
- 176.8089983543316
- 176.8089983543316
+ 72
+ 449.7535446824921
+ 449.7535446824921
- 55
- 192.10605689510996
- 192.10605689510996
+ 74
+ 454.7535446824921
+ 454.7535446824921
+
+
+ 84
+ 474.6029779237713
+ 474.6029779237713
+
+
+ 85
+ 474.6029779237713
+ 474.6029779237713
+
+
+ 86
+ 474.6029779237713
+ 474.6029779237713
+
+
+ 89
+ 474.6029779237713
+ 474.6029779237713
+
+
+ 87
+ 474.6029779237713
+ 474.6029779237713
+
+
+ 91
+ 474.6029779237713
+ 474.6029779237713
+
+
+ 90
+ 474.6029779237713
+ 474.6029779237713
- 54
- 197.10605689510996
- 197.10605689510996
+ 90
+ 495.2185060518596
+ 495.2185060518596
- 56
- 202.49122170224447
- 202.49122170224447
+ 91
+ 500.2185060518596
+ 500.2185060518596
- 58
- 204.49122170224447
- 204.49122170224447
+ 87
+ 507.2895738637251
+ 507.2895738637251
- 60
- 207.49122170224447
- 207.49122170224447
+ 89
+ 510.8951251391891
+ 510.8951251391891
- 59
- 217.931528211155
- 217.931528211155
+ 86
+ 515.1377658263084
+ 515.1377658263084
- 57
- 219.931528211155
- 219.931528211155
+ 85
+ 520.5229306334429
+ 520.5229306334429
- 40
- 235.7429165119969
- 235.7429165119969
+ 84
+ 523.3513577581891
+ 523.3513577581891
- 41
- 237.7429165119969
- 237.7429165119969
+ 88
+ 528.7365225653236
+ 528.7365225653236
- 42
- 239.7429165119969
- 239.7429165119969
+ 83
+ 537.3388478323662
+ 537.3388478323662
- 44
- 241.9789844894967
- 241.9789844894967
+ 1
+ 567.3054959599096
+ 567.3054959599096
- 45
- 243.9789844894967
- 243.9789844894967
+ 75
+ 570.3054959599096
+ 570.3054959599096
- 46
- 245.9789844894967
- 245.9789844894967
+ 4
+ 574.548136647029
+ 574.548136647029
- 48
- 248.80741161424288
- 248.80741161424288
+ 3
+ 576.548136647029
+ 576.548136647029
+
+
+ 12
+ 592.672652143626
+ 592.672652143626
+
+
+ 17
+ 592.672652143626
+ 592.672652143626
+
+
+ 14
+ 592.672652143626
+ 592.672652143626
+
+
+ 16
+ 592.672652143626
+ 592.672652143626
+
+
+ 13
+ 592.672652143626
+ 592.672652143626
- 51
- 251.80741161424288
- 251.80741161424288
+ 13
+ 623.4784957451247
+ 623.4784957451247
- 50
- 254.04347959174268
- 254.04347959174268
+ 16
+ 633.6765347723103
+ 633.6765347723103
- 52
- 257.20575725191105
- 257.20575725191105
+ 14
+ 635.6765347723103
+ 635.6765347723103
+
+
+ 17
+ 646.4468643865794
+ 646.4468643865794
+
+
+ 12
+ 658.653420002313
+ 658.653420002313
+
+
+ 18
+ 672.795555626044
+ 672.795555626044
+
+
+ 15
+ 679.8666234379095
+ 679.8666234379095
+
+
+ 9
+ 700.4578837198835
+ 700.4578837198835
+
+
+ 11
+ 703.6201613800519
+ 703.6201613800519
+
+
+ 6
+ 708.6201613800519
+ 708.6201613800519
+
+
+ 8
+ 710.8562293575517
+ 710.8562293575517
+
+
+ 24
+ 728.9669996338265
+ 728.9669996338265
+
+
+ 26
+ 728.9669996338265
+ 728.9669996338265
+
+
+ 25
+ 728.9669996338265
+ 728.9669996338265
+
+
+ 30
+ 728.9669996338265
+ 728.9669996338265
+
+
+ 28
+ 728.9669996338265
+ 728.9669996338265
+
+
+ 23
+ 728.9669996338265
+ 728.9669996338265
+
+
+ 27
+ 728.9669996338265
+ 728.9669996338265
+
+
+ 29
+ 728.9669996338265
+ 728.9669996338265
+
+
+ 29
+ 748.9669996338265
+ 748.9669996338265
+
+
+ 27
+ 752.5725509092905
+ 752.5725509092905
+
+
+ 23
+ 758.4035028041358
+ 758.4035028041358
+
+
+ 28
+ 763.4035028041358
+ 763.4035028041358
+
+
+ 30
+ 766.4035028041358
+ 766.4035028041358
+
+
+ 25
+ 772.234454698981
+ 772.234454698981
+
+
+ 26
+ 775.234454698981
+ 775.234454698981
+
+
+ 24
+ 780.234454698981
+ 780.234454698981
+
+
+ 47
+ 796.045842999823
+ 796.045842999823
49
- 260.20575725191105
- 260.20575725191105
-
-
- 47
- 262.20575725191105
- 262.20575725191105
+ 798.045842999823
+ 798.045842999823
43
- 265.20575725191105
- 265.20575725191105
+ 803.045842999823
+ 803.045842999823
- 281.7587026091579
+
+ 67
+ 817.9119117471415
+ 817.9119117471415
+
+ 830.1184673628752
diff --git a/jsprit-examples/src/main/java/examples/SolomonExample.java b/jsprit-examples/src/main/java/examples/SolomonExample.java
index 013dc833..d72997bc 100644
--- a/jsprit-examples/src/main/java/examples/SolomonExample.java
+++ b/jsprit-examples/src/main/java/examples/SolomonExample.java
@@ -69,7 +69,7 @@ public class SolomonExample {
*/
// VehicleRoutingAlgorithm vra = new SchrimpfFactory().createAlgorithm(vrp);
VehicleRoutingAlgorithm vra = VehicleRoutingAlgorithms.readAndCreateAlgorithm(vrp, "input/algorithmConfig_solomon.xml");
- vra.setPrematureBreak(100);
+// vra.setPrematureBreak(100);
// vra.getAlgorithmListeners().addListener(new AlgorithmSearchProgressChartListener("output/sol_progress.png"));
/*
* Solve the problem.
diff --git a/license.txt b/license.txt
deleted file mode 100644
index 4fdfe74d..00000000
--- a/license.txt
+++ /dev/null
@@ -1,165 +0,0 @@
- GNU LESSER GENERAL PUBLIC LICENSE
- Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc.
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-
- This version of the GNU Lesser General Public License incorporates
-the terms and conditions of version 3 of the GNU General Public
-License, supplemented by the additional permissions listed below.
-
- 0. Additional Definitions.
-
- As used herein, "this License" refers to version 3 of the GNU Lesser
-General Public License, and the "GNU GPL" refers to version 3 of the GNU
-General Public License.
-
- "The Library" refers to a covered work governed by this License,
-other than an Application or a Combined Work as defined below.
-
- An "Application" is any work that makes use of an interface provided
-by the Library, but which is not otherwise based on the Library.
-Defining a subclass of a class defined by the Library is deemed a mode
-of using an interface provided by the Library.
-
- A "Combined Work" is a work produced by combining or linking an
-Application with the Library. The particular version of the Library
-with which the Combined Work was made is also called the "Linked
-Version".
-
- The "Minimal Corresponding Source" for a Combined Work means the
-Corresponding Source for the Combined Work, excluding any source code
-for portions of the Combined Work that, considered in isolation, are
-based on the Application, and not on the Linked Version.
-
- The "Corresponding Application Code" for a Combined Work means the
-object code and/or source code for the Application, including any data
-and utility programs needed for reproducing the Combined Work from the
-Application, but excluding the System Libraries of the Combined Work.
-
- 1. Exception to Section 3 of the GNU GPL.
-
- You may convey a covered work under sections 3 and 4 of this License
-without being bound by section 3 of the GNU GPL.
-
- 2. Conveying Modified Versions.
-
- If you modify a copy of the Library, and, in your modifications, a
-facility refers to a function or data to be supplied by an Application
-that uses the facility (other than as an argument passed when the
-facility is invoked), then you may convey a copy of the modified
-version:
-
- a) under this License, provided that you make a good faith effort to
- ensure that, in the event an Application does not supply the
- function or data, the facility still operates, and performs
- whatever part of its purpose remains meaningful, or
-
- b) under the GNU GPL, with none of the additional permissions of
- this License applicable to that copy.
-
- 3. Object Code Incorporating Material from Library Header Files.
-
- The object code form of an Application may incorporate material from
-a header file that is part of the Library. You may convey such object
-code under terms of your choice, provided that, if the incorporated
-material is not limited to numerical parameters, data structure
-layouts and accessors, or small macros, inline functions and templates
-(ten or fewer lines in length), you do both of the following:
-
- a) Give prominent notice with each copy of the object code that the
- Library is used in it and that the Library and its use are
- covered by this License.
-
- b) Accompany the object code with a copy of the GNU GPL and this license
- document.
-
- 4. Combined Works.
-
- You may convey a Combined Work under terms of your choice that,
-taken together, effectively do not restrict modification of the
-portions of the Library contained in the Combined Work and reverse
-engineering for debugging such modifications, if you also do each of
-the following:
-
- a) Give prominent notice with each copy of the Combined Work that
- the Library is used in it and that the Library and its use are
- covered by this License.
-
- b) Accompany the Combined Work with a copy of the GNU GPL and this license
- document.
-
- c) For a Combined Work that displays copyright notices during
- execution, include the copyright notice for the Library among
- these notices, as well as a reference directing the user to the
- copies of the GNU GPL and this license document.
-
- d) Do one of the following:
-
- 0) Convey the Minimal Corresponding Source under the terms of this
- License, and the Corresponding Application Code in a form
- suitable for, and under terms that permit, the user to
- recombine or relink the Application with a modified version of
- the Linked Version to produce a modified Combined Work, in the
- manner specified by section 6 of the GNU GPL for conveying
- Corresponding Source.
-
- 1) Use a suitable shared library mechanism for linking with the
- Library. A suitable mechanism is one that (a) uses at run time
- a copy of the Library already present on the user's computer
- system, and (b) will operate properly with a modified version
- of the Library that is interface-compatible with the Linked
- Version.
-
- e) Provide Installation Information, but only if you would otherwise
- be required to provide such information under section 6 of the
- GNU GPL, and only to the extent that such information is
- necessary to install and execute a modified version of the
- Combined Work produced by recombining or relinking the
- Application with a modified version of the Linked Version. (If
- you use option 4d0, the Installation Information must accompany
- the Minimal Corresponding Source and Corresponding Application
- Code. If you use option 4d1, you must provide the Installation
- Information in the manner specified by section 6 of the GNU GPL
- for conveying Corresponding Source.)
-
- 5. Combined Libraries.
-
- You may place library facilities that are a work based on the
-Library side by side in a single library together with other library
-facilities that are not Applications and are not covered by this
-License, and convey such a combined library under terms of your
-choice, if you do both of the following:
-
- a) Accompany the combined library with a copy of the same work based
- on the Library, uncombined with any other library facilities,
- conveyed under the terms of this License.
-
- b) Give prominent notice with the combined library that part of it
- is a work based on the Library, and explaining where to find the
- accompanying uncombined form of the same work.
-
- 6. Revised Versions of the GNU Lesser General Public License.
-
- The Free Software Foundation may publish revised and/or new versions
-of the GNU Lesser General Public License from time to time. Such new
-versions will be similar in spirit to the present version, but may
-differ in detail to address new problems or concerns.
-
- Each version is given a distinguishing version number. If the
-Library as you received it specifies that a certain numbered version
-of the GNU Lesser General Public License "or any later version"
-applies to it, you have the option of following the terms and
-conditions either of that published version or of any later version
-published by the Free Software Foundation. If the Library as you
-received it does not specify a version number of the GNU Lesser
-General Public License, you may choose any version of the GNU Lesser
-General Public License ever published by the Free Software Foundation.
-
- If the Library as you received it specifies that a proxy can decide
-whether future versions of the GNU Lesser General Public License shall
-apply, that proxy's public statement of acceptance of any version is
-permanent authorization for you to choose that version for the
-Library.