diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/VehicleRoutingAlgorithmBuilder.java b/jsprit-core/src/main/java/jsprit/core/algorithm/VehicleRoutingAlgorithmBuilder.java index 834049f9..b1f3e25f 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/VehicleRoutingAlgorithmBuilder.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/VehicleRoutingAlgorithmBuilder.java @@ -1,11 +1,76 @@ package jsprit.core.algorithm; +import jsprit.core.algorithm.io.VehicleRoutingAlgorithms; +import jsprit.core.algorithm.state.StateManager; +import jsprit.core.algorithm.state.UpdateActivityTimes; +import jsprit.core.algorithm.state.UpdateEndLocationIfRouteIsOpen; +import jsprit.core.algorithm.state.UpdateVariableCosts; import jsprit.core.problem.VehicleRoutingProblem; +import jsprit.core.problem.constraint.ConstraintManager; +import jsprit.core.problem.solution.SolutionCostCalculator; public class VehicleRoutingAlgorithmBuilder { + private final String algorithmConfig; + + private final VehicleRoutingProblem vrp; + + private SolutionCostCalculator solutionCostCalculator; + + private StateManager stateManager; + + private boolean addCoreConstraints = false; + + private boolean addDefaultCostCalculators = false; + + private ConstraintManager constraintManager; + + private int nuOfThreads=0; + public VehicleRoutingAlgorithmBuilder(VehicleRoutingProblem problem, String algorithmConfig) { - + this.vrp=problem; + this.algorithmConfig=algorithmConfig; + } + + public void setObjectiveFunction(SolutionCostCalculator objectiveFunction) { + this.solutionCostCalculator = objectiveFunction; + } + + public void setStateManager(StateManager stateManager) { + this.stateManager=stateManager; + } + + public void addCoreConstraints() { + addCoreConstraints=true; + } + + public void addDefaultCostCalculators() { + addDefaultCostCalculators=true; + } + + public void setConstraintManager(ConstraintManager constraintManager) { + this.constraintManager=constraintManager; + } + + public void setNuOfThreads(int nuOfThreads){ + this.nuOfThreads=nuOfThreads; + } + + public VehicleRoutingAlgorithm build() { + if(stateManager == null) stateManager = new StateManager(vrp.getTransportCosts()); + if(constraintManager == null) constraintManager = new ConstraintManager(vrp,stateManager,vrp.getConstraints()); + //add core updater + stateManager.addStateUpdater(new UpdateEndLocationIfRouteIsOpen()); +// stateManager.addStateUpdater(new OpenRouteStateVerifier()); + stateManager.addStateUpdater(new UpdateActivityTimes(vrp.getTransportCosts())); + stateManager.addStateUpdater(new UpdateVariableCosts(vrp.getActivityCosts(), vrp.getTransportCosts(), stateManager)); + if(addCoreConstraints){ + constraintManager.addLoadConstraint(); + constraintManager.addTimeWindowConstraint(); + stateManager.updateLoadStates(); + stateManager.updateTimeWindowStates(); + } + return VehicleRoutingAlgorithms.readAndCreateAlgorithm(vrp, algorithmConfig, nuOfThreads, solutionCostCalculator, stateManager, constraintManager, addDefaultCostCalculators); } diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/io/InsertionFactory.java b/jsprit-core/src/main/java/jsprit/core/algorithm/io/InsertionFactory.java index 9a4f49a5..f6d92743 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/io/InsertionFactory.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/io/InsertionFactory.java @@ -39,7 +39,7 @@ class InsertionFactory { @SuppressWarnings("deprecation") public static InsertionStrategy createInsertion(VehicleRoutingProblem vrp, HierarchicalConfiguration config, - VehicleFleetManager vehicleFleetManager, StateManager routeStates, List algorithmListeners, ExecutorService executorService, int nuOfThreads, ConstraintManager constraintManager){ + VehicleFleetManager vehicleFleetManager, StateManager routeStates, List algorithmListeners, ExecutorService executorService, int nuOfThreads, ConstraintManager constraintManager, boolean addDefaultCostCalculators){ if(config.containsKey("[@name]")){ String insertionName = config.getString("[@name]"); @@ -59,8 +59,7 @@ class InsertionFactory { if(config.containsKey("level")){ String level = config.getString("level"); if(level.equals("local")){ - iBuilder.setLocalLevel(); -// calcBuilder.setLocalLevel(); + iBuilder.setLocalLevel(addDefaultCostCalculators); } else if(level.equals("route")){ int forwardLooking = 0; @@ -71,30 +70,31 @@ class InsertionFactory { else log.warn("parameter route[@forwardLooking] is missing. by default it is 0 which equals to local level"); if(mem != null) memory = Integer.parseInt(mem); else log.warn("parameter route[@memory] is missing. by default it is 1"); - iBuilder.setRouteLevel(forwardLooking, memory); -// calcBuilder.setRouteLevel(forwardLooking, memory); + iBuilder.setRouteLevel(forwardLooking, memory, addDefaultCostCalculators); } else throw new IllegalStateException("level " + level + " is not known. currently it only knows \"local\" or \"route\""); } - else iBuilder.setLocalLevel(); + else iBuilder.setLocalLevel(addDefaultCostCalculators); if(config.containsKey("considerFixedCosts") || config.containsKey("considerFixedCost")){ - String val = config.getString("considerFixedCosts"); - if(val == null) val = config.getString("considerFixedCost"); - if(val.equals("true")){ - double fixedCostWeight = 0.5; - String weight = config.getString("considerFixedCosts[@weight]"); - if(weight == null) weight = config.getString("considerFixedCost[@weight]"); - if(weight != null) fixedCostWeight = Double.parseDouble(weight); - else throw new IllegalStateException("fixedCostsParameter 'weight' must be set, e.g. true.\n" + - "this has to be changed in algorithm-config-xml-file."); - iBuilder.considerFixedCosts(fixedCostWeight); + if(addDefaultCostCalculators){ + String val = config.getString("considerFixedCosts"); + if(val == null) val = config.getString("considerFixedCost"); + if(val.equals("true")){ + double fixedCostWeight = 0.5; + String weight = config.getString("considerFixedCosts[@weight]"); + if(weight == null) weight = config.getString("considerFixedCost[@weight]"); + if(weight != null) fixedCostWeight = Double.parseDouble(weight); + else throw new IllegalStateException("fixedCostsParameter 'weight' must be set, e.g. true.\n" + + "this has to be changed in algorithm-config-xml-file."); + iBuilder.considerFixedCosts(fixedCostWeight); + } + else if(val.equals("false")){ + + } + else throw new IllegalStateException("considerFixedCosts must either be true or false, i.e. true or \nfalse. " + + "if latter, you can also omit the tag. this has to be changed in algorithm-config-xml-file"); } - else if(val.equals("false")){ - - } - else throw new IllegalStateException("considerFixedCosts must either be true or false, i.e. true or \nfalse. " + - "if latter, you can also omit the tag. this has to be changed in algorithm-config-xml-file"); } String timeSliceString = config.getString("experimental[@timeSlice]"); String neighbors = config.getString("experimental[@neighboringSlices]"); diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/io/VehicleRoutingAlgorithms.java b/jsprit-core/src/main/java/jsprit/core/algorithm/io/VehicleRoutingAlgorithms.java index 109bf7be..ecddf3f3 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/io/VehicleRoutingAlgorithms.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/io/VehicleRoutingAlgorithms.java @@ -484,8 +484,42 @@ public class VehicleRoutingAlgorithms { } private static VehicleRoutingAlgorithm createAlgo(final VehicleRoutingProblem vrp, XMLConfiguration config, int nuOfThreads, StateManager stateMan){ + //create state-manager + final StateManager stateManager; + if(stateMan!=null) { + stateManager = stateMan; + } + else{ + stateManager = new StateManager(vrp.getTransportCosts()); + } + stateManager.updateLoadStates(); + stateManager.updateTimeWindowStates(); + stateManager.addStateUpdater(new UpdateEndLocationIfRouteIsOpen()); + stateManager.addStateUpdater(new OpenRouteStateVerifier()); + stateManager.addStateUpdater(new UpdateActivityTimes(vrp.getTransportCosts())); + stateManager.addStateUpdater(new UpdateVariableCosts(vrp.getActivityCosts(), vrp.getTransportCosts(), stateManager)); + + /* + * define constraints + */ + //constraint manager + ConstraintManager constraintManager = new ConstraintManager(vrp,stateManager,vrp.getConstraints()); + constraintManager.addTimeWindowConstraint(); + constraintManager.addLoadConstraint(); - + return readAndCreateAlgorithm(vrp, config, nuOfThreads, null, stateManager, constraintManager, true); + } + + public static VehicleRoutingAlgorithm readAndCreateAlgorithm(final VehicleRoutingProblem vrp, String config, + int nuOfThreads, SolutionCostCalculator solutionCostCalculator, final StateManager stateManager, ConstraintManager constraintManager, boolean addDefaultCostCalculators) { + AlgorithmConfig algorithmConfig = new AlgorithmConfig(); + AlgorithmConfigXmlReader xmlReader = new AlgorithmConfigXmlReader(algorithmConfig); + xmlReader.read(config); + return readAndCreateAlgorithm(vrp, algorithmConfig.getXMLConfiguration(),nuOfThreads, solutionCostCalculator, stateManager, constraintManager, addDefaultCostCalculators); + } + + private static VehicleRoutingAlgorithm readAndCreateAlgorithm(final VehicleRoutingProblem vrp, XMLConfiguration config, + int nuOfThreads, SolutionCostCalculator solutionCostCalculator, final StateManager stateManager, ConstraintManager constraintManager, boolean addDefaultCostCalculators) { // map to store constructed modules TypedMap definedClasses = new TypedMap(); @@ -495,6 +529,7 @@ public class VehicleRoutingAlgorithms { // insertion listeners List insertionListeners = new ArrayList(); + //threading final ExecutorService executorService; if(nuOfThreads > 0){ @@ -527,33 +562,12 @@ public class VehicleRoutingAlgorithms { } else executorService = null; - + //create fleetmanager final VehicleFleetManager vehicleFleetManager = createFleetManager(vrp); - - //create state-manager - final StateManager stateManager; - if(stateMan!=null) { - stateManager = stateMan; - } - else{ - stateManager = new StateManager(vrp.getTransportCosts()); - } - stateManager.updateLoadStates(); - stateManager.updateTimeWindowStates(); - stateManager.addStateUpdater(new UpdateEndLocationIfRouteIsOpen()); - stateManager.addStateUpdater(new OpenRouteStateVerifier()); - - /* - * define constraints - */ - //constraint manager - ConstraintManager constraintManager = new ConstraintManager(vrp,stateManager,vrp.getConstraints()); - constraintManager.addTimeWindowConstraint(); - constraintManager.addLoadConstraint(); - + //construct initial solution creator - AlgorithmStartsListener createInitialSolution = createInitialSolution(config,vrp,vehicleFleetManager,stateManager,algorithmListeners,definedClasses,executorService,nuOfThreads,constraintManager); + AlgorithmStartsListener createInitialSolution = createInitialSolution(config,vrp,vehicleFleetManager,stateManager,algorithmListeners,definedClasses,executorService,nuOfThreads,constraintManager, addDefaultCostCalculators); if(createInitialSolution != null) algorithmListeners.add(new PrioritizedVRAListener(Priority.MEDIUM, createInitialSolution)); //construct algorithm, i.e. search-strategies and its modules @@ -564,12 +578,14 @@ public class VehicleRoutingAlgorithms { String name = getName(strategyConfig); SolutionAcceptor acceptor = getAcceptor(strategyConfig,vrp,algorithmListeners,definedClasses,solutionMemory); SolutionSelector selector = getSelector(strategyConfig,vrp,algorithmListeners,definedClasses); - SolutionCostCalculator costCalculator = getCostCalculator(stateManager); + SolutionCostCalculator costCalculator; + if(solutionCostCalculator==null) costCalculator = getDefaultCostCalculator(stateManager); + else costCalculator = solutionCostCalculator; SearchStrategy strategy = new SearchStrategy(selector, acceptor, costCalculator); strategy.setName(name); List modulesConfig = strategyConfig.configurationsAt("modules.module"); for(HierarchicalConfiguration moduleConfig : modulesConfig){ - SearchStrategyModule module = buildModule(moduleConfig,vrp,vehicleFleetManager,stateManager,algorithmListeners,definedClasses,executorService,nuOfThreads, constraintManager); + SearchStrategyModule module = buildModule(moduleConfig,vrp,vehicleFleetManager,stateManager,algorithmListeners,definedClasses,executorService,nuOfThreads, constraintManager, addDefaultCostCalculators); strategy.addModule(module); } searchStratManager.addStrategy(strategy, strategyConfig.getDouble("probability")); @@ -582,14 +598,6 @@ public class VehicleRoutingAlgorithms { metaAlgorithm.setNuOfIterations(iter); } - - /* - * define stateUpdates - */ - stateManager.addStateUpdater(new UpdateActivityTimes(vrp.getTransportCosts())); - stateManager.addStateUpdater(new UpdateVariableCosts(vrp.getActivityCosts(), vrp.getTransportCosts(), stateManager)); - - metaAlgorithm.getSearchStrategyManager().addSearchStrategyModuleListener(stateManager); metaAlgorithm.getAlgorithmListeners().addListener(stateManager); @@ -607,10 +615,10 @@ public class VehicleRoutingAlgorithms { //register listeners registerListeners(metaAlgorithm,algorithmListeners); registerInsertionListeners(definedClasses,insertionListeners); - return metaAlgorithm; + return metaAlgorithm; } - private static SolutionCostCalculator getCostCalculator(final StateManager stateManager) { + private static SolutionCostCalculator getDefaultCostCalculator(final StateManager stateManager) { SolutionCostCalculator calc = new SolutionCostCalculator() { @Override @@ -710,7 +718,7 @@ public class VehicleRoutingAlgorithms { metaAlgorithm.getAlgorithmListeners().addAll(algorithmListeners); } - private static AlgorithmStartsListener createInitialSolution(XMLConfiguration config, final VehicleRoutingProblem vrp, VehicleFleetManager vehicleFleetManager, final StateManager routeStates, Set algorithmListeners, TypedMap definedClasses, ExecutorService executorService, int nuOfThreads, ConstraintManager constraintManager) { + private static AlgorithmStartsListener createInitialSolution(XMLConfiguration config, final VehicleRoutingProblem vrp, VehicleFleetManager vehicleFleetManager, final StateManager routeStates, Set algorithmListeners, TypedMap definedClasses, ExecutorService executorService, int nuOfThreads, ConstraintManager constraintManager, boolean addDefaultCostCalculators) { List modConfigs = config.configurationsAt("construction.insertion"); if(modConfigs == null) return null; if(modConfigs.isEmpty()) return null; @@ -725,7 +733,7 @@ public class VehicleRoutingAlgorithms { InsertionStrategy insertionStrategy = definedClasses.get(insertionStrategyKey); if(insertionStrategy == null){ List prioListeners = new ArrayList(); - insertionStrategy = createInsertionStrategy(modConfig, vrp, vehicleFleetManager, routeStates, prioListeners, executorService, nuOfThreads, constraintManager); + insertionStrategy = createInsertionStrategy(modConfig, vrp, vehicleFleetManager, routeStates, prioListeners, executorService, nuOfThreads, constraintManager, addDefaultCostCalculators); algorithmListeners.addAll(prioListeners); definedClasses.put(insertionStrategyKey,insertionStrategy); } @@ -735,10 +743,7 @@ public class VehicleRoutingAlgorithms { @Override public void informAlgorithmStarts(VehicleRoutingProblem problem, VehicleRoutingAlgorithm algorithm, Collection solutions) { - InsertionInitialSolutionFactory insertionInitialSolutionFactory = new InsertionInitialSolutionFactory(finalInsertionStrategy, getCostCalculator(routeStates)); -// CreateInitialSolution createInitialSolution = new CreateInitialSolution(finalInsertionStrategy, getCostCalculator(routeStates)); -// -// createInitialSolution.setGenerateAsMuchAsRoutesAsVehiclesExist(false); + InsertionInitialSolutionFactory insertionInitialSolutionFactory = new InsertionInitialSolutionFactory(finalInsertionStrategy, getDefaultCostCalculator(routeStates)); VehicleRoutingProblemSolution vrpSol = insertionInitialSolutionFactory.createSolution(vrp); solutions.add(vrpSol); } @@ -825,7 +830,7 @@ public class VehicleRoutingAlgorithms { } private static SearchStrategyModule buildModule(HierarchicalConfiguration moduleConfig, final VehicleRoutingProblem vrp, VehicleFleetManager vehicleFleetManager, - final StateManager routeStates, Set algorithmListeners, TypedMap definedClasses, ExecutorService executorService, int nuOfThreads, ConstraintManager constraintManager) { + final StateManager routeStates, Set algorithmListeners, TypedMap definedClasses, ExecutorService executorService, int nuOfThreads, ConstraintManager constraintManager, boolean addDefaultCostCalculators) { String moduleName = moduleConfig.getString("[@name]"); if(moduleName == null) throw new IllegalStateException("module(-name) is missing."); String moduleId = moduleConfig.getString("[@id]"); @@ -865,7 +870,7 @@ public class VehicleRoutingAlgorithms { List insertionConfigs = moduleConfig.configurationsAt("insertion"); if(insertionConfigs.size() != 1) throw new IllegalStateException("this should be 1"); List prioListeners = new ArrayList(); - insertion = createInsertionStrategy(insertionConfigs.get(0), vrp, vehicleFleetManager, routeStates, prioListeners, executorService, nuOfThreads, constraintManager); + insertion = createInsertionStrategy(insertionConfigs.get(0), vrp, vehicleFleetManager, routeStates, prioListeners, executorService, nuOfThreads, constraintManager, addDefaultCostCalculators); algorithmListeners.addAll(prioListeners); } final InsertionStrategy final_insertion = insertion; @@ -938,8 +943,8 @@ public class VehicleRoutingAlgorithms { return ruin; } - private static InsertionStrategy createInsertionStrategy(HierarchicalConfiguration moduleConfig, VehicleRoutingProblem vrp,VehicleFleetManager vehicleFleetManager, StateManager routeStates, List algorithmListeners, ExecutorService executorService, int nuOfThreads, ConstraintManager constraintManager) { - InsertionStrategy insertion = InsertionFactory.createInsertion(vrp, moduleConfig, vehicleFleetManager, routeStates, algorithmListeners, executorService, nuOfThreads, constraintManager); + private static InsertionStrategy createInsertionStrategy(HierarchicalConfiguration moduleConfig, VehicleRoutingProblem vrp,VehicleFleetManager vehicleFleetManager, StateManager routeStates, List algorithmListeners, ExecutorService executorService, int nuOfThreads, ConstraintManager constraintManager, boolean addDefaultCostCalculators) { + InsertionStrategy insertion = InsertionFactory.createInsertion(vrp, moduleConfig, vehicleFleetManager, routeStates, algorithmListeners, executorService, nuOfThreads, constraintManager, addDefaultCostCalculators); return insertion; } diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/BestInsertionBuilder.java b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/BestInsertionBuilder.java index 7c0a1b5c..695c92f8 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/BestInsertionBuilder.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/BestInsertionBuilder.java @@ -45,6 +45,8 @@ public class BestInsertionBuilder { private boolean timeScheduling=false; private boolean allowVehicleSwitch=true; + + private boolean addDefaultCostCalc=true; public BestInsertionBuilder(VehicleRoutingProblem vrp, VehicleFleetManager vehicleFleetManager, StateManager stateManager, ConstraintManager constraintManager) { super(); @@ -61,11 +63,32 @@ public class BestInsertionBuilder { return this; }; + public BestInsertionBuilder setRouteLevel(int forwardLooking, int memory, boolean addDefaultMarginalCostCalculation){ + local = false; + this.forwaredLooking = forwardLooking; + this.memory = memory; + this.addDefaultCostCalc = addDefaultMarginalCostCalculation; + return this; + }; + public BestInsertionBuilder setLocalLevel(){ local = true; return this; }; + /** + * If addDefaulMarginalCostCalculation is false, no calculator is set which implicitly assumes that marginal cost calculation + * is controlled by your custom soft constraints. + * + * @param addDefaultMarginalCostCalculation + * @return + */ + public BestInsertionBuilder setLocalLevel(boolean addDefaultMarginalCostCalculation){ + local = true; + addDefaultCostCalc = addDefaultMarginalCostCalculation; + return this; + } + public BestInsertionBuilder considerFixedCosts(double weightOfFixedCosts){ this.weightOfFixedCosts = weightOfFixedCosts; this.considerFixedCosts = true; @@ -89,10 +112,10 @@ public class BestInsertionBuilder { List algorithmListeners = new ArrayList(); CalculatorBuilder calcBuilder = new CalculatorBuilder(iListeners, algorithmListeners); if(local){ - calcBuilder.setLocalLevel(); + calcBuilder.setLocalLevel(addDefaultCostCalc); } else { - calcBuilder.setRouteLevel(forwaredLooking, memory); + calcBuilder.setRouteLevel(forwaredLooking, memory, addDefaultCostCalc); } calcBuilder.setConstraintManager(constraintManager); calcBuilder.setStates(stateManager); diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/CalculatorBuilder.java b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/CalculatorBuilder.java index bbac87d2..32ab5348 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/CalculatorBuilder.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/CalculatorBuilder.java @@ -28,6 +28,8 @@ import jsprit.core.problem.job.Job; import jsprit.core.problem.job.Pickup; import jsprit.core.problem.job.Service; import jsprit.core.problem.job.Shipment; +import jsprit.core.problem.misc.JobInsertionContext; +import jsprit.core.problem.solution.route.activity.TourActivity; import jsprit.core.problem.solution.route.state.RouteAndActivityStateGetter; import jsprit.core.problem.vehicle.VehicleFleetManager; @@ -93,6 +95,8 @@ class CalculatorBuilder { private boolean allowVehicleSwitch = true; + private boolean addDefaultCostCalc = true; + /** * Constructs the builder. * @@ -145,9 +149,11 @@ class CalculatorBuilder { * Sets a flag to build a calculator based on local calculations. * *

Insertion of a job and job-activity is evaluated based on the previous and next activity. + * @param addDefaultCostCalc TODO */ - public void setLocalLevel(){ + public void setLocalLevel(boolean addDefaultCostCalc){ local = true; + this.addDefaultCostCalc = addDefaultCostCalc; } public void setActivityInsertionCostsCalculator(ActivityInsertionCostsCalculator activityInsertionCostsCalculator){ @@ -159,8 +165,9 @@ class CalculatorBuilder { * * @param forwardLooking * @param memory + * @param addDefaultMarginalCostCalc TODO */ - public void setRouteLevel(int forwardLooking, int memory){ + public void setRouteLevel(int forwardLooking, int memory, boolean addDefaultMarginalCostCalc){ local = false; this.forwardLooking = forwardLooking; this.memory = memory; @@ -242,12 +249,24 @@ class CalculatorBuilder { private CalculatorPlusListeners createStandardLocal(VehicleRoutingProblem vrp, RouteAndActivityStateGetter statesManager){ if(constraintManager == null) throw new IllegalStateException("constraint-manager is null"); - ActivityInsertionCostsCalculator actInsertionCalc; - if(activityInsertionCostCalculator == null){ + if(activityInsertionCostCalculator == null && addDefaultCostCalc){ actInsertionCalc = new LocalActivityInsertionCostsCalculator(vrp.getTransportCosts(), vrp.getActivityCosts()); } + else if(activityInsertionCostCalculator == null && !addDefaultCostCalc){ + actInsertionCalc = new ActivityInsertionCostsCalculator(){ + + final ActivityInsertionCosts noInsertionCosts = new ActivityInsertionCosts(0.,0.); + + @Override + public ActivityInsertionCosts getCosts(JobInsertionContext iContext, TourActivity prevAct,TourActivity nextAct, TourActivity newAct, + double depTimeAtPrevAct) { + return noInsertionCosts; + } + + }; + } else{ actInsertionCalc = activityInsertionCostCalculator; } @@ -279,9 +298,22 @@ class CalculatorBuilder { private CalculatorPlusListeners createStandardRoute(VehicleRoutingProblem vrp, RouteAndActivityStateGetter activityStates2, int forwardLooking, int solutionMemory){ int after = forwardLooking; ActivityInsertionCostsCalculator routeLevelCostEstimator; - if(activityInsertionCostCalculator == null){ + if(activityInsertionCostCalculator == null && addDefaultCostCalc){ routeLevelCostEstimator = new RouteLevelActivityInsertionCostsEstimator(vrp.getTransportCosts(), vrp.getActivityCosts(), activityStates2); } + else if(activityInsertionCostCalculator == null && !addDefaultCostCalc){ + routeLevelCostEstimator = new ActivityInsertionCostsCalculator(){ + + final ActivityInsertionCosts noInsertionCosts = new ActivityInsertionCosts(0.,0.); + + @Override + public ActivityInsertionCosts getCosts(JobInsertionContext iContext, TourActivity prevAct,TourActivity nextAct, TourActivity newAct, + double depTimeAtPrevAct) { + return noInsertionCosts; + } + + }; + } else{ routeLevelCostEstimator = activityInsertionCostCalculator; } diff --git a/jsprit-examples/src/main/java/jsprit/examples/TransportOfDisabledPeople.java b/jsprit-examples/src/main/java/jsprit/examples/TransportOfDisabledPeople.java index 49bc1ae7..986e226d 100644 --- a/jsprit-examples/src/main/java/jsprit/examples/TransportOfDisabledPeople.java +++ b/jsprit-examples/src/main/java/jsprit/examples/TransportOfDisabledPeople.java @@ -6,27 +6,29 @@ import jsprit.analysis.toolbox.GraphStreamViewer; import jsprit.analysis.toolbox.GraphStreamViewer.Label; import jsprit.analysis.toolbox.Plotter; import jsprit.analysis.toolbox.SolutionPrinter; +import jsprit.analysis.toolbox.SolutionPrinter.Print; import jsprit.core.algorithm.VehicleRoutingAlgorithm; import jsprit.core.algorithm.VehicleRoutingAlgorithmBuilder; -import jsprit.core.algorithm.io.VehicleRoutingAlgorithms; -import jsprit.core.algorithm.recreate.DellAmicoFixCostCalculator; import jsprit.core.algorithm.recreate.VariableTransportCostCalculator; import jsprit.core.algorithm.state.StateManager; import jsprit.core.algorithm.termination.IterationWithoutImprovementTermination; import jsprit.core.problem.VehicleRoutingProblem; import jsprit.core.problem.VehicleRoutingProblem.FleetSize; +import jsprit.core.problem.constraint.ConstraintManager; import jsprit.core.problem.constraint.HardRouteStateLevelConstraint; +import jsprit.core.problem.constraint.SoftActivityConstraint; import jsprit.core.problem.job.Shipment; import jsprit.core.problem.misc.JobInsertionContext; import jsprit.core.problem.solution.SolutionCostCalculator; import jsprit.core.problem.solution.VehicleRoutingProblemSolution; +import jsprit.core.problem.solution.route.VehicleRoute; +import jsprit.core.problem.solution.route.activity.TourActivity; import jsprit.core.problem.vehicle.Vehicle; import jsprit.core.problem.vehicle.VehicleImpl; import jsprit.core.problem.vehicle.VehicleImpl.Builder; import jsprit.core.problem.vehicle.VehicleType; import jsprit.core.problem.vehicle.VehicleTypeImpl; import jsprit.core.util.Coordinate; -import jsprit.core.util.CrowFlyCosts; import jsprit.core.util.Solutions; import jsprit.util.Examples; @@ -67,10 +69,20 @@ public class TransportOfDisabledPeople { vehicleBuilder1.setType(vehicleType_wheelchair); Vehicle vehicle1 = vehicleBuilder1.build(); + Builder vehicleBuilder1_2 = VehicleImpl.Builder.newInstance("wheelchair_bus_2"); + vehicleBuilder1_2.setStartLocationCoordinate(Coordinate.newInstance(10, 10)); + vehicleBuilder1_2.setType(vehicleType_wheelchair); + Vehicle vehicle1_2 = vehicleBuilder1_2.build(); + Builder vehicleBuilder2 = VehicleImpl.Builder.newInstance("passenger_bus"); vehicleBuilder2.setStartLocationCoordinate(Coordinate.newInstance(30, 30)).setEndLocationCoordinate(Coordinate.newInstance(30, 19)); vehicleBuilder2.setType(vehicleType_solelypassenger); Vehicle vehicle2 = vehicleBuilder2.build(); + + Builder vehicleBuilder2_2 = VehicleImpl.Builder.newInstance("passenger_bus_2"); + vehicleBuilder2_2.setStartLocationCoordinate(Coordinate.newInstance(30, 30)).setEndLocationCoordinate(Coordinate.newInstance(30, 19)); + vehicleBuilder2_2.setType(vehicleType_solelypassenger); + Vehicle vehicle2_2 = vehicleBuilder2_2.build(); /* @@ -108,7 +120,7 @@ public class TransportOfDisabledPeople { Shipment shipment20 = Shipment.Builder.newInstance("wheelchair_10").addSizeDimension(WHEELCHAIRSPACE_INDEX, 1).setPickupCoord(Coordinate.newInstance(15, 20)).setDeliveryCoord(Coordinate.newInstance(14, 18)).build(); VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); - vrpBuilder.addVehicle(vehicle1).addVehicle(vehicle2); + vrpBuilder.addVehicle(vehicle1).addVehicle(vehicle2).addVehicle(vehicle1_2).addVehicle(vehicle2_2); vrpBuilder.addJob(shipment1).addJob(shipment2).addJob(shipment3).addJob(shipment4); vrpBuilder.addJob(shipment5).addJob(shipment6).addJob(shipment7).addJob(shipment8); vrpBuilder.addJob(shipment9).addJob(shipment10).addJob(shipment11).addJob(shipment12); @@ -137,35 +149,50 @@ public class TransportOfDisabledPeople { return true; } }; - - CrowFlyCosts crowFlyCosts = new CrowFlyCosts(vrpBuilder.getLocations()); - StateManager stateManager = new StateManager(crowFlyCosts); - - //add the constraint to the problem - vrpBuilder.addConstraint(wheelchair_bus_passenger_pickup_constraint); - vrpBuilder.addConstraint(new DellAmicoFixCostCalculator(vrpBuilder.getAddedJobs().size(), stateManager)); - vrpBuilder.addConstraint(new VariableTransportCostCalculator(crowFlyCosts)); - + SolutionCostCalculator objectiveFunction = new SolutionCostCalculator() { @Override public double getCosts(VehicleRoutingProblemSolution solution) { - // TODO Auto-generated method stub - return 0; + double maxTransportTime = 0.; + for(VehicleRoute route : solution.getRoutes()){ + if(route.getEnd().getArrTime() > maxTransportTime){ + maxTransportTime = route.getEnd().getArrTime(); + } + } + return maxTransportTime; } }; //build the problem VehicleRoutingProblem problem = vrpBuilder.build(); + StateManager stateManager = new StateManager(problem.getTransportCosts()); + + ConstraintManager constraintManager = new ConstraintManager(problem, stateManager); + constraintManager.addConstraint(wheelchair_bus_passenger_pickup_constraint); +// DellAmicoFixCostCalculator dellAmicoFixCostCalc = new DellAmicoFixCostCalculator(vrpBuilder.getAddedJobs().size(), stateManager); +// constraintManager.addConstraint(dellAmicoFixCostCalc); + constraintManager.addConstraint(new VariableTransportCostCalculator(problem.getTransportCosts())); + constraintManager.addConstraint(new SoftActivityConstraint() { + + @Override + public double getCosts(JobInsertionContext iFacts, TourActivity prevAct, + TourActivity newAct, TourActivity nextAct, double prevActDepTime) { + // TODO Auto-generated method stub + return 0; + } + }); + VehicleRoutingAlgorithmBuilder algorithmBuilder = new VehicleRoutingAlgorithmBuilder(problem, "input/algorithmConfig_noVehicleSwitch.xml"); algorithmBuilder.setObjectiveFunction(objectiveFunction); algorithmBuilder.setStateManager(stateManager); + algorithmBuilder.setConstraintManager(constraintManager); algorithmBuilder.addCoreConstraints(); - algorithmBuilder.addVariableCostCalculator(); - algorithmBuilder.addFixCostCalculator(); +// algorithmBuilder.addDefaultCostCalculators(); - VehicleRoutingAlgorithm vra = algorithmBuilder.build(); + VehicleRoutingAlgorithm algorithm = algorithmBuilder.build(); +// algorithm.addListener(dellAmicoFixCostCalc); /* * get a sample algorithm. * @@ -175,7 +202,7 @@ public class TransportOfDisabledPeople { * bit more complicated and you cannot just add the above hard-constraint. Latter will be covered in another example. * */ - VehicleRoutingAlgorithm algorithm = VehicleRoutingAlgorithms.readAndCreateAlgorithm(problem, "input/algorithmConfig_noVehicleSwitch.xml"); +// VehicleRoutingAlgorithm algorithm = VehicleRoutingAlgorithms.readAndCreateAlgorithm(problem, "input/algorithmConfig_noVehicleSwitch.xml"); algorithm.setPrematureAlgorithmTermination(new IterationWithoutImprovementTermination(100)); // algorithm.setNuOfIterations(30000); /* @@ -196,7 +223,7 @@ public class TransportOfDisabledPeople { /* * print nRoutes and totalCosts of bestSolution */ - SolutionPrinter.print(bestSolution); + SolutionPrinter.print(problem,bestSolution,Print.VERBOSE); /* * plot problem without solution