diff --git a/jsprit-core/src/main/java/algorithms/CalculatorBuilder.java b/jsprit-core/src/main/java/algorithms/CalculatorBuilder.java
index 97e8fba6..0a3898a2 100644
--- a/jsprit-core/src/main/java/algorithms/CalculatorBuilder.java
+++ b/jsprit-core/src/main/java/algorithms/CalculatorBuilder.java
@@ -23,6 +23,7 @@ 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;
@@ -81,6 +82,8 @@ class CalculatorBuilder {
private double timeSlice;
private int neighbors;
+
+ private ConstraintManager constraintManager;
/**
* Constructs the builder.
@@ -213,9 +216,11 @@ class CalculatorBuilder {
}
}
- private CalculatorPlusListeners createStandardLocal(VehicleRoutingProblem vrp, StateManager activityStates2){
- MarginalsCalculus defaultCalc = new MarginalsCalculusTriangleInequality(vrp.getTransportCosts(), vrp.getActivityCosts(), new HardConstraints.HardTimeWindowConstraint(activityStates2, vrp.getTransportCosts()) );
- JobInsertionCalculator standardServiceInsertion = new CalculatesServiceInsertion(vrp.getTransportCosts(), defaultCalc, new HardConstraints.HardLoadConstraint(activityStates2));
+ private CalculatorPlusListeners createStandardLocal(VehicleRoutingProblem vrp, StateManager statesManager){
+ if(constraintManager == null) throw new IllegalStateException("constraint-manager is null");
+
+ MarginalsCalculus defaultCalc = new MarginalsCalculusTriangleInequality(vrp.getTransportCosts(), vrp.getActivityCosts(), constraintManager);
+ JobInsertionCalculator standardServiceInsertion = new CalculatesServiceInsertion(vrp.getTransportCosts(), defaultCalc, constraintManager);
((CalculatesServiceInsertion) standardServiceInsertion).setNeighborhood(vrp.getNeighborhood());
CalculatorPlusListeners calcPlusListeners = new CalculatorPlusListeners(standardServiceInsertion);
@@ -246,6 +251,10 @@ class CalculatorBuilder {
return new CalculatesVehTypeDepServiceInsertion(fleetManager, baseCalc);
}
+ public void setConstraintManager(ConstraintManager constraintManager) {
+ this.constraintManager = constraintManager;
+ }
+
}
diff --git a/jsprit-core/src/main/java/algorithms/Gendreau.java b/jsprit-core/src/main/java/algorithms/Gendreau.java
index 70125dc4..183b9a1e 100644
--- a/jsprit-core/src/main/java/algorithms/Gendreau.java
+++ b/jsprit-core/src/main/java/algorithms/Gendreau.java
@@ -32,9 +32,11 @@ 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.SearchStrategyModule;
import basics.algo.SearchStrategyModuleListener;
import basics.route.TourActivity;
@@ -53,8 +55,6 @@ final class Gendreau implements SearchStrategyModule{
private final InsertionStrategy insertionStrategy;
- private final Inserter inserter;
-
private VehicleFleetManager fleetManager;
private Random random = RandomNumberGeneration.getRandom();
@@ -71,7 +71,7 @@ final class Gendreau implements SearchStrategyModule{
super();
InsertionListeners insertionListeners = new InsertionListeners();
insertionListeners.addAllListeners(insertionStrategy.getListeners());
- inserter = new Inserter(insertionListeners);
+ new Inserter(insertionListeners);
this.ruin = ruin;
this.vrp = vrp;
this.insertionStrategy = insertionStrategy;
@@ -205,7 +205,18 @@ final class Gendreau implements SearchStrategyModule{
@Override
public void addModuleListener(SearchStrategyModuleListener moduleListener) {
- // TODO Auto-generated method stub
+ if(moduleListener instanceof InsertionListener){
+ InsertionListener iListener = (InsertionListener) moduleListener;
+ if(!insertionStrategy.getListeners().contains(iListener)){
+ insertionStrategy.addListener(iListener);
+ }
+ }
+ if(moduleListener instanceof RuinListener){
+ RuinListener rListener = (RuinListener) moduleListener;
+ if(!ruin.getListeners().contains(rListener)){
+ ruin.addListener(rListener);
+ }
+ }
}
}
diff --git a/jsprit-core/src/main/java/algorithms/HardConstraints.java b/jsprit-core/src/main/java/algorithms/HardConstraints.java
index 656dbad1..17b18676 100644
--- a/jsprit-core/src/main/java/algorithms/HardConstraints.java
+++ b/jsprit-core/src/main/java/algorithms/HardConstraints.java
@@ -11,9 +11,24 @@ import basics.Service;
import basics.costs.VehicleRoutingTransportCosts;
import basics.route.DeliveryActivity;
import basics.route.PickupActivity;
+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 {
@@ -48,7 +63,31 @@ class HardConstraints {
}
-
+ 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 {
@@ -90,6 +129,12 @@ class HardConstraints {
}
}
+ /**
+ * lsjdfjsdlfjsa
+ *
+ * @author stefan
+ *
+ */
static class HardPickupAndDeliveryLoadConstraint implements HardRouteLevelConstraint {
private StateManager stateManager;
@@ -107,7 +152,7 @@ class HardConstraints {
return false;
}
}
- else if(insertionContext.getJob() instanceof Pickup){
+ 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;
@@ -118,15 +163,20 @@ class HardConstraints {
}
- static class HardTimeWindowConstraint implements HardActivityLevelConstraint {
+ /**
+ * ljsljslfjs
+ * @author stefan
+ *
+ */
+ public static class HardTimeWindowActivityLevelConstraint implements HardActivityLevelConstraint {
- private static Logger log = Logger.getLogger(HardTimeWindowConstraint.class);
+ private static Logger log = Logger.getLogger(HardTimeWindowActivityLevelConstraint.class);
private StateManager states;
private VehicleRoutingTransportCosts routingCosts;
- public HardTimeWindowConstraint(StateManager states, VehicleRoutingTransportCosts routingCosts) {
+ public HardTimeWindowActivityLevelConstraint(StateManager states, VehicleRoutingTransportCosts routingCosts) {
super();
this.states = states;
this.routingCosts = routingCosts;
@@ -152,11 +202,11 @@ class HardConstraints {
}
}
- static class HardPickupAndDeliveryConstraint implements HardActivityLevelConstraint {
+ static class HardPickupAndDeliveryActivityLevelConstraint implements HardActivityLevelConstraint {
private StateManager stateManager;
- public HardPickupAndDeliveryConstraint(StateManager stateManager) {
+ public HardPickupAndDeliveryActivityLevelConstraint(StateManager stateManager) {
super();
this.stateManager = stateManager;
}
@@ -176,7 +226,7 @@ class HardConstraints {
futurePicks = (int) stateManager.getActivityState(prevAct, StateTypes.FUTURE_PICKS).toDouble();
pastDeliveries = (int) stateManager.getActivityState(prevAct, StateTypes.PAST_DELIVERIES).toDouble();
}
- if(newAct instanceof PickupActivity){
+ if(newAct instanceof PickupActivity || newAct instanceof ServiceActivity){
if(loadAtPrevAct + newAct.getCapacityDemand() + futurePicks > iFacts.getNewVehicle().getCapacity()){
return false;
}
@@ -192,11 +242,11 @@ class HardConstraints {
}
- static class HardPickupAndDeliveryBackhaulConstraint implements HardActivityLevelConstraint {
+ static class HardPickupAndDeliveryBackhaulActivityLevelConstraint implements HardActivityLevelConstraint {
private StateManager stateManager;
- public HardPickupAndDeliveryBackhaulConstraint(StateManager stateManager) {
+ public HardPickupAndDeliveryBackhaulActivityLevelConstraint(StateManager stateManager) {
super();
this.stateManager = stateManager;
}
@@ -204,7 +254,9 @@ class HardConstraints {
@Override
public boolean fulfilled(InsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
if(newAct instanceof PickupActivity && nextAct instanceof DeliveryActivity){ return false; }
+ if(newAct instanceof ServiceActivity && nextAct instanceof DeliveryActivity){ return false; }
if(newAct instanceof DeliveryActivity && prevAct instanceof PickupActivity){ return false; }
+ if(newAct instanceof DeliveryActivity && prevAct instanceof ServiceActivity){ return false; }
int loadAtPrevAct;
int futurePicks;
int pastDeliveries;
@@ -218,7 +270,7 @@ class HardConstraints {
futurePicks = (int) stateManager.getActivityState(prevAct, StateTypes.FUTURE_PICKS).toDouble();
pastDeliveries = (int) stateManager.getActivityState(prevAct, StateTypes.PAST_DELIVERIES).toDouble();
}
- if(newAct instanceof PickupActivity){
+ if(newAct instanceof PickupActivity || newAct instanceof ServiceActivity){
if(loadAtPrevAct + newAct.getCapacityDemand() + futurePicks > iFacts.getNewVehicle().getCapacity()){
return false;
}
diff --git a/jsprit-core/src/main/java/algorithms/InsertionFactory.java b/jsprit-core/src/main/java/algorithms/InsertionFactory.java
index 402d0e98..182efa0f 100644
--- a/jsprit-core/src/main/java/algorithms/InsertionFactory.java
+++ b/jsprit-core/src/main/java/algorithms/InsertionFactory.java
@@ -27,6 +27,7 @@ import java.util.concurrent.ExecutorService;
import org.apache.commons.configuration.HierarchicalConfiguration;
import org.apache.log4j.Logger;
+import algorithms.HardConstraints.ConstraintManager;
import algorithms.StateUpdates.UpdateStates;
import basics.VehicleRoutingProblem;
import basics.algo.InsertionListener;
@@ -37,7 +38,7 @@ 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){
+ VehicleFleetManager vehicleFleetManager, StateManagerImpl routeStates, List algorithmListeners, ExecutorService executorService, int nuOfThreads, ConstraintManager constraintManager){
boolean concurrentInsertion = false;
if(executorService != null) concurrentInsertion = true;
if(config.containsKey("[@name]")){
@@ -53,6 +54,7 @@ class InsertionFactory {
calcBuilder.setStates(routeStates);
calcBuilder.setVehicleRoutingProblem(vrp);
calcBuilder.setVehicleFleetManager(vehicleFleetManager);
+ calcBuilder.setConstraintManager(constraintManager);
if(config.containsKey("level")){
String level = config.getString("level");
@@ -102,13 +104,13 @@ class InsertionFactory {
// insertionStrategy = RegretInsertion.newInstance(routeAlgorithm);
// }
- insertionStrategy.addListener(new RemoveEmptyVehicles(vehicleFleetManager));
- insertionStrategy.addListener(new ResetAndIniFleetManager(vehicleFleetManager));
- insertionStrategy.addListener(new VehicleSwitched(vehicleFleetManager));
+// 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()));
+// 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)));
diff --git a/jsprit-core/src/main/java/algorithms/StateUpdates.java b/jsprit-core/src/main/java/algorithms/StateUpdates.java
index 9c7d4054..23a6e836 100644
--- a/jsprit-core/src/main/java/algorithms/StateUpdates.java
+++ b/jsprit-core/src/main/java/algorithms/StateUpdates.java
@@ -11,7 +11,9 @@ import algorithms.BackwardInTimeListeners.BackwardInTimeListener;
import algorithms.ForwardInTimeListeners.ForwardInTimeListener;
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;
@@ -27,6 +29,7 @@ import basics.costs.VehicleRoutingTransportCosts;
import basics.route.DeliveryActivity;
import basics.route.End;
import basics.route.PickupActivity;
+import basics.route.ServiceActivity;
import basics.route.Start;
import basics.route.TourActivity;
import basics.route.VehicleRoute;
@@ -444,7 +447,7 @@ class StateUpdates {
@Override
public void prevActivity(TourActivity act, double latestDepartureTime, double latestOperationStartTime) {
stateManager.putActivityState(act, StateTypes.FUTURE_PICKS, new StateImpl(futurePicks));
- if(act instanceof PickupActivity){
+ if(act instanceof PickupActivity || act instanceof ServiceActivity){
futurePicks += act.getCapacityDemand();
}
assert futurePicks <= route.getVehicle().getCapacity() : "sum of pickups must not be > vehicleCap";
@@ -542,15 +545,79 @@ class StateUpdates {
}
}
- static class WalkThroughAndUpdateRoutesOnceTheyChanged implements InsertionStartsListener, JobInsertedListener {
+ 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 IterateRouteForwardInTime forwardInTimeIterator;
private IterateRouteBackwardInTime backwardInTimeIterator;
- public WalkThroughAndUpdateRoutesOnceTheyChanged(VehicleRoutingTransportCosts routingCosts) {
+ private Collection insertionStartsListeners;
+
+ private Collection jobInsertionListeners;
+
+ public UpdateRouteStatesOnceTheRouteHasBeenChanged(VehicleRoutingTransportCosts routingCosts) {
forwardInTimeIterator = new IterateRouteForwardInTime(routingCosts);
backwardInTimeIterator = new IterateRouteBackwardInTime(routingCosts);
+ insertionStartsListeners = new ArrayList();
+ jobInsertionListeners = new ArrayList();
}
void addListener(ForwardInTimeListener l){
@@ -560,16 +627,31 @@ class StateUpdates {
void addListener(BackwardInTimeListener l){
backwardInTimeIterator.addListener(l);
}
+
+ 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.iterate(inRoute);
+ backwardInTimeIterator.iterate(inRoute);
}
@Override
public void informInsertionStarts(Collection vehicleRoutes, Collection unassignedJobs) {
- // TODO Auto-generated method stub
-
+ for(VehicleRoute route : vehicleRoutes){
+ for(InsertionStarts insertionsStartsHandler : insertionStartsListeners){
+ insertionsStartsHandler.insertionStarts(route);
+ }
+ forwardInTimeIterator.iterate(route);
+ backwardInTimeIterator.iterate(route);
+ }
}
}
diff --git a/jsprit-core/src/main/java/algorithms/VehicleRoutingAlgorithms.java b/jsprit-core/src/main/java/algorithms/VehicleRoutingAlgorithms.java
index ad9fa4aa..d3c77390 100644
--- a/jsprit-core/src/main/java/algorithms/VehicleRoutingAlgorithms.java
+++ b/jsprit-core/src/main/java/algorithms/VehicleRoutingAlgorithms.java
@@ -35,7 +35,12 @@ import org.apache.commons.configuration.HierarchicalConfiguration;
import org.apache.commons.configuration.XMLConfiguration;
import org.apache.log4j.Logger;
-import util.RouteUtils;
+import algorithms.HardConstraints.ConstraintManager;
+import algorithms.HardConstraints.HardTimeWindowActivityLevelConstraint;
+import algorithms.StateUpdates.UpdateActivityTimes;
+import algorithms.StateUpdates.UpdateCostsAtAllLevels;
+import algorithms.StateUpdates.UpdateEarliestStartTimeWindowAtActLocations;
+import algorithms.StateUpdates.UpdateLatestOperationStartTimeAtActLocations;
import algorithms.StateUpdates.UpdateStates;
import algorithms.VehicleRoutingAlgorithms.TypedMap.AbstractKey;
import algorithms.VehicleRoutingAlgorithms.TypedMap.AcceptorKey;
@@ -50,21 +55,19 @@ import algorithms.acceptors.SolutionAcceptor;
import algorithms.selectors.SelectBest;
import algorithms.selectors.SelectRandomly;
import algorithms.selectors.SolutionSelector;
-import basics.Job;
import basics.VehicleRoutingAlgorithm;
import basics.VehicleRoutingProblem;
+import basics.VehicleRoutingProblem.Constraint;
import basics.VehicleRoutingProblem.FleetSize;
import basics.VehicleRoutingProblemSolution;
import basics.algo.AlgorithmStartsListener;
import basics.algo.InsertionListener;
-import basics.algo.IterationStartsListener;
import basics.algo.IterationWithoutImprovementBreaker;
import basics.algo.PrematureAlgorithmBreaker;
import basics.algo.SearchStrategy;
import basics.algo.SearchStrategy.DiscoveredSolution;
import basics.algo.SearchStrategyManager;
import basics.algo.SearchStrategyModule;
-import basics.algo.SearchStrategyModuleListener;
import basics.algo.TimeBreaker;
import basics.algo.VariationCoefficientBreaker;
import basics.algo.VehicleRoutingAlgorithmListeners.PrioritizedVRAListener;
@@ -427,50 +430,43 @@ public class VehicleRoutingAlgorithms {
}
private static VehicleRoutingAlgorithm createAlgo(final VehicleRoutingProblem vrp, XMLConfiguration config, ExecutorService executorService, int nuOfThreads){
-
- //fleetmanager
- final VehicleFleetManager vehicleFleetManager;
- if(vrp.getFleetSize().equals(FleetSize.INFINITE)){
- vehicleFleetManager = new InfiniteVehicles(vrp.getVehicles());
-
- }
- else if(vrp.getFleetSize().equals(FleetSize.FINITE)){
- vehicleFleetManager = new VehicleFleetManagerImpl(vrp.getVehicles());
- }
- else{
- throw new IllegalStateException("fleet size can only be infinite or finite. " +
- "makes sure your config file contains one of these options");
- }
-
+
+ // map to store constructed modules
+ TypedMap definedClasses = new TypedMap();
+
+ // algorithm listeners
Set algorithmListeners = new HashSet();
+
+ // insertion listeners
List insertionListeners = new ArrayList();
- algorithmListeners.add(new PrioritizedVRAListener(Priority.LOW, new SolutionVerifier()));
-
- final StateManagerImpl routeStates = new StateManagerImpl();
- IterationStartsListener resetStates = new IterationStartsListener() {
-
- @Override
- public void informIterationStarts(int i, VehicleRoutingProblem problem, Collection solutions) {
- routeStates.clear();
- }
- };
- algorithmListeners.add(new PrioritizedVRAListener(Priority.LOW, resetStates));
+ //create fleetmanager
+ final VehicleFleetManager vehicleFleetManager = createFleetManager(vrp);
-// insertionListeners.add(new UdateCostsAtRouteLevel(routeStates,vrp.getTransportCosts(),vrp.getActivityCosts()));
+ //create state-manager
+ final StateManagerImpl stateManager = new StateManagerImpl();
-// RouteStates routeStates = new RouteStates();
-// routeStates.initialiseStateOfJobs(vrp.getJobs().values());
-// algorithmListeners.add(new PrioritizedVRAListener(Priority.LOW, routeStates));
-
- TypedMap definedClasses = new TypedMap();
-
/*
- * initial solution - construction
+ * define constraints
*/
- AlgorithmStartsListener createInitialSolution = createInitialSolution(config,vrp,vehicleFleetManager,routeStates,algorithmListeners,definedClasses,executorService,nuOfThreads);
+ //constraint manager
+ ConstraintManager constraintManager = new ConstraintManager();
+ constraintManager.addConstraint(new HardConstraints.HardTimeWindowActivityLevelConstraint(stateManager, vrp.getTransportCosts()));
+
+ if(vrp.getProblemConstraints().contains(Constraint.DELIVERIES_FIRST)){
+ constraintManager.addConstraint(new HardConstraints.HardPickupAndDeliveryBackhaulActivityLevelConstraint(stateManager));
+ }
+ else{
+ constraintManager.addConstraint(new HardConstraints.HardPickupAndDeliveryActivityLevelConstraint(stateManager));
+ }
+
+ constraintManager.addConstraint(new HardConstraints.HardPickupAndDeliveryLoadConstraint(stateManager));
+
+ //construct initial solution creator
+ AlgorithmStartsListener createInitialSolution = createInitialSolution(config,vrp,vehicleFleetManager,stateManager,algorithmListeners,definedClasses,executorService,nuOfThreads,constraintManager);
if(createInitialSolution != null) algorithmListeners.add(new PrioritizedVRAListener(Priority.MEDIUM, createInitialSolution));
+ //construct algorithm, i.e. search-strategies and its modules
int solutionMemory = config.getInt("strategy.memory");
SearchStrategyManager searchStratManager = new SearchStrategyManager();
List strategyConfigs = config.configurationsAt("strategy.searchStrategies.searchStrategy");
@@ -482,26 +478,72 @@ public class VehicleRoutingAlgorithms {
strategy.setName(name);
List modulesConfig = strategyConfig.configurationsAt("modules.module");
for(HierarchicalConfiguration moduleConfig : modulesConfig){
- SearchStrategyModule module = buildModule(moduleConfig,vrp,vehicleFleetManager,routeStates,algorithmListeners,definedClasses,executorService,nuOfThreads);
+ SearchStrategyModule module = buildModule(moduleConfig,vrp,vehicleFleetManager,stateManager,algorithmListeners,definedClasses,executorService,nuOfThreads, constraintManager);
strategy.addModule(module);
}
searchStratManager.addStrategy(strategy, strategyConfig.getDouble("probability"));
}
+
+ //construct algorithm
VehicleRoutingAlgorithm metaAlgorithm = new VehicleRoutingAlgorithm(vrp, searchStratManager);
if(config.containsKey("iterations")){
int iter = config.getInt("iterations");
metaAlgorithm.setNuOfIterations(iter);
log.info("set nuOfIterations to " + iter);
}
- //prematureBreak
+
+
+ /*
+ * 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());
+
+ routeChangedListener.addInsertionStartsListener(new StateUpdates.UpdateLoadsAtStartAndEndOfRouteWhenInsertionStarts(stateManager));
+ routeChangedListener.addJobInsertedListener(new StateUpdates.UpdateLoadsAtStartAndEndOfRouteWhenJobHasBeenInserted(stateManager));
+
+ routeChangedListener.addListener(new StateUpdates.UpdateActivityTimes());
+ routeChangedListener.addListener(new StateUpdates.UpdateLoadAtActivityLevel(stateManager));
+ routeChangedListener.addListener(new StateUpdates.UpdateCostsAtAllLevels(vrp.getActivityCosts(), vrp.getTransportCosts(), stateManager));
+
+ routeChangedListener.addListener(new StateUpdates.UpdateOccuredDeliveriesAtActivityLevel(stateManager));
+ routeChangedListener.addListener(new StateUpdates.UpdateLatestOperationStartTimeAtActLocations(stateManager));
+ routeChangedListener.addListener(new StateUpdates.UpdateFuturePickupsAtActivityLevel(stateManager));
+
+ metaAlgorithm.getSearchStrategyManager().addSearchStrategyModuleListener(routeChangedListener);
+ metaAlgorithm.getSearchStrategyManager().addSearchStrategyModuleListener(new RemoveEmptyVehicles(vehicleFleetManager));
+ metaAlgorithm.getSearchStrategyManager().addSearchStrategyModuleListener(new ResetAndIniFleetManager(vehicleFleetManager));
+ metaAlgorithm.getSearchStrategyManager().addSearchStrategyModuleListener(new VehicleSwitched(vehicleFleetManager));
+
+ //define prematureBreak
PrematureAlgorithmBreaker prematureAlgoBreaker = getPrematureBreaker(config,algorithmListeners);
metaAlgorithm.setPrematureAlgorithmBreaker(prematureAlgoBreaker);
+ //misc
+ algorithmListeners.add(new PrioritizedVRAListener(Priority.LOW, new SolutionVerifier()));
+
+ //register listeners
registerListeners(metaAlgorithm,algorithmListeners);
registerInsertionListeners(definedClasses,insertionListeners);
return metaAlgorithm;
}
+ private static VehicleFleetManager createFleetManager(final VehicleRoutingProblem vrp) {
+ if(vrp.getFleetSize().equals(FleetSize.INFINITE)){
+ return new InfiniteVehicles(vrp.getVehicles());
+
+ }
+ else if(vrp.getFleetSize().equals(FleetSize.FINITE)){
+ return new VehicleFleetManagerImpl(vrp.getVehicles());
+ }
+ throw new IllegalStateException("fleet size can only be infinite or finite. " +
+ "makes sure your config file contains one of these options");
+ }
+
private static PrematureAlgorithmBreaker getPrematureBreaker(XMLConfiguration config, Set algorithmListeners) {
String basedOn = config.getString("prematureBreak[@basedOn]");
if(basedOn == null){
@@ -569,7 +611,7 @@ public class VehicleRoutingAlgorithms {
metaAlgorithm.getAlgorithmListeners().addAll(algorithmListeners);
}
- private static AlgorithmStartsListener createInitialSolution(XMLConfiguration config, final VehicleRoutingProblem vrp, VehicleFleetManager vehicleFleetManager, StateManagerImpl routeStates, Set algorithmListeners, TypedMap definedClasses, ExecutorService executorService, int nuOfThreads) {
+ private static AlgorithmStartsListener createInitialSolution(XMLConfiguration config, final VehicleRoutingProblem vrp, VehicleFleetManager vehicleFleetManager, StateManagerImpl 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;
@@ -584,7 +626,7 @@ public class VehicleRoutingAlgorithms {
InsertionStrategy insertionStrategy = definedClasses.get(insertionStrategyKey);
if(insertionStrategy == null){
List prioListeners = new ArrayList();
- insertionStrategy = createInsertionStrategy(modConfig, vrp, vehicleFleetManager, routeStates, prioListeners, executorService, nuOfThreads);
+ insertionStrategy = createInsertionStrategy(modConfig, vrp, vehicleFleetManager, routeStates, prioListeners, executorService, nuOfThreads, constraintManager);
algorithmListeners.addAll(prioListeners);
definedClasses.put(insertionStrategyKey,insertionStrategy);
}
@@ -666,7 +708,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) {
+ final StateManagerImpl 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]");
@@ -715,49 +757,14 @@ public class VehicleRoutingAlgorithms {
List insertionConfigs = moduleConfig.configurationsAt("insertion");
if(insertionConfigs.size() != 1) throw new IllegalStateException("this should be 1");
List prioListeners = new ArrayList();
- insertion = createInsertionStrategy(insertionConfigs.get(0), vrp, vehicleFleetManager, routeStates, prioListeners, executorService, nuOfThreads);
+ insertion = createInsertionStrategy(insertionConfigs.get(0), vrp, vehicleFleetManager, routeStates, prioListeners, executorService, nuOfThreads, constraintManager);
algorithmListeners.addAll(prioListeners);
}
final InsertionStrategy final_insertion = insertion;
- SearchStrategyModule module = new SearchStrategyModule() {
-
- private Logger logger = Logger.getLogger(SearchStrategyModule.class);
-
- @Override
- public VehicleRoutingProblemSolution runAndGetSolution(VehicleRoutingProblemSolution vrpSolution) {
- Collection ruinedJobs = ruin.ruin(vrpSolution.getRoutes());
- final_insertion.insertJobs(vrpSolution.getRoutes(), ruinedJobs);
- double totalCost = RouteUtils.getTotalCost(vrpSolution.getRoutes());
- vrpSolution.setCost(totalCost);
- return vrpSolution;
- }
-
- @Override
- public String toString() {
- return getName();
- }
-
- @Override
- public String getName() {
- return "[name=ruin_and_recreate][ruin="+ruin+"][recreate="+final_insertion+"]";
- }
-
- @Override
- public void addModuleListener(SearchStrategyModuleListener moduleListener) {
- if(moduleListener instanceof InsertionListener){
- InsertionListener iListener = (InsertionListener) moduleListener;
- if(!final_insertion.getListeners().contains(iListener)){
- logger.info("register moduleListener " + moduleListener);
- final_insertion.addListener(iListener);
- }
-
- }
-
- }
- };
- return module;
+
+ RuinAndRecreateModule rrModule = new RuinAndRecreateModule("ruin_and_recreate", final_insertion, ruin);
+ return rrModule;
}
-
if(moduleName.equals("gendreau")){
int iterations = moduleConfig.getInt("iterations");
double share = moduleConfig.getDouble("share");
@@ -770,7 +777,6 @@ public class VehicleRoutingAlgorithms {
RuinStrategy ruin = definedClasses.get(stratKey);
if(ruin == null){
ruin = new RuinRadial(vrp, 0.3, new JobDistanceAvgCosts(vrp.getTransportCosts()));
- ruin.addListener(new UpdateStates(routeStates, vrp.getTransportCosts(), vrp.getActivityCosts()));
definedClasses.put(stratKey, ruin);
}
@@ -785,7 +791,7 @@ public class VehicleRoutingAlgorithms {
List insertionConfigs = moduleConfig.configurationsAt("insertion");
if(insertionConfigs.size() != 1) throw new IllegalStateException("this should be 1");
List prioListeners = new ArrayList();
- insertion = createInsertionStrategy(insertionConfigs.get(0), vrp, vehicleFleetManager, routeStates, prioListeners, executorService, nuOfThreads);
+ insertion = createInsertionStrategy(insertionConfigs.get(0), vrp, vehicleFleetManager, routeStates, prioListeners, executorService, nuOfThreads, constraintManager);
algorithmListeners.addAll(prioListeners);
}
Gendreau gendreau = new Gendreau(vrp, ruin, insertion);
@@ -809,7 +815,6 @@ public class VehicleRoutingAlgorithms {
RuinStrategy ruin = definedClasses.get(stratKey);
if(ruin == null){
ruin = new RuinRadial(vrp, shareToRuin, jobDistance);
- ruin.addListener(new UpdateStates(routeStates, vrp.getTransportCosts(), vrp.getActivityCosts()));
definedClasses.put(stratKey, ruin);
}
return ruin;
@@ -820,14 +825,13 @@ public class VehicleRoutingAlgorithms {
RuinStrategy ruin = definedClasses.get(stratKey);
if(ruin == null){
ruin = new RuinRandom(vrp, shareToRuin);
- ruin.addListener(new UpdateStates(routeStates, vrp.getTransportCosts(), vrp.getActivityCosts()));
definedClasses.put(stratKey, ruin);
}
return ruin;
}
- private static InsertionStrategy createInsertionStrategy(HierarchicalConfiguration moduleConfig, VehicleRoutingProblem vrp,VehicleFleetManager vehicleFleetManager, StateManagerImpl routeStates, List algorithmListeners, ExecutorService executorService, int nuOfThreads) {
- InsertionStrategy insertion = InsertionFactory.createInsertion(vrp, moduleConfig, vehicleFleetManager, routeStates, algorithmListeners, executorService, nuOfThreads);
+ private static InsertionStrategy createInsertionStrategy(HierarchicalConfiguration moduleConfig, VehicleRoutingProblem vrp,VehicleFleetManager vehicleFleetManager, StateManagerImpl 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/test/java/algorithms/BuildPDVRPAlgoFromScratchTest.java b/jsprit-core/src/test/java/algorithms/BuildPDVRPAlgoFromScratchTest.java
index fa3242d0..8150e095 100644
--- a/jsprit-core/src/test/java/algorithms/BuildPDVRPAlgoFromScratchTest.java
+++ b/jsprit-core/src/test/java/algorithms/BuildPDVRPAlgoFromScratchTest.java
@@ -55,8 +55,8 @@ public class BuildPDVRPAlgoFromScratchTest {
final StateManagerImpl stateManager = new StateManagerImpl();
HardActivityLevelConstraintManager actLevelConstraintAccumulator = new HardActivityLevelConstraintManager();
- actLevelConstraintAccumulator.addConstraint(new HardConstraints.HardPickupAndDeliveryConstraint(stateManager));
- actLevelConstraintAccumulator.addConstraint(new HardConstraints.HardTimeWindowConstraint(stateManager, vrp.getTransportCosts()));
+ actLevelConstraintAccumulator.addConstraint(new HardConstraints.HardPickupAndDeliveryActivityLevelConstraint(stateManager));
+ actLevelConstraintAccumulator.addConstraint(new HardConstraints.HardTimeWindowActivityLevelConstraint(stateManager, vrp.getTransportCosts()));
MarginalsCalculus marginalCalculus = new MarginalsCalculusTriangleInequality(vrp.getTransportCosts(), vrp.getActivityCosts(), actLevelConstraintAccumulator);
diff --git a/jsprit-core/src/test/java/algorithms/GendreauPostOptTest.java b/jsprit-core/src/test/java/algorithms/GendreauPostOptTest.java
index a82b670c..7642b043 100644
--- a/jsprit-core/src/test/java/algorithms/GendreauPostOptTest.java
+++ b/jsprit-core/src/test/java/algorithms/GendreauPostOptTest.java
@@ -152,7 +152,7 @@ public class GendreauPostOptTest {
activityCosts = new ExampleActivityCostFunction();
- CalculatesServiceInsertion standardServiceInsertion = new CalculatesServiceInsertion(cost, new MarginalsCalculusTriangleInequality(cost, activityCosts, new HardConstraints.HardTimeWindowConstraint(states, cost)), new HardConstraints.HardLoadConstraint(states));
+ CalculatesServiceInsertion standardServiceInsertion = new CalculatesServiceInsertion(cost, new MarginalsCalculusTriangleInequality(cost, activityCosts, new HardConstraints.HardTimeWindowActivityLevelConstraint(states, cost)), new HardConstraints.HardLoadConstraint(states));
CalculatesServiceInsertionConsideringFixCost withFixCost = new CalculatesServiceInsertionConsideringFixCost(standardServiceInsertion, states);
withFixCost.setWeightOfFixCost(1.2);
diff --git a/jsprit-core/src/test/java/algorithms/TestCalculatesServiceInsertion.java b/jsprit-core/src/test/java/algorithms/TestCalculatesServiceInsertion.java
index ebd5a30b..8ab72ed7 100644
--- a/jsprit-core/src/test/java/algorithms/TestCalculatesServiceInsertion.java
+++ b/jsprit-core/src/test/java/algorithms/TestCalculatesServiceInsertion.java
@@ -157,7 +157,7 @@ public class TestCalculatesServiceInsertion {
ExampleActivityCostFunction activityCosts = new ExampleActivityCostFunction();
- serviceInsertion = new CalculatesServiceInsertion(costs, new MarginalsCalculusTriangleInequality(costs, activityCosts, new HardConstraints.HardTimeWindowConstraint(states, costs)), new HardConstraints.HardLoadConstraint(states));
+ serviceInsertion = new CalculatesServiceInsertion(costs, new MarginalsCalculusTriangleInequality(costs, activityCosts, new HardConstraints.HardTimeWindowActivityLevelConstraint(states, costs)), new HardConstraints.HardLoadConstraint(states));
stateUpdater = new UpdateStates(states, costs, activityCosts);
diff --git a/jsprit-examples/src/main/java/examples/RefuseCollectionExample.java b/jsprit-examples/src/main/java/examples/RefuseCollectionExample.java
index 58a3133d..61d9db1b 100644
--- a/jsprit-examples/src/main/java/examples/RefuseCollectionExample.java
+++ b/jsprit-examples/src/main/java/examples/RefuseCollectionExample.java
@@ -201,7 +201,7 @@ public class RefuseCollectionExample {
VehicleRoutingProblem vrp = vrpBuilder.build();
VehicleRoutingAlgorithm vra = new GreedySchrimpfFactory().createAlgorithm(vrp);
- vra.setPrematureBreak(10);
+ vra.setPrematureBreak(100);
Collection solutions = vra.searchSolutions();
SolutionPrinter.print(Solutions.getBest(solutions),Print.VERBOSE);