mirror of
https://github.com/graphhopper/jsprit.git
synced 2020-01-24 07:45:05 +01:00
modify classes such than they can cope with pickup and deliveries
This commit is contained in:
parent
0806d524e6
commit
26219aa3a1
10 changed files with 283 additions and 123 deletions
|
|
@ -23,6 +23,7 @@ package algorithms;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import algorithms.HardConstraints.ConstraintManager;
|
||||||
import basics.VehicleRoutingProblem;
|
import basics.VehicleRoutingProblem;
|
||||||
import basics.algo.InsertionListener;
|
import basics.algo.InsertionListener;
|
||||||
import basics.algo.VehicleRoutingAlgorithmListeners.PrioritizedVRAListener;
|
import basics.algo.VehicleRoutingAlgorithmListeners.PrioritizedVRAListener;
|
||||||
|
|
@ -82,6 +83,8 @@ class CalculatorBuilder {
|
||||||
|
|
||||||
private int neighbors;
|
private int neighbors;
|
||||||
|
|
||||||
|
private ConstraintManager constraintManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs the builder.
|
* Constructs the builder.
|
||||||
*
|
*
|
||||||
|
|
@ -213,9 +216,11 @@ class CalculatorBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private CalculatorPlusListeners createStandardLocal(VehicleRoutingProblem vrp, StateManager activityStates2){
|
private CalculatorPlusListeners createStandardLocal(VehicleRoutingProblem vrp, StateManager statesManager){
|
||||||
MarginalsCalculus defaultCalc = new MarginalsCalculusTriangleInequality(vrp.getTransportCosts(), vrp.getActivityCosts(), new HardConstraints.HardTimeWindowConstraint(activityStates2, vrp.getTransportCosts()) );
|
if(constraintManager == null) throw new IllegalStateException("constraint-manager is null");
|
||||||
JobInsertionCalculator standardServiceInsertion = new CalculatesServiceInsertion(vrp.getTransportCosts(), defaultCalc, new HardConstraints.HardLoadConstraint(activityStates2));
|
|
||||||
|
MarginalsCalculus defaultCalc = new MarginalsCalculusTriangleInequality(vrp.getTransportCosts(), vrp.getActivityCosts(), constraintManager);
|
||||||
|
JobInsertionCalculator standardServiceInsertion = new CalculatesServiceInsertion(vrp.getTransportCosts(), defaultCalc, constraintManager);
|
||||||
|
|
||||||
((CalculatesServiceInsertion) standardServiceInsertion).setNeighborhood(vrp.getNeighborhood());
|
((CalculatesServiceInsertion) standardServiceInsertion).setNeighborhood(vrp.getNeighborhood());
|
||||||
CalculatorPlusListeners calcPlusListeners = new CalculatorPlusListeners(standardServiceInsertion);
|
CalculatorPlusListeners calcPlusListeners = new CalculatorPlusListeners(standardServiceInsertion);
|
||||||
|
|
@ -246,6 +251,10 @@ class CalculatorBuilder {
|
||||||
return new CalculatesVehTypeDepServiceInsertion(fleetManager, baseCalc);
|
return new CalculatesVehTypeDepServiceInsertion(fleetManager, baseCalc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setConstraintManager(ConstraintManager constraintManager) {
|
||||||
|
this.constraintManager = constraintManager;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,9 +32,11 @@ import java.util.Set;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import util.RandomNumberGeneration;
|
import util.RandomNumberGeneration;
|
||||||
|
import algorithms.RuinStrategy.RuinListener;
|
||||||
import basics.Job;
|
import basics.Job;
|
||||||
import basics.VehicleRoutingProblem;
|
import basics.VehicleRoutingProblem;
|
||||||
import basics.VehicleRoutingProblemSolution;
|
import basics.VehicleRoutingProblemSolution;
|
||||||
|
import basics.algo.InsertionListener;
|
||||||
import basics.algo.SearchStrategyModule;
|
import basics.algo.SearchStrategyModule;
|
||||||
import basics.algo.SearchStrategyModuleListener;
|
import basics.algo.SearchStrategyModuleListener;
|
||||||
import basics.route.TourActivity;
|
import basics.route.TourActivity;
|
||||||
|
|
@ -53,8 +55,6 @@ final class Gendreau implements SearchStrategyModule{
|
||||||
|
|
||||||
private final InsertionStrategy insertionStrategy;
|
private final InsertionStrategy insertionStrategy;
|
||||||
|
|
||||||
private final Inserter inserter;
|
|
||||||
|
|
||||||
private VehicleFleetManager fleetManager;
|
private VehicleFleetManager fleetManager;
|
||||||
|
|
||||||
private Random random = RandomNumberGeneration.getRandom();
|
private Random random = RandomNumberGeneration.getRandom();
|
||||||
|
|
@ -71,7 +71,7 @@ final class Gendreau implements SearchStrategyModule{
|
||||||
super();
|
super();
|
||||||
InsertionListeners insertionListeners = new InsertionListeners();
|
InsertionListeners insertionListeners = new InsertionListeners();
|
||||||
insertionListeners.addAllListeners(insertionStrategy.getListeners());
|
insertionListeners.addAllListeners(insertionStrategy.getListeners());
|
||||||
inserter = new Inserter(insertionListeners);
|
new Inserter(insertionListeners);
|
||||||
this.ruin = ruin;
|
this.ruin = ruin;
|
||||||
this.vrp = vrp;
|
this.vrp = vrp;
|
||||||
this.insertionStrategy = insertionStrategy;
|
this.insertionStrategy = insertionStrategy;
|
||||||
|
|
@ -205,7 +205,18 @@ final class Gendreau implements SearchStrategyModule{
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addModuleListener(SearchStrategyModuleListener moduleListener) {
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,9 +11,24 @@ import basics.Service;
|
||||||
import basics.costs.VehicleRoutingTransportCosts;
|
import basics.costs.VehicleRoutingTransportCosts;
|
||||||
import basics.route.DeliveryActivity;
|
import basics.route.DeliveryActivity;
|
||||||
import basics.route.PickupActivity;
|
import basics.route.PickupActivity;
|
||||||
|
import basics.route.ServiceActivity;
|
||||||
import basics.route.Start;
|
import basics.route.Start;
|
||||||
import basics.route.TourActivity;
|
import basics.route.TourActivity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* collection of hard constrainters bot at activity and at route level.
|
||||||
|
*
|
||||||
|
* <p>HardPickupAndDeliveryLoadConstraint requires LOAD_AT_DEPOT and LOAD (i.e. load at end) at route-level
|
||||||
|
*
|
||||||
|
* <p>HardTimeWindowConstraint requires LATEST_OPERATION_START_TIME
|
||||||
|
*
|
||||||
|
* <p>HardPickupAndDeliveryConstraint requires LOAD_AT_DEPOT and LOAD at route-level and FUTURE_PICKS and PAST_DELIVIERS on activity-level
|
||||||
|
*
|
||||||
|
* <p>HardPickupAndDeliveryBackhaulConstraint requires LOAD_AT_DEPOT and LOAD at route-level and FUTURE_PICKS and PAST_DELIVIERS on activity-level
|
||||||
|
*
|
||||||
|
* @author stefan
|
||||||
|
*
|
||||||
|
*/
|
||||||
class HardConstraints {
|
class HardConstraints {
|
||||||
|
|
||||||
interface HardRouteLevelConstraint {
|
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 {
|
static class HardActivityLevelConstraintManager implements HardActivityLevelConstraint {
|
||||||
|
|
||||||
|
|
@ -90,6 +129,12 @@ class HardConstraints {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* lsjdfjsdlfjsa
|
||||||
|
*
|
||||||
|
* @author stefan
|
||||||
|
*
|
||||||
|
*/
|
||||||
static class HardPickupAndDeliveryLoadConstraint implements HardRouteLevelConstraint {
|
static class HardPickupAndDeliveryLoadConstraint implements HardRouteLevelConstraint {
|
||||||
|
|
||||||
private StateManager stateManager;
|
private StateManager stateManager;
|
||||||
|
|
@ -107,7 +152,7 @@ class HardConstraints {
|
||||||
return false;
|
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();
|
int loadAtEnd = (int) stateManager.getRouteState(insertionContext.getRoute(), StateTypes.LOAD).toDouble();
|
||||||
if(loadAtEnd + insertionContext.getJob().getCapacityDemand() > insertionContext.getNewVehicle().getCapacity()){
|
if(loadAtEnd + insertionContext.getJob().getCapacityDemand() > insertionContext.getNewVehicle().getCapacity()){
|
||||||
return false;
|
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 StateManager states;
|
||||||
|
|
||||||
private VehicleRoutingTransportCosts routingCosts;
|
private VehicleRoutingTransportCosts routingCosts;
|
||||||
|
|
||||||
public HardTimeWindowConstraint(StateManager states, VehicleRoutingTransportCosts routingCosts) {
|
public HardTimeWindowActivityLevelConstraint(StateManager states, VehicleRoutingTransportCosts routingCosts) {
|
||||||
super();
|
super();
|
||||||
this.states = states;
|
this.states = states;
|
||||||
this.routingCosts = routingCosts;
|
this.routingCosts = routingCosts;
|
||||||
|
|
@ -152,11 +202,11 @@ class HardConstraints {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static class HardPickupAndDeliveryConstraint implements HardActivityLevelConstraint {
|
static class HardPickupAndDeliveryActivityLevelConstraint implements HardActivityLevelConstraint {
|
||||||
|
|
||||||
private StateManager stateManager;
|
private StateManager stateManager;
|
||||||
|
|
||||||
public HardPickupAndDeliveryConstraint(StateManager stateManager) {
|
public HardPickupAndDeliveryActivityLevelConstraint(StateManager stateManager) {
|
||||||
super();
|
super();
|
||||||
this.stateManager = stateManager;
|
this.stateManager = stateManager;
|
||||||
}
|
}
|
||||||
|
|
@ -176,7 +226,7 @@ class HardConstraints {
|
||||||
futurePicks = (int) stateManager.getActivityState(prevAct, StateTypes.FUTURE_PICKS).toDouble();
|
futurePicks = (int) stateManager.getActivityState(prevAct, StateTypes.FUTURE_PICKS).toDouble();
|
||||||
pastDeliveries = (int) stateManager.getActivityState(prevAct, StateTypes.PAST_DELIVERIES).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()){
|
if(loadAtPrevAct + newAct.getCapacityDemand() + futurePicks > iFacts.getNewVehicle().getCapacity()){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -192,11 +242,11 @@ class HardConstraints {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static class HardPickupAndDeliveryBackhaulConstraint implements HardActivityLevelConstraint {
|
static class HardPickupAndDeliveryBackhaulActivityLevelConstraint implements HardActivityLevelConstraint {
|
||||||
|
|
||||||
private StateManager stateManager;
|
private StateManager stateManager;
|
||||||
|
|
||||||
public HardPickupAndDeliveryBackhaulConstraint(StateManager stateManager) {
|
public HardPickupAndDeliveryBackhaulActivityLevelConstraint(StateManager stateManager) {
|
||||||
super();
|
super();
|
||||||
this.stateManager = stateManager;
|
this.stateManager = stateManager;
|
||||||
}
|
}
|
||||||
|
|
@ -204,7 +254,9 @@ class HardConstraints {
|
||||||
@Override
|
@Override
|
||||||
public boolean fulfilled(InsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
|
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 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 PickupActivity){ return false; }
|
||||||
|
if(newAct instanceof DeliveryActivity && prevAct instanceof ServiceActivity){ return false; }
|
||||||
int loadAtPrevAct;
|
int loadAtPrevAct;
|
||||||
int futurePicks;
|
int futurePicks;
|
||||||
int pastDeliveries;
|
int pastDeliveries;
|
||||||
|
|
@ -218,7 +270,7 @@ class HardConstraints {
|
||||||
futurePicks = (int) stateManager.getActivityState(prevAct, StateTypes.FUTURE_PICKS).toDouble();
|
futurePicks = (int) stateManager.getActivityState(prevAct, StateTypes.FUTURE_PICKS).toDouble();
|
||||||
pastDeliveries = (int) stateManager.getActivityState(prevAct, StateTypes.PAST_DELIVERIES).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()){
|
if(loadAtPrevAct + newAct.getCapacityDemand() + futurePicks > iFacts.getNewVehicle().getCapacity()){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ import java.util.concurrent.ExecutorService;
|
||||||
import org.apache.commons.configuration.HierarchicalConfiguration;
|
import org.apache.commons.configuration.HierarchicalConfiguration;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
import algorithms.HardConstraints.ConstraintManager;
|
||||||
import algorithms.StateUpdates.UpdateStates;
|
import algorithms.StateUpdates.UpdateStates;
|
||||||
import basics.VehicleRoutingProblem;
|
import basics.VehicleRoutingProblem;
|
||||||
import basics.algo.InsertionListener;
|
import basics.algo.InsertionListener;
|
||||||
|
|
@ -37,7 +38,7 @@ class InsertionFactory {
|
||||||
private static Logger log = Logger.getLogger(InsertionFactory.class);
|
private static Logger log = Logger.getLogger(InsertionFactory.class);
|
||||||
|
|
||||||
public static InsertionStrategy createInsertion(VehicleRoutingProblem vrp, HierarchicalConfiguration config,
|
public static InsertionStrategy createInsertion(VehicleRoutingProblem vrp, HierarchicalConfiguration config,
|
||||||
VehicleFleetManager vehicleFleetManager, StateManagerImpl routeStates, List<PrioritizedVRAListener> algorithmListeners, ExecutorService executorService, int nuOfThreads){
|
VehicleFleetManager vehicleFleetManager, StateManagerImpl routeStates, List<PrioritizedVRAListener> algorithmListeners, ExecutorService executorService, int nuOfThreads, ConstraintManager constraintManager){
|
||||||
boolean concurrentInsertion = false;
|
boolean concurrentInsertion = false;
|
||||||
if(executorService != null) concurrentInsertion = true;
|
if(executorService != null) concurrentInsertion = true;
|
||||||
if(config.containsKey("[@name]")){
|
if(config.containsKey("[@name]")){
|
||||||
|
|
@ -53,6 +54,7 @@ class InsertionFactory {
|
||||||
calcBuilder.setStates(routeStates);
|
calcBuilder.setStates(routeStates);
|
||||||
calcBuilder.setVehicleRoutingProblem(vrp);
|
calcBuilder.setVehicleRoutingProblem(vrp);
|
||||||
calcBuilder.setVehicleFleetManager(vehicleFleetManager);
|
calcBuilder.setVehicleFleetManager(vehicleFleetManager);
|
||||||
|
calcBuilder.setConstraintManager(constraintManager);
|
||||||
|
|
||||||
if(config.containsKey("level")){
|
if(config.containsKey("level")){
|
||||||
String level = config.getString("level");
|
String level = config.getString("level");
|
||||||
|
|
@ -102,13 +104,13 @@ class InsertionFactory {
|
||||||
// insertionStrategy = RegretInsertion.newInstance(routeAlgorithm);
|
// insertionStrategy = RegretInsertion.newInstance(routeAlgorithm);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
insertionStrategy.addListener(new RemoveEmptyVehicles(vehicleFleetManager));
|
// insertionStrategy.addListener(new RemoveEmptyVehicles(vehicleFleetManager));
|
||||||
insertionStrategy.addListener(new ResetAndIniFleetManager(vehicleFleetManager));
|
// insertionStrategy.addListener(new ResetAndIniFleetManager(vehicleFleetManager));
|
||||||
insertionStrategy.addListener(new VehicleSwitched(vehicleFleetManager));
|
// insertionStrategy.addListener(new VehicleSwitched(vehicleFleetManager));
|
||||||
|
|
||||||
// insertionStrategy.addListener(new UpdateLoadAtRouteLevel(routeStates));
|
// 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);
|
for(InsertionListener l : insertionListeners) insertionStrategy.addListener(l);
|
||||||
// insertionStrategy.addListener(new FindCheaperVehicle(
|
// insertionStrategy.addListener(new FindCheaperVehicle(
|
||||||
// new FindCheaperVehicleAlgoNew(vehicleFleetManager, tourStateCalculator, auxCalculator)));
|
// new FindCheaperVehicleAlgoNew(vehicleFleetManager, tourStateCalculator, auxCalculator)));
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,9 @@ import algorithms.BackwardInTimeListeners.BackwardInTimeListener;
|
||||||
import algorithms.ForwardInTimeListeners.ForwardInTimeListener;
|
import algorithms.ForwardInTimeListeners.ForwardInTimeListener;
|
||||||
import algorithms.RuinStrategy.RuinListener;
|
import algorithms.RuinStrategy.RuinListener;
|
||||||
import algorithms.StateManager.StateImpl;
|
import algorithms.StateManager.StateImpl;
|
||||||
|
import basics.Delivery;
|
||||||
import basics.Job;
|
import basics.Job;
|
||||||
|
import basics.Pickup;
|
||||||
import basics.Service;
|
import basics.Service;
|
||||||
import basics.VehicleRoutingProblem;
|
import basics.VehicleRoutingProblem;
|
||||||
import basics.VehicleRoutingProblemSolution;
|
import basics.VehicleRoutingProblemSolution;
|
||||||
|
|
@ -27,6 +29,7 @@ import basics.costs.VehicleRoutingTransportCosts;
|
||||||
import basics.route.DeliveryActivity;
|
import basics.route.DeliveryActivity;
|
||||||
import basics.route.End;
|
import basics.route.End;
|
||||||
import basics.route.PickupActivity;
|
import basics.route.PickupActivity;
|
||||||
|
import basics.route.ServiceActivity;
|
||||||
import basics.route.Start;
|
import basics.route.Start;
|
||||||
import basics.route.TourActivity;
|
import basics.route.TourActivity;
|
||||||
import basics.route.VehicleRoute;
|
import basics.route.VehicleRoute;
|
||||||
|
|
@ -444,7 +447,7 @@ class StateUpdates {
|
||||||
@Override
|
@Override
|
||||||
public void prevActivity(TourActivity act, double latestDepartureTime, double latestOperationStartTime) {
|
public void prevActivity(TourActivity act, double latestDepartureTime, double latestOperationStartTime) {
|
||||||
stateManager.putActivityState(act, StateTypes.FUTURE_PICKS, new StateImpl(futurePicks));
|
stateManager.putActivityState(act, StateTypes.FUTURE_PICKS, new StateImpl(futurePicks));
|
||||||
if(act instanceof PickupActivity){
|
if(act instanceof PickupActivity || act instanceof ServiceActivity){
|
||||||
futurePicks += act.getCapacityDemand();
|
futurePicks += act.getCapacityDemand();
|
||||||
}
|
}
|
||||||
assert futurePicks <= route.getVehicle().getCapacity() : "sum of pickups must not be > vehicleCap";
|
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 IterateRouteForwardInTime forwardInTimeIterator;
|
||||||
|
|
||||||
private IterateRouteBackwardInTime backwardInTimeIterator;
|
private IterateRouteBackwardInTime backwardInTimeIterator;
|
||||||
|
|
||||||
public WalkThroughAndUpdateRoutesOnceTheyChanged(VehicleRoutingTransportCosts routingCosts) {
|
private Collection<InsertionStarts> insertionStartsListeners;
|
||||||
|
|
||||||
|
private Collection<JobInsertedListener> jobInsertionListeners;
|
||||||
|
|
||||||
|
public UpdateRouteStatesOnceTheRouteHasBeenChanged(VehicleRoutingTransportCosts routingCosts) {
|
||||||
forwardInTimeIterator = new IterateRouteForwardInTime(routingCosts);
|
forwardInTimeIterator = new IterateRouteForwardInTime(routingCosts);
|
||||||
backwardInTimeIterator = new IterateRouteBackwardInTime(routingCosts);
|
backwardInTimeIterator = new IterateRouteBackwardInTime(routingCosts);
|
||||||
|
insertionStartsListeners = new ArrayList<InsertionStarts>();
|
||||||
|
jobInsertionListeners = new ArrayList<JobInsertedListener>();
|
||||||
}
|
}
|
||||||
|
|
||||||
void addListener(ForwardInTimeListener l){
|
void addListener(ForwardInTimeListener l){
|
||||||
|
|
@ -561,15 +628,30 @@ class StateUpdates {
|
||||||
backwardInTimeIterator.addListener(l);
|
backwardInTimeIterator.addListener(l);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void addInsertionStartsListener(InsertionStarts insertionStartListener){
|
||||||
|
insertionStartsListeners.add(insertionStartListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
void addJobInsertedListener(JobInsertedListener jobInsertedListener){
|
||||||
|
jobInsertionListeners.add(jobInsertedListener);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) {
|
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
|
@Override
|
||||||
public void informInsertionStarts(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs) {
|
public void informInsertionStarts(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs) {
|
||||||
// TODO Auto-generated method stub
|
for(VehicleRoute route : vehicleRoutes){
|
||||||
|
for(InsertionStarts insertionsStartsHandler : insertionStartsListeners){
|
||||||
|
insertionsStartsHandler.insertionStarts(route);
|
||||||
|
}
|
||||||
|
forwardInTimeIterator.iterate(route);
|
||||||
|
backwardInTimeIterator.iterate(route);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,12 @@ import org.apache.commons.configuration.HierarchicalConfiguration;
|
||||||
import org.apache.commons.configuration.XMLConfiguration;
|
import org.apache.commons.configuration.XMLConfiguration;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import 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.StateUpdates.UpdateStates;
|
||||||
import algorithms.VehicleRoutingAlgorithms.TypedMap.AbstractKey;
|
import algorithms.VehicleRoutingAlgorithms.TypedMap.AbstractKey;
|
||||||
import algorithms.VehicleRoutingAlgorithms.TypedMap.AcceptorKey;
|
import algorithms.VehicleRoutingAlgorithms.TypedMap.AcceptorKey;
|
||||||
|
|
@ -50,21 +55,19 @@ import algorithms.acceptors.SolutionAcceptor;
|
||||||
import algorithms.selectors.SelectBest;
|
import algorithms.selectors.SelectBest;
|
||||||
import algorithms.selectors.SelectRandomly;
|
import algorithms.selectors.SelectRandomly;
|
||||||
import algorithms.selectors.SolutionSelector;
|
import algorithms.selectors.SolutionSelector;
|
||||||
import basics.Job;
|
|
||||||
import basics.VehicleRoutingAlgorithm;
|
import basics.VehicleRoutingAlgorithm;
|
||||||
import basics.VehicleRoutingProblem;
|
import basics.VehicleRoutingProblem;
|
||||||
|
import basics.VehicleRoutingProblem.Constraint;
|
||||||
import basics.VehicleRoutingProblem.FleetSize;
|
import basics.VehicleRoutingProblem.FleetSize;
|
||||||
import basics.VehicleRoutingProblemSolution;
|
import basics.VehicleRoutingProblemSolution;
|
||||||
import basics.algo.AlgorithmStartsListener;
|
import basics.algo.AlgorithmStartsListener;
|
||||||
import basics.algo.InsertionListener;
|
import basics.algo.InsertionListener;
|
||||||
import basics.algo.IterationStartsListener;
|
|
||||||
import basics.algo.IterationWithoutImprovementBreaker;
|
import basics.algo.IterationWithoutImprovementBreaker;
|
||||||
import basics.algo.PrematureAlgorithmBreaker;
|
import basics.algo.PrematureAlgorithmBreaker;
|
||||||
import basics.algo.SearchStrategy;
|
import basics.algo.SearchStrategy;
|
||||||
import basics.algo.SearchStrategy.DiscoveredSolution;
|
import basics.algo.SearchStrategy.DiscoveredSolution;
|
||||||
import basics.algo.SearchStrategyManager;
|
import basics.algo.SearchStrategyManager;
|
||||||
import basics.algo.SearchStrategyModule;
|
import basics.algo.SearchStrategyModule;
|
||||||
import basics.algo.SearchStrategyModuleListener;
|
|
||||||
import basics.algo.TimeBreaker;
|
import basics.algo.TimeBreaker;
|
||||||
import basics.algo.VariationCoefficientBreaker;
|
import basics.algo.VariationCoefficientBreaker;
|
||||||
import basics.algo.VehicleRoutingAlgorithmListeners.PrioritizedVRAListener;
|
import basics.algo.VehicleRoutingAlgorithmListeners.PrioritizedVRAListener;
|
||||||
|
|
@ -428,49 +431,42 @@ public class VehicleRoutingAlgorithms {
|
||||||
|
|
||||||
private static VehicleRoutingAlgorithm createAlgo(final VehicleRoutingProblem vrp, XMLConfiguration config, ExecutorService executorService, int nuOfThreads){
|
private static VehicleRoutingAlgorithm createAlgo(final VehicleRoutingProblem vrp, XMLConfiguration config, ExecutorService executorService, int nuOfThreads){
|
||||||
|
|
||||||
//fleetmanager
|
// map to store constructed modules
|
||||||
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");
|
|
||||||
}
|
|
||||||
|
|
||||||
Set<PrioritizedVRAListener> algorithmListeners = new HashSet<PrioritizedVRAListener>();
|
|
||||||
List<InsertionListener> insertionListeners = new ArrayList<InsertionListener>();
|
|
||||||
|
|
||||||
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<VehicleRoutingProblemSolution> solutions) {
|
|
||||||
routeStates.clear();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
algorithmListeners.add(new PrioritizedVRAListener(Priority.LOW, resetStates));
|
|
||||||
|
|
||||||
// insertionListeners.add(new UdateCostsAtRouteLevel(routeStates,vrp.getTransportCosts(),vrp.getActivityCosts()));
|
|
||||||
|
|
||||||
// RouteStates routeStates = new RouteStates();
|
|
||||||
// routeStates.initialiseStateOfJobs(vrp.getJobs().values());
|
|
||||||
// algorithmListeners.add(new PrioritizedVRAListener(Priority.LOW, routeStates));
|
|
||||||
|
|
||||||
TypedMap definedClasses = new TypedMap();
|
TypedMap definedClasses = new TypedMap();
|
||||||
|
|
||||||
|
// algorithm listeners
|
||||||
|
Set<PrioritizedVRAListener> algorithmListeners = new HashSet<PrioritizedVRAListener>();
|
||||||
|
|
||||||
|
// insertion listeners
|
||||||
|
List<InsertionListener> insertionListeners = new ArrayList<InsertionListener>();
|
||||||
|
|
||||||
|
//create fleetmanager
|
||||||
|
final VehicleFleetManager vehicleFleetManager = createFleetManager(vrp);
|
||||||
|
|
||||||
|
//create state-manager
|
||||||
|
final StateManagerImpl stateManager = new StateManagerImpl();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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));
|
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");
|
int solutionMemory = config.getInt("strategy.memory");
|
||||||
SearchStrategyManager searchStratManager = new SearchStrategyManager();
|
SearchStrategyManager searchStratManager = new SearchStrategyManager();
|
||||||
List<HierarchicalConfiguration> strategyConfigs = config.configurationsAt("strategy.searchStrategies.searchStrategy");
|
List<HierarchicalConfiguration> strategyConfigs = config.configurationsAt("strategy.searchStrategies.searchStrategy");
|
||||||
|
|
@ -482,26 +478,72 @@ public class VehicleRoutingAlgorithms {
|
||||||
strategy.setName(name);
|
strategy.setName(name);
|
||||||
List<HierarchicalConfiguration> modulesConfig = strategyConfig.configurationsAt("modules.module");
|
List<HierarchicalConfiguration> modulesConfig = strategyConfig.configurationsAt("modules.module");
|
||||||
for(HierarchicalConfiguration moduleConfig : modulesConfig){
|
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);
|
strategy.addModule(module);
|
||||||
}
|
}
|
||||||
searchStratManager.addStrategy(strategy, strategyConfig.getDouble("probability"));
|
searchStratManager.addStrategy(strategy, strategyConfig.getDouble("probability"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//construct algorithm
|
||||||
VehicleRoutingAlgorithm metaAlgorithm = new VehicleRoutingAlgorithm(vrp, searchStratManager);
|
VehicleRoutingAlgorithm metaAlgorithm = new VehicleRoutingAlgorithm(vrp, searchStratManager);
|
||||||
if(config.containsKey("iterations")){
|
if(config.containsKey("iterations")){
|
||||||
int iter = config.getInt("iterations");
|
int iter = config.getInt("iterations");
|
||||||
metaAlgorithm.setNuOfIterations(iter);
|
metaAlgorithm.setNuOfIterations(iter);
|
||||||
log.info("set nuOfIterations to " + 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);
|
PrematureAlgorithmBreaker prematureAlgoBreaker = getPrematureBreaker(config,algorithmListeners);
|
||||||
metaAlgorithm.setPrematureAlgorithmBreaker(prematureAlgoBreaker);
|
metaAlgorithm.setPrematureAlgorithmBreaker(prematureAlgoBreaker);
|
||||||
|
|
||||||
|
//misc
|
||||||
|
algorithmListeners.add(new PrioritizedVRAListener(Priority.LOW, new SolutionVerifier()));
|
||||||
|
|
||||||
|
//register listeners
|
||||||
registerListeners(metaAlgorithm,algorithmListeners);
|
registerListeners(metaAlgorithm,algorithmListeners);
|
||||||
registerInsertionListeners(definedClasses,insertionListeners);
|
registerInsertionListeners(definedClasses,insertionListeners);
|
||||||
return metaAlgorithm;
|
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<PrioritizedVRAListener> algorithmListeners) {
|
private static PrematureAlgorithmBreaker getPrematureBreaker(XMLConfiguration config, Set<PrioritizedVRAListener> algorithmListeners) {
|
||||||
String basedOn = config.getString("prematureBreak[@basedOn]");
|
String basedOn = config.getString("prematureBreak[@basedOn]");
|
||||||
if(basedOn == null){
|
if(basedOn == null){
|
||||||
|
|
@ -569,7 +611,7 @@ public class VehicleRoutingAlgorithms {
|
||||||
metaAlgorithm.getAlgorithmListeners().addAll(algorithmListeners);
|
metaAlgorithm.getAlgorithmListeners().addAll(algorithmListeners);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static AlgorithmStartsListener createInitialSolution(XMLConfiguration config, final VehicleRoutingProblem vrp, VehicleFleetManager vehicleFleetManager, StateManagerImpl routeStates, Set<PrioritizedVRAListener> algorithmListeners, TypedMap definedClasses, ExecutorService executorService, int nuOfThreads) {
|
private static AlgorithmStartsListener createInitialSolution(XMLConfiguration config, final VehicleRoutingProblem vrp, VehicleFleetManager vehicleFleetManager, StateManagerImpl routeStates, Set<PrioritizedVRAListener> algorithmListeners, TypedMap definedClasses, ExecutorService executorService, int nuOfThreads, ConstraintManager constraintManager) {
|
||||||
List<HierarchicalConfiguration> modConfigs = config.configurationsAt("construction.insertion");
|
List<HierarchicalConfiguration> modConfigs = config.configurationsAt("construction.insertion");
|
||||||
if(modConfigs == null) return null;
|
if(modConfigs == null) return null;
|
||||||
if(modConfigs.isEmpty()) return null;
|
if(modConfigs.isEmpty()) return null;
|
||||||
|
|
@ -584,7 +626,7 @@ public class VehicleRoutingAlgorithms {
|
||||||
InsertionStrategy insertionStrategy = definedClasses.get(insertionStrategyKey);
|
InsertionStrategy insertionStrategy = definedClasses.get(insertionStrategyKey);
|
||||||
if(insertionStrategy == null){
|
if(insertionStrategy == null){
|
||||||
List<PrioritizedVRAListener> prioListeners = new ArrayList<PrioritizedVRAListener>();
|
List<PrioritizedVRAListener> prioListeners = new ArrayList<PrioritizedVRAListener>();
|
||||||
insertionStrategy = createInsertionStrategy(modConfig, vrp, vehicleFleetManager, routeStates, prioListeners, executorService, nuOfThreads);
|
insertionStrategy = createInsertionStrategy(modConfig, vrp, vehicleFleetManager, routeStates, prioListeners, executorService, nuOfThreads, constraintManager);
|
||||||
algorithmListeners.addAll(prioListeners);
|
algorithmListeners.addAll(prioListeners);
|
||||||
definedClasses.put(insertionStrategyKey,insertionStrategy);
|
definedClasses.put(insertionStrategyKey,insertionStrategy);
|
||||||
}
|
}
|
||||||
|
|
@ -666,7 +708,7 @@ public class VehicleRoutingAlgorithms {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static SearchStrategyModule buildModule(HierarchicalConfiguration moduleConfig, final VehicleRoutingProblem vrp, VehicleFleetManager vehicleFleetManager,
|
private static SearchStrategyModule buildModule(HierarchicalConfiguration moduleConfig, final VehicleRoutingProblem vrp, VehicleFleetManager vehicleFleetManager,
|
||||||
final StateManagerImpl routeStates, Set<PrioritizedVRAListener> algorithmListeners, TypedMap definedClasses, ExecutorService executorService, int nuOfThreads) {
|
final StateManagerImpl routeStates, Set<PrioritizedVRAListener> algorithmListeners, TypedMap definedClasses, ExecutorService executorService, int nuOfThreads, ConstraintManager constraintManager) {
|
||||||
String moduleName = moduleConfig.getString("[@name]");
|
String moduleName = moduleConfig.getString("[@name]");
|
||||||
if(moduleName == null) throw new IllegalStateException("module(-name) is missing.");
|
if(moduleName == null) throw new IllegalStateException("module(-name) is missing.");
|
||||||
String moduleId = moduleConfig.getString("[@id]");
|
String moduleId = moduleConfig.getString("[@id]");
|
||||||
|
|
@ -715,49 +757,14 @@ public class VehicleRoutingAlgorithms {
|
||||||
List<HierarchicalConfiguration> insertionConfigs = moduleConfig.configurationsAt("insertion");
|
List<HierarchicalConfiguration> insertionConfigs = moduleConfig.configurationsAt("insertion");
|
||||||
if(insertionConfigs.size() != 1) throw new IllegalStateException("this should be 1");
|
if(insertionConfigs.size() != 1) throw new IllegalStateException("this should be 1");
|
||||||
List<PrioritizedVRAListener> prioListeners = new ArrayList<PrioritizedVRAListener>();
|
List<PrioritizedVRAListener> prioListeners = new ArrayList<PrioritizedVRAListener>();
|
||||||
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);
|
algorithmListeners.addAll(prioListeners);
|
||||||
}
|
}
|
||||||
final InsertionStrategy final_insertion = insertion;
|
final InsertionStrategy final_insertion = insertion;
|
||||||
SearchStrategyModule module = new SearchStrategyModule() {
|
|
||||||
|
|
||||||
private Logger logger = Logger.getLogger(SearchStrategyModule.class);
|
RuinAndRecreateModule rrModule = new RuinAndRecreateModule("ruin_and_recreate", final_insertion, ruin);
|
||||||
|
return rrModule;
|
||||||
@Override
|
|
||||||
public VehicleRoutingProblemSolution runAndGetSolution(VehicleRoutingProblemSolution vrpSolution) {
|
|
||||||
Collection<Job> 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(moduleName.equals("gendreau")){
|
if(moduleName.equals("gendreau")){
|
||||||
int iterations = moduleConfig.getInt("iterations");
|
int iterations = moduleConfig.getInt("iterations");
|
||||||
double share = moduleConfig.getDouble("share");
|
double share = moduleConfig.getDouble("share");
|
||||||
|
|
@ -770,7 +777,6 @@ public class VehicleRoutingAlgorithms {
|
||||||
RuinStrategy ruin = definedClasses.get(stratKey);
|
RuinStrategy ruin = definedClasses.get(stratKey);
|
||||||
if(ruin == null){
|
if(ruin == null){
|
||||||
ruin = new RuinRadial(vrp, 0.3, new JobDistanceAvgCosts(vrp.getTransportCosts()));
|
ruin = new RuinRadial(vrp, 0.3, new JobDistanceAvgCosts(vrp.getTransportCosts()));
|
||||||
ruin.addListener(new UpdateStates(routeStates, vrp.getTransportCosts(), vrp.getActivityCosts()));
|
|
||||||
definedClasses.put(stratKey, ruin);
|
definedClasses.put(stratKey, ruin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -785,7 +791,7 @@ public class VehicleRoutingAlgorithms {
|
||||||
List<HierarchicalConfiguration> insertionConfigs = moduleConfig.configurationsAt("insertion");
|
List<HierarchicalConfiguration> insertionConfigs = moduleConfig.configurationsAt("insertion");
|
||||||
if(insertionConfigs.size() != 1) throw new IllegalStateException("this should be 1");
|
if(insertionConfigs.size() != 1) throw new IllegalStateException("this should be 1");
|
||||||
List<PrioritizedVRAListener> prioListeners = new ArrayList<PrioritizedVRAListener>();
|
List<PrioritizedVRAListener> prioListeners = new ArrayList<PrioritizedVRAListener>();
|
||||||
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);
|
algorithmListeners.addAll(prioListeners);
|
||||||
}
|
}
|
||||||
Gendreau gendreau = new Gendreau(vrp, ruin, insertion);
|
Gendreau gendreau = new Gendreau(vrp, ruin, insertion);
|
||||||
|
|
@ -809,7 +815,6 @@ public class VehicleRoutingAlgorithms {
|
||||||
RuinStrategy ruin = definedClasses.get(stratKey);
|
RuinStrategy ruin = definedClasses.get(stratKey);
|
||||||
if(ruin == null){
|
if(ruin == null){
|
||||||
ruin = new RuinRadial(vrp, shareToRuin, jobDistance);
|
ruin = new RuinRadial(vrp, shareToRuin, jobDistance);
|
||||||
ruin.addListener(new UpdateStates(routeStates, vrp.getTransportCosts(), vrp.getActivityCosts()));
|
|
||||||
definedClasses.put(stratKey, ruin);
|
definedClasses.put(stratKey, ruin);
|
||||||
}
|
}
|
||||||
return ruin;
|
return ruin;
|
||||||
|
|
@ -820,14 +825,13 @@ public class VehicleRoutingAlgorithms {
|
||||||
RuinStrategy ruin = definedClasses.get(stratKey);
|
RuinStrategy ruin = definedClasses.get(stratKey);
|
||||||
if(ruin == null){
|
if(ruin == null){
|
||||||
ruin = new RuinRandom(vrp, shareToRuin);
|
ruin = new RuinRandom(vrp, shareToRuin);
|
||||||
ruin.addListener(new UpdateStates(routeStates, vrp.getTransportCosts(), vrp.getActivityCosts()));
|
|
||||||
definedClasses.put(stratKey, ruin);
|
definedClasses.put(stratKey, ruin);
|
||||||
}
|
}
|
||||||
return ruin;
|
return ruin;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static InsertionStrategy createInsertionStrategy(HierarchicalConfiguration moduleConfig, VehicleRoutingProblem vrp,VehicleFleetManager vehicleFleetManager, StateManagerImpl routeStates, List<PrioritizedVRAListener> algorithmListeners, ExecutorService executorService, int nuOfThreads) {
|
private static InsertionStrategy createInsertionStrategy(HierarchicalConfiguration moduleConfig, VehicleRoutingProblem vrp,VehicleFleetManager vehicleFleetManager, StateManagerImpl routeStates, List<PrioritizedVRAListener> algorithmListeners, ExecutorService executorService, int nuOfThreads, ConstraintManager constraintManager) {
|
||||||
InsertionStrategy insertion = InsertionFactory.createInsertion(vrp, moduleConfig, vehicleFleetManager, routeStates, algorithmListeners, executorService, nuOfThreads);
|
InsertionStrategy insertion = InsertionFactory.createInsertion(vrp, moduleConfig, vehicleFleetManager, routeStates, algorithmListeners, executorService, nuOfThreads, constraintManager);
|
||||||
return insertion;
|
return insertion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -55,8 +55,8 @@ public class BuildPDVRPAlgoFromScratchTest {
|
||||||
final StateManagerImpl stateManager = new StateManagerImpl();
|
final StateManagerImpl stateManager = new StateManagerImpl();
|
||||||
|
|
||||||
HardActivityLevelConstraintManager actLevelConstraintAccumulator = new HardActivityLevelConstraintManager();
|
HardActivityLevelConstraintManager actLevelConstraintAccumulator = new HardActivityLevelConstraintManager();
|
||||||
actLevelConstraintAccumulator.addConstraint(new HardConstraints.HardPickupAndDeliveryConstraint(stateManager));
|
actLevelConstraintAccumulator.addConstraint(new HardConstraints.HardPickupAndDeliveryActivityLevelConstraint(stateManager));
|
||||||
actLevelConstraintAccumulator.addConstraint(new HardConstraints.HardTimeWindowConstraint(stateManager, vrp.getTransportCosts()));
|
actLevelConstraintAccumulator.addConstraint(new HardConstraints.HardTimeWindowActivityLevelConstraint(stateManager, vrp.getTransportCosts()));
|
||||||
|
|
||||||
MarginalsCalculus marginalCalculus = new MarginalsCalculusTriangleInequality(vrp.getTransportCosts(), vrp.getActivityCosts(), actLevelConstraintAccumulator);
|
MarginalsCalculus marginalCalculus = new MarginalsCalculusTriangleInequality(vrp.getTransportCosts(), vrp.getActivityCosts(), actLevelConstraintAccumulator);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -152,7 +152,7 @@ public class GendreauPostOptTest {
|
||||||
|
|
||||||
activityCosts = new ExampleActivityCostFunction();
|
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);
|
CalculatesServiceInsertionConsideringFixCost withFixCost = new CalculatesServiceInsertionConsideringFixCost(standardServiceInsertion, states);
|
||||||
withFixCost.setWeightOfFixCost(1.2);
|
withFixCost.setWeightOfFixCost(1.2);
|
||||||
|
|
|
||||||
|
|
@ -157,7 +157,7 @@ public class TestCalculatesServiceInsertion {
|
||||||
|
|
||||||
ExampleActivityCostFunction activityCosts = new ExampleActivityCostFunction();
|
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);
|
stateUpdater = new UpdateStates(states, costs, activityCosts);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -201,7 +201,7 @@ public class RefuseCollectionExample {
|
||||||
VehicleRoutingProblem vrp = vrpBuilder.build();
|
VehicleRoutingProblem vrp = vrpBuilder.build();
|
||||||
|
|
||||||
VehicleRoutingAlgorithm vra = new GreedySchrimpfFactory().createAlgorithm(vrp);
|
VehicleRoutingAlgorithm vra = new GreedySchrimpfFactory().createAlgorithm(vrp);
|
||||||
vra.setPrematureBreak(10);
|
vra.setPrematureBreak(100);
|
||||||
Collection<VehicleRoutingProblemSolution> solutions = vra.searchSolutions();
|
Collection<VehicleRoutingProblemSolution> solutions = vra.searchSolutions();
|
||||||
|
|
||||||
SolutionPrinter.print(Solutions.getBest(solutions),Print.VERBOSE);
|
SolutionPrinter.print(Solutions.getBest(solutions),Print.VERBOSE);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue