1
0
Fork 0
mirror of https://github.com/graphhopper/jsprit.git synced 2020-01-24 07:45:05 +01:00

full control over obj-func and insertion heuristic

This commit is contained in:
oblonski 2014-03-24 21:32:11 +01:00
parent 5399749cef
commit 959b467ac7
6 changed files with 248 additions and 96 deletions

View file

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

View file

@ -39,7 +39,7 @@ class InsertionFactory {
@SuppressWarnings("deprecation")
public static InsertionStrategy createInsertion(VehicleRoutingProblem vrp, HierarchicalConfiguration config,
VehicleFleetManager vehicleFleetManager, StateManager routeStates, List<PrioritizedVRAListener> algorithmListeners, ExecutorService executorService, int nuOfThreads, ConstraintManager constraintManager){
VehicleFleetManager vehicleFleetManager, StateManager routeStates, List<PrioritizedVRAListener> 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. <considerFixedCosts weight=1.0>true</considerFixedCosts>.\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. <considerFixedCosts weight=1.0>true</considerFixedCosts>.\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. <considerFixedCosts weight=1.0>true</considerFixedCosts> or \n<considerFixedCosts weight=1.0>false</considerFixedCosts>. " +
"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. <considerFixedCosts weight=1.0>true</considerFixedCosts> or \n<considerFixedCosts weight=1.0>false</considerFixedCosts>. " +
"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]");

View file

@ -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<InsertionListener> insertionListeners = new ArrayList<InsertionListener>();
//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<HierarchicalConfiguration> 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<PrioritizedVRAListener> algorithmListeners, TypedMap definedClasses, ExecutorService executorService, int nuOfThreads, ConstraintManager constraintManager) {
private static AlgorithmStartsListener createInitialSolution(XMLConfiguration config, final VehicleRoutingProblem vrp, VehicleFleetManager vehicleFleetManager, final StateManager routeStates, Set<PrioritizedVRAListener> algorithmListeners, TypedMap definedClasses, ExecutorService executorService, int nuOfThreads, ConstraintManager constraintManager, boolean addDefaultCostCalculators) {
List<HierarchicalConfiguration> 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<PrioritizedVRAListener> prioListeners = new ArrayList<PrioritizedVRAListener>();
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<VehicleRoutingProblemSolution> 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<PrioritizedVRAListener> algorithmListeners, TypedMap definedClasses, ExecutorService executorService, int nuOfThreads, ConstraintManager constraintManager) {
final StateManager routeStates, Set<PrioritizedVRAListener> 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<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, 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<PrioritizedVRAListener> 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<PrioritizedVRAListener> algorithmListeners, ExecutorService executorService, int nuOfThreads, ConstraintManager constraintManager, boolean addDefaultCostCalculators) {
InsertionStrategy insertion = InsertionFactory.createInsertion(vrp, moduleConfig, vehicleFleetManager, routeStates, algorithmListeners, executorService, nuOfThreads, constraintManager, addDefaultCostCalculators);
return insertion;
}

View file

@ -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<PrioritizedVRAListener> algorithmListeners = new ArrayList<PrioritizedVRAListener>();
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);

View file

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