1
0
Fork 0
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:
Stefan Schroeder 2013-09-02 17:21:51 +02:00
parent 0806d524e6
commit 26219aa3a1
10 changed files with 283 additions and 123 deletions

View file

@ -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;
}
}

View file

@ -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);
}
}
}
}

View file

@ -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.
*
* <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 {
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;
}

View file

@ -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<PrioritizedVRAListener> algorithmListeners, ExecutorService executorService, int nuOfThreads){
VehicleFleetManager vehicleFleetManager, StateManagerImpl routeStates, List<PrioritizedVRAListener> 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)));

View file

@ -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<InsertionStarts> insertionStartsListeners;
private Collection<JobInsertedListener> jobInsertionListeners;
public UpdateRouteStatesOnceTheRouteHasBeenChanged(VehicleRoutingTransportCosts routingCosts) {
forwardInTimeIterator = new IterateRouteForwardInTime(routingCosts);
backwardInTimeIterator = new IterateRouteBackwardInTime(routingCosts);
insertionStartsListeners = new ArrayList<InsertionStarts>();
jobInsertionListeners = new ArrayList<JobInsertedListener>();
}
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<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);
}
}
}

View file

@ -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<PrioritizedVRAListener> algorithmListeners = new HashSet<PrioritizedVRAListener>();
// insertion listeners
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));
//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<HierarchicalConfiguration> strategyConfigs = config.configurationsAt("strategy.searchStrategies.searchStrategy");
@ -482,26 +478,72 @@ public class VehicleRoutingAlgorithms {
strategy.setName(name);
List<HierarchicalConfiguration> 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<PrioritizedVRAListener> 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<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");
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<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);
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<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]");
if(moduleName == null) throw new IllegalStateException("module(-name) is missing.");
String moduleId = moduleConfig.getString("[@id]");
@ -715,49 +757,14 @@ public class VehicleRoutingAlgorithms {
List<HierarchicalConfiguration> insertionConfigs = moduleConfig.configurationsAt("insertion");
if(insertionConfigs.size() != 1) throw new IllegalStateException("this should be 1");
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);
}
final InsertionStrategy final_insertion = insertion;
SearchStrategyModule module = new SearchStrategyModule() {
private Logger logger = Logger.getLogger(SearchStrategyModule.class);
@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;
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<HierarchicalConfiguration> insertionConfigs = moduleConfig.configurationsAt("insertion");
if(insertionConfigs.size() != 1) throw new IllegalStateException("this should be 1");
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);
}
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<PrioritizedVRAListener> 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<PrioritizedVRAListener> algorithmListeners, ExecutorService executorService, int nuOfThreads, ConstraintManager constraintManager) {
InsertionStrategy insertion = InsertionFactory.createInsertion(vrp, moduleConfig, vehicleFleetManager, routeStates, algorithmListeners, executorService, nuOfThreads, constraintManager);
return insertion;
}

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -201,7 +201,7 @@ public class RefuseCollectionExample {
VehicleRoutingProblem vrp = vrpBuilder.build();
VehicleRoutingAlgorithm vra = new GreedySchrimpfFactory().createAlgorithm(vrp);
vra.setPrematureBreak(10);
vra.setPrematureBreak(100);
Collection<VehicleRoutingProblemSolution> solutions = vra.searchSolutions();
SolutionPrinter.print(Solutions.getBest(solutions),Print.VERBOSE);