mirror of
https://github.com/graphhopper/jsprit.git
synced 2020-01-24 07:45:05 +01:00
reformat
This commit is contained in:
parent
5051b6960b
commit
966dc6e901
63 changed files with 1447 additions and 1466 deletions
|
|
@ -59,7 +59,7 @@ public class AlgorithmSearchProgressChartListener implements IterationEndsListen
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void informAlgorithmEnds(VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions) {
|
public void informAlgorithmEnds(VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions) {
|
||||||
log.info("create chart " + filename);
|
log.info("create chart {}", filename);
|
||||||
XYLineChartBuilder.saveChartAsPNG(chartBuilder.build(), filename);
|
XYLineChartBuilder.saveChartAsPNG(chartBuilder.build(), filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -416,8 +416,7 @@ public class ComputationalLaboratory {
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e){
|
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -283,7 +283,7 @@ public class Plotter {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void plot(VehicleRoutingProblem vrp, final Collection<VehicleRoute> routes, String pngFile, String title) {
|
private void plot(VehicleRoutingProblem vrp, final Collection<VehicleRoute> routes, String pngFile, String title) {
|
||||||
log.info("plot to " + pngFile);
|
log.info("plot to {}", pngFile);
|
||||||
XYSeriesCollection problem;
|
XYSeriesCollection problem;
|
||||||
XYSeriesCollection solution = null;
|
XYSeriesCollection solution = null;
|
||||||
final XYSeriesCollection shipments;
|
final XYSeriesCollection shipments;
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ public class StopWatch implements AlgorithmStartsListener, AlgorithmEndsListener
|
||||||
@Override
|
@Override
|
||||||
public void informAlgorithmEnds(VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions) {
|
public void informAlgorithmEnds(VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions) {
|
||||||
stop();
|
stop();
|
||||||
log.info("computation time [in sec]: " + getCompTimeInSeconds());
|
log.info("computation time [in sec]: {}", getCompTimeInSeconds());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stop() {
|
public void stop() {
|
||||||
|
|
|
||||||
|
|
@ -342,8 +342,7 @@ public class Jsprit {
|
||||||
noiseMaker.setRandom(random);
|
noiseMaker.setRandom(random);
|
||||||
constraintManager.addConstraint(noiseMaker);
|
constraintManager.addConstraint(noiseMaker);
|
||||||
noiseConfigurator = noiseMaker;
|
noiseConfigurator = noiseMaker;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
InsertionNoiseMaker noiseMaker = new InsertionNoiseMaker(vrp, maxCosts, noiseLevel, noiseProbability);
|
InsertionNoiseMaker noiseMaker = new InsertionNoiseMaker(vrp, maxCosts, noiseLevel, noiseProbability);
|
||||||
noiseMaker.setRandom(random);
|
noiseMaker.setRandom(random);
|
||||||
constraintManager.addConstraint(noiseMaker);
|
constraintManager.addConstraint(noiseMaker);
|
||||||
|
|
@ -594,8 +593,7 @@ public class Jsprit {
|
||||||
//break defined and required but not assigned penalty
|
//break defined and required but not assigned penalty
|
||||||
if (route.getEnd().getArrTime() > route.getVehicle().getBreak().getTimeWindow().getEnd()) {
|
if (route.getEnd().getArrTime() > route.getVehicle().getBreak().getTimeWindow().getEnd()) {
|
||||||
costs += maxCosts * 2 + route.getVehicle().getBreak().getServiceDuration() * route.getVehicle().getType().getVehicleCostParams().perServiceTimeUnit;
|
costs += maxCosts * 2 + route.getVehicle().getBreak().getServiceDuration() * route.getVehicle().getType().getVehicleCostParams().perServiceTimeUnit;
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
costs -= maxCosts * 2;
|
costs -= maxCosts * 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,6 @@ import java.util.List;
|
||||||
* Calculator that calculates the best insertion position for a {@link jsprit.core.problem.job.Service}.
|
* Calculator that calculates the best insertion position for a {@link jsprit.core.problem.job.Service}.
|
||||||
*
|
*
|
||||||
* @author schroeder
|
* @author schroeder
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
final class BreakInsertionCalculator implements JobInsertionCostsCalculator {
|
final class BreakInsertionCalculator implements JobInsertionCostsCalculator {
|
||||||
|
|
||||||
|
|
@ -89,7 +88,6 @@ final class BreakInsertionCalculator implements JobInsertionCostsCalculator{
|
||||||
/**
|
/**
|
||||||
* Calculates the marginal cost of inserting job i locally. This is based on the
|
* Calculates the marginal cost of inserting job i locally. This is based on the
|
||||||
* assumption that cost changes can entirely covered by only looking at the predecessor i-1 and its successor i+1.
|
* assumption that cost changes can entirely covered by only looking at the predecessor i-1 and its successor i+1.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public InsertionData getInsertionData(final VehicleRoute currentRoute, final Job jobToInsert, final Vehicle newVehicle, double newVehicleDepartureTime, final Driver newDriver, final double bestKnownCosts) {
|
public InsertionData getInsertionData(final VehicleRoute currentRoute, final Job jobToInsert, final Vehicle newVehicle, double newVehicleDepartureTime, final Driver newDriver, final double bestKnownCosts) {
|
||||||
|
|
@ -178,5 +176,4 @@ final class BreakInsertionCalculator implements JobInsertionCostsCalculator{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,8 +32,6 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class JobInsertionCostsCalculatorBuilder {
|
public class JobInsertionCostsCalculatorBuilder {
|
||||||
|
|
||||||
private static class CalculatorPlusListeners {
|
private static class CalculatorPlusListeners {
|
||||||
|
|
@ -97,7 +95,7 @@ public class JobInsertionCostsCalculatorBuilder {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs the builder.
|
* Constructs the builder.
|
||||||
*
|
* <p/>
|
||||||
* <p>Some calculators require information from the overall algorithm or the higher-level insertion procedure. Thus listeners inform them.
|
* <p>Some calculators require information from the overall algorithm or the higher-level insertion procedure. Thus listeners inform them.
|
||||||
* These listeners are cached in the according list and can thus be added when its time to add them.
|
* These listeners are cached in the according list and can thus be added when its time to add them.
|
||||||
*
|
*
|
||||||
|
|
@ -112,8 +110,8 @@ public class JobInsertionCostsCalculatorBuilder {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets activityStates. MUST be set.
|
* Sets activityStates. MUST be set.
|
||||||
* @param stateManager
|
|
||||||
*
|
*
|
||||||
|
* @param stateManager
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public JobInsertionCostsCalculatorBuilder setStateManager(RouteAndActivityStateGetter stateManager) {
|
public JobInsertionCostsCalculatorBuilder setStateManager(RouteAndActivityStateGetter stateManager) {
|
||||||
|
|
@ -145,8 +143,9 @@ public class JobInsertionCostsCalculatorBuilder {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets a flag to build a calculator based on local calculations.
|
* Sets a flag to build a calculator based on local calculations.
|
||||||
*
|
* <p/>
|
||||||
* <p>Insertion of a job and job-activity is evaluated based on the previous and next activity.
|
* <p>Insertion of a job and job-activity is evaluated based on the previous and next activity.
|
||||||
|
*
|
||||||
* @param addDefaultCostCalc
|
* @param addDefaultCostCalc
|
||||||
*/
|
*/
|
||||||
public JobInsertionCostsCalculatorBuilder setLocalLevel(boolean addDefaultCostCalc) {
|
public JobInsertionCostsCalculatorBuilder setLocalLevel(boolean addDefaultCostCalc) {
|
||||||
|
|
@ -200,15 +199,17 @@ public class JobInsertionCostsCalculatorBuilder {
|
||||||
* @throws IllegalStateException if vrp == null or activityStates == null or fleetManager == null.
|
* @throws IllegalStateException if vrp == null or activityStates == null or fleetManager == null.
|
||||||
*/
|
*/
|
||||||
public JobInsertionCostsCalculator build() {
|
public JobInsertionCostsCalculator build() {
|
||||||
if(vrp == null) throw new IllegalStateException("vehicle-routing-problem is null, but it must be set (this.setVehicleRoutingProblem(vrp))");
|
if (vrp == null)
|
||||||
if(states == null) throw new IllegalStateException("states is null, but is must be set (this.setStateManager(states))");
|
throw new IllegalStateException("vehicle-routing-problem is null, but it must be set (this.setVehicleRoutingProblem(vrp))");
|
||||||
if(fleetManager == null) throw new IllegalStateException("fleetManager is null, but it must be set (this.setVehicleFleetManager(fleetManager))");
|
if (states == null)
|
||||||
|
throw new IllegalStateException("states is null, but is must be set (this.setStateManager(states))");
|
||||||
|
if (fleetManager == null)
|
||||||
|
throw new IllegalStateException("fleetManager is null, but it must be set (this.setVehicleFleetManager(fleetManager))");
|
||||||
JobInsertionCostsCalculator baseCalculator = null;
|
JobInsertionCostsCalculator baseCalculator = null;
|
||||||
CalculatorPlusListeners standardLocal = null;
|
CalculatorPlusListeners standardLocal = null;
|
||||||
if (local) {
|
if (local) {
|
||||||
standardLocal = createStandardLocal(vrp, states);
|
standardLocal = createStandardLocal(vrp, states);
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
checkServicesOnly();
|
checkServicesOnly();
|
||||||
standardLocal = createStandardRoute(vrp, states, forwardLooking, memory);
|
standardLocal = createStandardRoute(vrp, states, forwardLooking, memory);
|
||||||
}
|
}
|
||||||
|
|
@ -263,8 +264,7 @@ public class JobInsertionCostsCalculatorBuilder {
|
||||||
if (activityInsertionCostCalculator == null && addDefaultCostCalc) {
|
if (activityInsertionCostCalculator == null && addDefaultCostCalc) {
|
||||||
actInsertionCalc = new LocalActivityInsertionCostsCalculator(vrp.getTransportCosts(), vrp.getActivityCosts(), statesManager);
|
actInsertionCalc = new LocalActivityInsertionCostsCalculator(vrp.getTransportCosts(), vrp.getActivityCosts(), statesManager);
|
||||||
configLocal = new ConfigureLocalActivityInsertionCalculator(vrp, (LocalActivityInsertionCostsCalculator) actInsertionCalc);
|
configLocal = new ConfigureLocalActivityInsertionCalculator(vrp, (LocalActivityInsertionCostsCalculator) actInsertionCalc);
|
||||||
}
|
} else if (activityInsertionCostCalculator == null && !addDefaultCostCalc) {
|
||||||
else if(activityInsertionCostCalculator == null && !addDefaultCostCalc){
|
|
||||||
actInsertionCalc = new ActivityInsertionCostsCalculator() {
|
actInsertionCalc = new ActivityInsertionCostsCalculator() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -274,8 +274,7 @@ public class JobInsertionCostsCalculatorBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
actInsertionCalc = activityInsertionCostCalculator;
|
actInsertionCalc = activityInsertionCostCalculator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -323,8 +322,7 @@ public class JobInsertionCostsCalculatorBuilder {
|
||||||
RouteLevelActivityInsertionCostsEstimator routeLevelActivityInsertionCostsEstimator = new RouteLevelActivityInsertionCostsEstimator(vrp.getTransportCosts(), vrp.getActivityCosts(), activityStates2);
|
RouteLevelActivityInsertionCostsEstimator routeLevelActivityInsertionCostsEstimator = new RouteLevelActivityInsertionCostsEstimator(vrp.getTransportCosts(), vrp.getActivityCosts(), activityStates2);
|
||||||
routeLevelActivityInsertionCostsEstimator.setForwardLooking(forwardLooking);
|
routeLevelActivityInsertionCostsEstimator.setForwardLooking(forwardLooking);
|
||||||
routeLevelCostEstimator = routeLevelActivityInsertionCostsEstimator;
|
routeLevelCostEstimator = routeLevelActivityInsertionCostsEstimator;
|
||||||
}
|
} else if (activityInsertionCostCalculator == null && !addDefaultCostCalc) {
|
||||||
else if(activityInsertionCostCalculator == null && !addDefaultCostCalc){
|
|
||||||
routeLevelCostEstimator = new ActivityInsertionCostsCalculator() {
|
routeLevelCostEstimator = new ActivityInsertionCostsCalculator() {
|
||||||
|
|
||||||
final ActivityInsertionCosts noInsertionCosts = new ActivityInsertionCosts(0., 0.);
|
final ActivityInsertionCosts noInsertionCosts = new ActivityInsertionCosts(0., 0.);
|
||||||
|
|
@ -336,8 +334,7 @@ public class JobInsertionCostsCalculatorBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
routeLevelCostEstimator = activityInsertionCostCalculator;
|
routeLevelCostEstimator = activityInsertionCostCalculator;
|
||||||
}
|
}
|
||||||
ServiceInsertionOnRouteLevelCalculator jobInsertionCalculator = new ServiceInsertionOnRouteLevelCalculator(vrp.getTransportCosts(), vrp.getActivityCosts(), routeLevelCostEstimator, constraintManager, constraintManager);
|
ServiceInsertionOnRouteLevelCalculator jobInsertionCalculator = new ServiceInsertionOnRouteLevelCalculator(vrp.getTransportCosts(), vrp.getActivityCosts(), routeLevelCostEstimator, constraintManager, constraintManager);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (C) 2014 Stefan Schroeder
|
* Copyright (C) 2014 Stefan Schroeder
|
||||||
*
|
*
|
||||||
|
|
@ -32,11 +31,10 @@ import jsprit.core.util.CalculationUtils;
|
||||||
* Calculates activity insertion costs locally, i.e. by comparing the additional costs of insertion the new activity k between
|
* Calculates activity insertion costs locally, i.e. by comparing the additional costs of insertion the new activity k between
|
||||||
* activity i (prevAct) and j (nextAct).
|
* activity i (prevAct) and j (nextAct).
|
||||||
* Additional costs are then basically calculated as delta c = c_ik + c_kj - c_ij.
|
* Additional costs are then basically calculated as delta c = c_ik + c_kj - c_ij.
|
||||||
*
|
* <p/>
|
||||||
* <p>Note once time has an effect on costs this class requires activity endTimes.
|
* <p>Note once time has an effect on costs this class requires activity endTimes.
|
||||||
*
|
*
|
||||||
* @author stefan
|
* @author stefan
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
class LocalActivityInsertionCostsCalculator implements ActivityInsertionCostsCalculator {
|
class LocalActivityInsertionCostsCalculator implements ActivityInsertionCostsCalculator {
|
||||||
|
|
||||||
|
|
@ -81,8 +79,7 @@ class LocalActivityInsertionCostsCalculator implements ActivityInsertionCostsCal
|
||||||
if (iFacts.getRoute().isEmpty()) {
|
if (iFacts.getRoute().isEmpty()) {
|
||||||
double tp_costs_prevAct_nextAct = routingCosts.getTransportCost(prevAct.getLocation(), nextAct.getLocation(), depTimeAtPrevAct, iFacts.getNewDriver(), iFacts.getNewVehicle());
|
double tp_costs_prevAct_nextAct = routingCosts.getTransportCost(prevAct.getLocation(), nextAct.getLocation(), depTimeAtPrevAct, iFacts.getNewDriver(), iFacts.getNewVehicle());
|
||||||
oldCosts += tp_costs_prevAct_nextAct;
|
oldCosts += tp_costs_prevAct_nextAct;
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
double tp_costs_prevAct_nextAct = routingCosts.getTransportCost(prevAct.getLocation(), nextAct.getLocation(), prevAct.getEndTime(), iFacts.getRoute().getDriver(), iFacts.getRoute().getVehicle());
|
double tp_costs_prevAct_nextAct = routingCosts.getTransportCost(prevAct.getLocation(), nextAct.getLocation(), prevAct.getEndTime(), iFacts.getRoute().getDriver(), iFacts.getRoute().getVehicle());
|
||||||
double arrTime_nextAct = depTimeAtPrevAct + routingCosts.getTransportTime(prevAct.getLocation(), nextAct.getLocation(), prevAct.getEndTime(), iFacts.getRoute().getDriver(), iFacts.getRoute().getVehicle());
|
double arrTime_nextAct = depTimeAtPrevAct + routingCosts.getTransportTime(prevAct.getLocation(), nextAct.getLocation(), prevAct.getEndTime(), iFacts.getRoute().getDriver(), iFacts.getRoute().getVehicle());
|
||||||
double endTime_nextAct_old = CalculationUtils.getActivityEndTime(arrTime_nextAct, nextAct);
|
double endTime_nextAct_old = CalculationUtils.getActivityEndTime(arrTime_nextAct, nextAct);
|
||||||
|
|
|
||||||
|
|
@ -32,14 +32,13 @@ import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insertion based on regret approach.
|
* Insertion based on regret approach.
|
||||||
*
|
* <p/>
|
||||||
* <p>Basically calculates the insertion cost of the firstBest and the secondBest alternative. The score is then calculated as difference
|
* <p>Basically calculates the insertion cost of the firstBest and the secondBest alternative. The score is then calculated as difference
|
||||||
* between secondBest and firstBest, plus additional scoring variables that can defined in this.ScoringFunction.
|
* between secondBest and firstBest, plus additional scoring variables that can defined in this.ScoringFunction.
|
||||||
* The idea is that if the cost of the secondBest alternative is way higher than the first best, it seems to be important to insert this
|
* The idea is that if the cost of the secondBest alternative is way higher than the first best, it seems to be important to insert this
|
||||||
* customer immediatedly. If difference is not that high, it might not impact solution if this customer is inserted later.
|
* customer immediatedly. If difference is not that high, it might not impact solution if this customer is inserted later.
|
||||||
*
|
*
|
||||||
* @author stefan schroeder
|
* @author stefan schroeder
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class RegretInsertion extends AbstractInsertionStrategy {
|
public class RegretInsertion extends AbstractInsertionStrategy {
|
||||||
|
|
||||||
|
|
@ -96,7 +95,6 @@ public class RegretInsertion extends AbstractInsertionStrategy {
|
||||||
* Scorer to include other impacts on score such as time-window length or distance to depot.
|
* Scorer to include other impacts on score such as time-window length or distance to depot.
|
||||||
*
|
*
|
||||||
* @author schroeder
|
* @author schroeder
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
static interface ScoringFunction {
|
static interface ScoringFunction {
|
||||||
|
|
||||||
|
|
@ -106,11 +104,10 @@ public class RegretInsertion extends AbstractInsertionStrategy {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scorer that includes the length of the time-window when scoring a job. The wider the time-window, the lower the score.
|
* Scorer that includes the length of the time-window when scoring a job. The wider the time-window, the lower the score.
|
||||||
*
|
* <p/>
|
||||||
* <p>This is the default scorer, i.e.: score = (secondBest - firstBest) + this.TimeWindowScorer.score(job)
|
* <p>This is the default scorer, i.e.: score = (secondBest - firstBest) + this.TimeWindowScorer.score(job)
|
||||||
*
|
*
|
||||||
* @author schroeder
|
* @author schroeder
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public static class DefaultScorer implements ScoringFunction {
|
public static class DefaultScorer implements ScoringFunction {
|
||||||
|
|
||||||
|
|
@ -126,20 +123,22 @@ public class RegretInsertion extends AbstractInsertionStrategy {
|
||||||
this.vrp = vrp;
|
this.vrp = vrp;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTimeWindowParam(double tw_param){ this.tw_param = tw_param; }
|
public void setTimeWindowParam(double tw_param) {
|
||||||
|
this.tw_param = tw_param;
|
||||||
|
}
|
||||||
|
|
||||||
public void setDepotDistanceParam(double depotDistance_param){ this.depotDistance_param = depotDistance_param; }
|
public void setDepotDistanceParam(double depotDistance_param) {
|
||||||
|
this.depotDistance_param = depotDistance_param;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double score(InsertionData best, Job job) {
|
public double score(InsertionData best, Job job) {
|
||||||
double score;
|
double score;
|
||||||
if (job instanceof Service) {
|
if (job instanceof Service) {
|
||||||
score = scoreService(best, job);
|
score = scoreService(best, job);
|
||||||
}
|
} else if (job instanceof Shipment) {
|
||||||
else if(job instanceof Shipment){
|
|
||||||
score = scoreShipment(best, job);
|
score = scoreShipment(best, job);
|
||||||
}
|
} else throw new IllegalStateException("not supported");
|
||||||
else throw new IllegalStateException("not supported");
|
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -193,7 +192,7 @@ public class RegretInsertion extends AbstractInsertionStrategy {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the scoring function.
|
* Sets the scoring function.
|
||||||
*
|
* <p/>
|
||||||
* <p>By default, the this.TimeWindowScorer is used.
|
* <p>By default, the this.TimeWindowScorer is used.
|
||||||
*
|
*
|
||||||
* @param scoringFunction to score
|
* @param scoringFunction to score
|
||||||
|
|
@ -218,9 +217,8 @@ public class RegretInsertion extends AbstractInsertionStrategy {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs insertion.
|
* Runs insertion.
|
||||||
*
|
* <p/>
|
||||||
* <p>Before inserting a job, all unassigned jobs are scored according to its best- and secondBest-insertion plus additional scoring variables.
|
* <p>Before inserting a job, all unassigned jobs are scored according to its best- and secondBest-insertion plus additional scoring variables.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Collection<Job> insertUnassignedJobs(Collection<VehicleRoute> routes, Collection<Job> unassignedJobs) {
|
public Collection<Job> insertUnassignedJobs(Collection<VehicleRoute> routes, Collection<Job> unassignedJobs) {
|
||||||
|
|
@ -258,8 +256,7 @@ public class RegretInsertion extends AbstractInsertionStrategy {
|
||||||
else {
|
else {
|
||||||
if (scoredJob.getScore() > bestScoredJob.getScore()) {
|
if (scoredJob.getScore() > bestScoredJob.getScore()) {
|
||||||
bestScoredJob = scoredJob;
|
bestScoredJob = scoredJob;
|
||||||
}
|
} else if (scoredJob.getScore() == bestScoredJob.getScore()) {
|
||||||
else if (scoredJob.getScore() == bestScoredJob.getScore()){
|
|
||||||
if (scoredJob.getJob().getId().compareTo(bestScoredJob.getJob().getId()) <= 0) {
|
if (scoredJob.getJob().getId().compareTo(bestScoredJob.getJob().getId()) <= 0) {
|
||||||
bestScoredJob = scoredJob;
|
bestScoredJob = scoredJob;
|
||||||
}
|
}
|
||||||
|
|
@ -314,8 +311,7 @@ public class RegretInsertion extends AbstractInsertionStrategy {
|
||||||
ScoredJob scoredJob;
|
ScoredJob scoredJob;
|
||||||
if (bestRoute == emptyRoute) {
|
if (bestRoute == emptyRoute) {
|
||||||
scoredJob = new ScoredJob(unassignedJob, score, best, bestRoute, true);
|
scoredJob = new ScoredJob(unassignedJob, score, best, bestRoute, true);
|
||||||
}
|
} else scoredJob = new ScoredJob(unassignedJob, score, best, bestRoute, false);
|
||||||
else scoredJob = new ScoredJob(unassignedJob, score, best, bestRoute, false);
|
|
||||||
return scoredJob;
|
return scoredJob;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -329,8 +325,7 @@ public class RegretInsertion extends AbstractInsertionStrategy {
|
||||||
//if only one vehicle, I want the job to be inserted with min iCosts
|
//if only one vehicle, I want the job to be inserted with min iCosts
|
||||||
//if there are more vehicles, I want this job to be prioritized since there are no alternatives
|
//if there are more vehicles, I want this job to be prioritized since there are no alternatives
|
||||||
score = Integer.MAX_VALUE - best.getInsertionCost() + scoringFunction.score(best, unassignedJob);
|
score = Integer.MAX_VALUE - best.getInsertionCost() + scoringFunction.score(best, unassignedJob);
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
score = (secondBest.getInsertionCost() - best.getInsertionCost()) + scoringFunction.score(best, unassignedJob);
|
score = (secondBest.getInsertionCost() - best.getInsertionCost()) + scoringFunction.score(best, unassignedJob);
|
||||||
}
|
}
|
||||||
return score;
|
return score;
|
||||||
|
|
|
||||||
|
|
@ -135,8 +135,7 @@ public class RegretInsertionConcurrent extends AbstractInsertionStrategy {
|
||||||
bestScoredJob = sJob;
|
bestScoredJob = sJob;
|
||||||
} else if (sJob.getScore() > bestScoredJob.getScore()) {
|
} else if (sJob.getScore() > bestScoredJob.getScore()) {
|
||||||
bestScoredJob = sJob;
|
bestScoredJob = sJob;
|
||||||
}
|
} else if (sJob.getScore() == bestScoredJob.getScore()) {
|
||||||
else if (sJob.getScore() == bestScoredJob.getScore()){
|
|
||||||
if (sJob.getJob().getId().compareTo(bestScoredJob.getJob().getId()) <= 0) {
|
if (sJob.getJob().getId().compareTo(bestScoredJob.getJob().getId()) <= 0) {
|
||||||
bestScoredJob = sJob;
|
bestScoredJob = sJob;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,8 @@ public class RuinBreaks implements RuinListener {
|
||||||
private final static Logger logger = LogManager.getLogger();
|
private final static Logger logger = LogManager.getLogger();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void ruinStarts(Collection<VehicleRoute> routes) {}
|
public void ruinStarts(Collection<VehicleRoute> routes) {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void ruinEnds(Collection<VehicleRoute> routes, Collection<Job> unassignedJobs) {
|
public void ruinEnds(Collection<VehicleRoute> routes, Collection<Job> unassignedJobs) {
|
||||||
|
|
@ -32,5 +33,6 @@ public class RuinBreaks implements RuinListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removed(Job job, VehicleRoute fromRoute) {}
|
public void removed(Job job, VehicleRoute fromRoute) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,6 @@ import jsprit.core.problem.solution.route.activity.TourActivity;
|
||||||
* Updates and memorizes latest operation start times at activities.
|
* Updates and memorizes latest operation start times at activities.
|
||||||
*
|
*
|
||||||
* @author schroeder
|
* @author schroeder
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class UpdateFutureWaitingTimes implements ReverseActivityVisitor, StateUpdater {
|
public class UpdateFutureWaitingTimes implements ReverseActivityVisitor, StateUpdater {
|
||||||
|
|
||||||
|
|
@ -58,5 +57,6 @@ public class UpdateFutureWaitingTimes implements ReverseActivityVisitor, StateUp
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void finish() {}
|
public void finish() {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,18 +42,15 @@ import java.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains and defines the vehicle routing problem.
|
* Contains and defines the vehicle routing problem.
|
||||||
*
|
* <p/>
|
||||||
* <p>A routing problem is defined as jobs, vehicles, costs and constraints.
|
* <p>A routing problem is defined as jobs, vehicles, costs and constraints.
|
||||||
*
|
* <p/>
|
||||||
* <p> To construct the problem, use VehicleRoutingProblem.Builder. Get an instance of this by using the static method VehicleRoutingProblem.Builder.newInstance().
|
* <p> To construct the problem, use VehicleRoutingProblem.Builder. Get an instance of this by using the static method VehicleRoutingProblem.Builder.newInstance().
|
||||||
*
|
* <p/>
|
||||||
* <p>By default, fleetSize is INFINITE, transport-costs are calculated as euclidean-distance (CrowFlyCosts),
|
* <p>By default, fleetSize is INFINITE, transport-costs are calculated as euclidean-distance (CrowFlyCosts),
|
||||||
* and activity-costs are set to zero.
|
* and activity-costs are set to zero.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
*
|
|
||||||
* @author stefan schroeder
|
* @author stefan schroeder
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class VehicleRoutingProblem {
|
public class VehicleRoutingProblem {
|
||||||
|
|
||||||
|
|
@ -61,18 +58,18 @@ public class VehicleRoutingProblem {
|
||||||
* Builder to build the routing-problem.
|
* Builder to build the routing-problem.
|
||||||
*
|
*
|
||||||
* @author stefan schroeder
|
* @author stefan schroeder
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a new instance of this builder.
|
* Returns a new instance of this builder.
|
||||||
*
|
*
|
||||||
* @return builder
|
* @return builder
|
||||||
*/
|
*/
|
||||||
public static Builder newInstance(){ return new Builder(); }
|
public static Builder newInstance() {
|
||||||
|
return new Builder();
|
||||||
|
}
|
||||||
|
|
||||||
private VehicleRoutingTransportCosts transportCosts;
|
private VehicleRoutingTransportCosts transportCosts;
|
||||||
|
|
||||||
|
|
@ -103,8 +100,7 @@ public class VehicleRoutingProblem {
|
||||||
List<AbstractActivity> acts = new ArrayList<AbstractActivity>();
|
List<AbstractActivity> acts = new ArrayList<AbstractActivity>();
|
||||||
if (job instanceof Service) {
|
if (job instanceof Service) {
|
||||||
acts.add(serviceActivityFactory.createActivity((Service) job));
|
acts.add(serviceActivityFactory.createActivity((Service) job));
|
||||||
}
|
} else if (job instanceof Shipment) {
|
||||||
else if(job instanceof Shipment){
|
|
||||||
acts.add(shipmentActivityFactory.createPickup((Shipment) job));
|
acts.add(shipmentActivityFactory.createPickup((Shipment) job));
|
||||||
acts.add(shipmentActivityFactory.createDelivery((Shipment) job));
|
acts.add(shipmentActivityFactory.createDelivery((Shipment) job));
|
||||||
}
|
}
|
||||||
|
|
@ -137,7 +133,9 @@ public class VehicleRoutingProblem {
|
||||||
activityIndexCounter++;
|
activityIndexCounter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void incVehicleTypeIdIndexCounter() { vehicleTypeIdIndexCounter++; }
|
private void incVehicleTypeIdIndexCounter() {
|
||||||
|
vehicleTypeIdIndexCounter++;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the unmodifiable map of collected locations (mapped by their location-id).
|
* Returns the unmodifiable map of collected locations (mapped by their location-id).
|
||||||
|
|
@ -150,12 +148,11 @@ public class VehicleRoutingProblem {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the locations collected SO FAR by this builder.
|
* Returns the locations collected SO FAR by this builder.
|
||||||
*
|
* <p/>
|
||||||
* <p>Locations are cached when adding a shipment, service, depot, vehicle.
|
* <p>Locations are cached when adding a shipment, service, depot, vehicle.
|
||||||
*
|
*
|
||||||
* @return locations
|
* @return locations
|
||||||
*
|
*/
|
||||||
**/
|
|
||||||
public Locations getLocations() {
|
public Locations getLocations() {
|
||||||
return new Locations() {
|
return new Locations() {
|
||||||
|
|
||||||
|
|
@ -182,7 +179,7 @@ public class VehicleRoutingProblem {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the type of fleetSize.
|
* Sets the type of fleetSize.
|
||||||
*
|
* <p/>
|
||||||
* <p>FleetSize is either FleetSize.INFINITE or FleetSize.FINITE. By default it is FleetSize.INFINITE.
|
* <p>FleetSize is either FleetSize.INFINITE or FleetSize.FINITE. By default it is FleetSize.INFINITE.
|
||||||
*
|
*
|
||||||
* @param fleetSize the fleet size used in this problem. it can either be FleetSize.INFINITE or FleetSize.FINITE
|
* @param fleetSize the fleet size used in this problem. it can either be FleetSize.INFINITE or FleetSize.FINITE
|
||||||
|
|
@ -195,7 +192,7 @@ public class VehicleRoutingProblem {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a job which is either a service or a shipment.
|
* Adds a job which is either a service or a shipment.
|
||||||
*
|
* <p/>
|
||||||
* <p>Note that job.getId() must be unique, i.e. no job (either it is a shipment or a service) is allowed to have an already allocated id.
|
* <p>Note that job.getId() must be unique, i.e. no job (either it is a shipment or a service) is allowed to have an already allocated id.
|
||||||
*
|
*
|
||||||
* @param job job to be added
|
* @param job job to be added
|
||||||
|
|
@ -211,7 +208,7 @@ public class VehicleRoutingProblem {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a job which is either a service or a shipment.
|
* Adds a job which is either a service or a shipment.
|
||||||
*
|
* <p/>
|
||||||
* <p>Note that job.getId() must be unique, i.e. no job (either it is a shipment or a service) is allowed to have an already allocated id.
|
* <p>Note that job.getId() must be unique, i.e. no job (either it is a shipment or a service) is allowed to have an already allocated id.
|
||||||
*
|
*
|
||||||
* @param job job to be added
|
* @param job job to be added
|
||||||
|
|
@ -219,8 +216,10 @@ public class VehicleRoutingProblem {
|
||||||
* @throws IllegalStateException if job is neither a shipment nor a service, or jobId has already been added.
|
* @throws IllegalStateException if job is neither a shipment nor a service, or jobId has already been added.
|
||||||
*/
|
*/
|
||||||
public Builder addJob(AbstractJob job) {
|
public Builder addJob(AbstractJob job) {
|
||||||
if(tentativeJobs.containsKey(job.getId())) throw new IllegalStateException("jobList already contains a job with id " + job.getId() + ". make sure you use unique ids for your jobs (i.e. service and shipments)");
|
if (tentativeJobs.containsKey(job.getId()))
|
||||||
if(!(job instanceof Service || job instanceof Shipment)) throw new IllegalStateException("job must be either a service or a shipment");
|
throw new IllegalStateException("jobList already contains a job with id " + job.getId() + ". make sure you use unique ids for your jobs (i.e. service and shipments)");
|
||||||
|
if (!(job instanceof Service || job instanceof Shipment))
|
||||||
|
throw new IllegalStateException("job must be either a service or a shipment");
|
||||||
job.setIndex(jobIndexCounter);
|
job.setIndex(jobIndexCounter);
|
||||||
incJobIndexCounter();
|
incJobIndexCounter();
|
||||||
tentativeJobs.put(job.getId(), job);
|
tentativeJobs.put(job.getId(), job);
|
||||||
|
|
@ -231,8 +230,7 @@ public class VehicleRoutingProblem {
|
||||||
private void addLocationToTentativeLocations(Job job) {
|
private void addLocationToTentativeLocations(Job job) {
|
||||||
if (job instanceof Service) {
|
if (job instanceof Service) {
|
||||||
tentative_coordinates.put(((Service) job).getLocation().getId(), ((Service) job).getLocation().getCoordinate());
|
tentative_coordinates.put(((Service) job).getLocation().getId(), ((Service) job).getLocation().getCoordinate());
|
||||||
}
|
} else if (job instanceof Shipment) {
|
||||||
else if(job instanceof Shipment){
|
|
||||||
Shipment shipment = (Shipment) job;
|
Shipment shipment = (Shipment) job;
|
||||||
tentative_coordinates.put(shipment.getPickupLocation().getId(), shipment.getPickupLocation().getCoordinate());
|
tentative_coordinates.put(shipment.getPickupLocation().getId(), shipment.getPickupLocation().getCoordinate());
|
||||||
tentative_coordinates.put(shipment.getDeliveryLocation().getId(), shipment.getDeliveryLocation().getCoordinate());
|
tentative_coordinates.put(shipment.getDeliveryLocation().getId(), shipment.getDeliveryLocation().getCoordinate());
|
||||||
|
|
@ -243,8 +241,7 @@ public class VehicleRoutingProblem {
|
||||||
if (job instanceof Service) {
|
if (job instanceof Service) {
|
||||||
Service service = (Service) job;
|
Service service = (Service) job;
|
||||||
addService(service);
|
addService(service);
|
||||||
}
|
} else if (job instanceof Shipment) {
|
||||||
else if(job instanceof Shipment){
|
|
||||||
Shipment shipment = (Shipment) job;
|
Shipment shipment = (Shipment) job;
|
||||||
addShipment(shipment);
|
addShipment(shipment);
|
||||||
}
|
}
|
||||||
|
|
@ -294,7 +291,8 @@ public class VehicleRoutingProblem {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void registerLocation(Job job) {
|
private void registerLocation(Job job) {
|
||||||
if (job instanceof Service) tentative_coordinates.put(((Service) job).getLocation().getId(), ((Service) job).getLocation().getCoordinate());
|
if (job instanceof Service)
|
||||||
|
tentative_coordinates.put(((Service) job).getLocation().getId(), ((Service) job).getLocation().getCoordinate());
|
||||||
if (job instanceof Shipment) {
|
if (job instanceof Shipment) {
|
||||||
Shipment shipment = (Shipment) job;
|
Shipment shipment = (Shipment) job;
|
||||||
tentative_coordinates.put(shipment.getPickupLocation().getId(), shipment.getPickupLocation().getCoordinate());
|
tentative_coordinates.put(shipment.getPickupLocation().getId(), shipment.getPickupLocation().getCoordinate());
|
||||||
|
|
@ -325,7 +323,9 @@ public class VehicleRoutingProblem {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addShipment(Shipment job) {
|
private void addShipment(Shipment job) {
|
||||||
if(jobs.containsKey(job.getId())){ logger.warn("job " + job + " already in job list. overrides existing job."); }
|
if (jobs.containsKey(job.getId())) {
|
||||||
|
logger.warn("job " + job + " already in job list. overrides existing job.");
|
||||||
|
}
|
||||||
tentative_coordinates.put(job.getPickupLocation().getId(), job.getPickupLocation().getCoordinate());
|
tentative_coordinates.put(job.getPickupLocation().getId(), job.getPickupLocation().getCoordinate());
|
||||||
tentative_coordinates.put(job.getDeliveryLocation().getId(), job.getDeliveryLocation().getCoordinate());
|
tentative_coordinates.put(job.getDeliveryLocation().getId(), job.getDeliveryLocation().getCoordinate());
|
||||||
jobs.put(job.getId(), job);
|
jobs.put(job.getId(), job);
|
||||||
|
|
@ -334,21 +334,20 @@ public class VehicleRoutingProblem {
|
||||||
/**
|
/**
|
||||||
* Adds a vehicle.
|
* Adds a vehicle.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
* @param vehicle vehicle to be added
|
* @param vehicle vehicle to be added
|
||||||
* @return this builder
|
* @return this builder
|
||||||
* @deprecated use addVehicle(AbstractVehicle vehicle) instead
|
* @deprecated use addVehicle(AbstractVehicle vehicle) instead
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public Builder addVehicle(Vehicle vehicle) {
|
public Builder addVehicle(Vehicle vehicle) {
|
||||||
if(!(vehicle instanceof AbstractVehicle)) throw new IllegalStateException("vehicle must be an AbstractVehicle");
|
if (!(vehicle instanceof AbstractVehicle))
|
||||||
|
throw new IllegalStateException("vehicle must be an AbstractVehicle");
|
||||||
return addVehicle((AbstractVehicle) vehicle);
|
return addVehicle((AbstractVehicle) vehicle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a vehicle.
|
* Adds a vehicle.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
* @param vehicle vehicle to be added
|
* @param vehicle vehicle to be added
|
||||||
* @return this builder
|
* @return this builder
|
||||||
*/
|
*/
|
||||||
|
|
@ -359,8 +358,7 @@ public class VehicleRoutingProblem {
|
||||||
}
|
}
|
||||||
if (typeKeyIndices.containsKey(vehicle.getVehicleTypeIdentifier())) {
|
if (typeKeyIndices.containsKey(vehicle.getVehicleTypeIdentifier())) {
|
||||||
vehicle.getVehicleTypeIdentifier().setIndex(typeKeyIndices.get(vehicle.getVehicleTypeIdentifier()));
|
vehicle.getVehicleTypeIdentifier().setIndex(typeKeyIndices.get(vehicle.getVehicleTypeIdentifier()));
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
vehicle.getVehicleTypeIdentifier().setIndex(vehicleTypeIdIndexCounter);
|
vehicle.getVehicleTypeIdentifier().setIndex(vehicleTypeIdIndexCounter);
|
||||||
typeKeyIndices.put(vehicle.getVehicleTypeIdentifier(), vehicleTypeIdIndexCounter);
|
typeKeyIndices.put(vehicle.getVehicleTypeIdentifier(), vehicleTypeIdIndexCounter);
|
||||||
incVehicleTypeIdIndexCounter();
|
incVehicleTypeIdIndexCounter();
|
||||||
|
|
@ -383,7 +381,7 @@ public class VehicleRoutingProblem {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the activity-costs.
|
* Sets the activity-costs.
|
||||||
*
|
* <p/>
|
||||||
* <p>By default it is set to zero.
|
* <p>By default it is set to zero.
|
||||||
*
|
*
|
||||||
* @param activityCosts activity costs of the problem
|
* @param activityCosts activity costs of the problem
|
||||||
|
|
@ -397,7 +395,7 @@ public class VehicleRoutingProblem {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds the {@link VehicleRoutingProblem}.
|
* Builds the {@link VehicleRoutingProblem}.
|
||||||
*
|
* <p/>
|
||||||
* <p>If {@link VehicleRoutingTransportCosts} are not set, {@link CrowFlyCosts} is used.
|
* <p>If {@link VehicleRoutingTransportCosts} are not set, {@link CrowFlyCosts} is used.
|
||||||
*
|
*
|
||||||
* @return {@link VehicleRoutingProblem}
|
* @return {@link VehicleRoutingProblem}
|
||||||
|
|
@ -412,7 +410,8 @@ public class VehicleRoutingProblem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
boolean hasBreaks = addBreaksToActivityMap();
|
boolean hasBreaks = addBreaksToActivityMap();
|
||||||
if(hasBreaks && fleetSize.equals(FleetSize.INFINITE)) throw new UnsupportedOperationException("breaks are not yet supported when dealing with infinite fleet. either set it to finite or omit breaks.");
|
if (hasBreaks && fleetSize.equals(FleetSize.INFINITE))
|
||||||
|
throw new UnsupportedOperationException("breaks are not yet supported when dealing with infinite fleet. either set it to finite or omit breaks.");
|
||||||
return new VehicleRoutingProblem(this);
|
return new VehicleRoutingProblem(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -479,7 +478,9 @@ public class VehicleRoutingProblem {
|
||||||
|
|
||||||
private Builder addService(Service service) {
|
private Builder addService(Service service) {
|
||||||
tentative_coordinates.put(service.getLocation().getId(), service.getLocation().getCoordinate());
|
tentative_coordinates.put(service.getLocation().getId(), service.getLocation().getCoordinate());
|
||||||
if(jobs.containsKey(service.getId())){ logger.warn("service " + service + " already in job list. overrides existing job."); }
|
if (jobs.containsKey(service.getId())) {
|
||||||
|
logger.warn("service " + service + " already in job list. overrides existing job.");
|
||||||
|
}
|
||||||
jobs.put(service.getId(), service);
|
jobs.put(service.getId(), service);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
@ -491,7 +492,6 @@ public class VehicleRoutingProblem {
|
||||||
* Enum that characterizes the fleet-size.
|
* Enum that characterizes the fleet-size.
|
||||||
*
|
*
|
||||||
* @author sschroeder
|
* @author sschroeder
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public static enum FleetSize {
|
public static enum FleetSize {
|
||||||
FINITE, INFINITE
|
FINITE, INFINITE
|
||||||
|
|
@ -572,7 +572,7 @@ public class VehicleRoutingProblem {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns type of fleetSize, either INFINITE or FINITE.
|
* Returns type of fleetSize, either INFINITE or FINITE.
|
||||||
*
|
* <p/>
|
||||||
* <p>By default, it is INFINITE.
|
* <p>By default, it is INFINITE.
|
||||||
*
|
*
|
||||||
* @return either FleetSize.INFINITE or FleetSize.FINITE
|
* @return either FleetSize.INFINITE or FleetSize.FINITE
|
||||||
|
|
@ -659,7 +659,9 @@ public class VehicleRoutingProblem {
|
||||||
/**
|
/**
|
||||||
* @return total number of activities
|
* @return total number of activities
|
||||||
*/
|
*/
|
||||||
public int getNuActivities(){ return nuActivities; }
|
public int getNuActivities() {
|
||||||
|
return nuActivities;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return factory that creates the activities associated to a job
|
* @return factory that creates the activities associated to a job
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@ import jsprit.core.problem.Skills;
|
||||||
* Pickup extends Service and is intended to model a Service where smth is LOADED (i.e. picked up) to a transport unit.
|
* Pickup extends Service and is intended to model a Service where smth is LOADED (i.e. picked up) to a transport unit.
|
||||||
*
|
*
|
||||||
* @author schroeder
|
* @author schroeder
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class Break extends Service {
|
public class Break extends Service {
|
||||||
|
|
||||||
|
|
@ -48,7 +47,7 @@ public class Break extends Service {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds Pickup.
|
* Builds Pickup.
|
||||||
*
|
* <p/>
|
||||||
* <p>Pickup type is "pickup"
|
* <p>Pickup type is "pickup"
|
||||||
*
|
*
|
||||||
* @return pickup
|
* @return pickup
|
||||||
|
|
|
||||||
|
|
@ -129,11 +129,9 @@ public class VehicleRoute {
|
||||||
List<AbstractActivity> acts = new ArrayList<AbstractActivity>();
|
List<AbstractActivity> acts = new ArrayList<AbstractActivity>();
|
||||||
if (job instanceof Break) {
|
if (job instanceof Break) {
|
||||||
acts.add(BreakActivity.newInstance((Break) job));
|
acts.add(BreakActivity.newInstance((Break) job));
|
||||||
}
|
} else if (job instanceof Service) {
|
||||||
else if(job instanceof Service){
|
|
||||||
acts.add(serviceActivityFactory.createActivity((Service) job));
|
acts.add(serviceActivityFactory.createActivity((Service) job));
|
||||||
}
|
} else if (job instanceof Shipment) {
|
||||||
else if(job instanceof Shipment){
|
|
||||||
acts.add(shipmentActivityFactory.createPickup((Shipment) job));
|
acts.add(shipmentActivityFactory.createPickup((Shipment) job));
|
||||||
acts.add(shipmentActivityFactory.createDelivery((Shipment) job));
|
acts.add(shipmentActivityFactory.createDelivery((Shipment) job));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -174,5 +174,4 @@ public class BreakActivity extends AbstractActivity implements JobActivity{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@ import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of {@link Vehicle}.
|
* Implementation of {@link Vehicle}.
|
||||||
*
|
*
|
||||||
|
|
@ -91,19 +90,20 @@ public class VehicleImpl extends AbstractVehicle {
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Break getBreak() { return null; }
|
public Break getBreak() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builder that builds the vehicle.
|
* Builder that builds the vehicle.
|
||||||
*
|
* <p/>
|
||||||
* <p>By default, earliestDepartureTime is 0.0, latestDepartureTime is Double.MAX_VALUE,
|
* <p>By default, earliestDepartureTime is 0.0, latestDepartureTime is Double.MAX_VALUE,
|
||||||
* it returns to the depot and its {@link VehicleType} is the DefaultType with typeId equal to 'default'
|
* it returns to the depot and its {@link VehicleType} is the DefaultType with typeId equal to 'default'
|
||||||
* and a capacity of 0.
|
* and a capacity of 0.
|
||||||
*
|
*
|
||||||
* @author stefan
|
* @author stefan
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
|
|
||||||
|
|
@ -138,8 +138,8 @@ public class VehicleImpl extends AbstractVehicle {
|
||||||
* Sets the {@link VehicleType}.<br>
|
* Sets the {@link VehicleType}.<br>
|
||||||
*
|
*
|
||||||
* @param type the type to be set
|
* @param type the type to be set
|
||||||
* @throws IllegalStateException if type is null
|
|
||||||
* @return this builder
|
* @return this builder
|
||||||
|
* @throws IllegalStateException if type is null
|
||||||
*/
|
*/
|
||||||
public Builder setType(VehicleType type) {
|
public Builder setType(VehicleType type) {
|
||||||
if (type == null) throw new IllegalStateException("type cannot be null.");
|
if (type == null) throw new IllegalStateException("type cannot be null.");
|
||||||
|
|
@ -149,11 +149,11 @@ public class VehicleImpl extends AbstractVehicle {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the flag whether the vehicle must return to depot or not.
|
* Sets the flag whether the vehicle must return to depot or not.
|
||||||
*
|
* <p/>
|
||||||
* <p>If returnToDepot is true, the vehicle must return to specified end-location. If you
|
* <p>If returnToDepot is true, the vehicle must return to specified end-location. If you
|
||||||
* omit specifying the end-location, vehicle returns to start-location (that must to be set). If
|
* omit specifying the end-location, vehicle returns to start-location (that must to be set). If
|
||||||
* you specify it, it returns to specified end-location.
|
* you specify it, it returns to specified end-location.
|
||||||
*
|
* <p/>
|
||||||
* <p>If returnToDepot is false, the end-location of the vehicle is endogenous.
|
* <p>If returnToDepot is false, the end-location of the vehicle is endogenous.
|
||||||
*
|
*
|
||||||
* @param returnToDepot true if vehicle need to return to depot, otherwise false
|
* @param returnToDepot true if vehicle need to return to depot, otherwise false
|
||||||
|
|
@ -187,7 +187,8 @@ public class VehicleImpl extends AbstractVehicle {
|
||||||
* @return this builder
|
* @return this builder
|
||||||
*/
|
*/
|
||||||
public Builder setEarliestStart(double earliest_startTime) {
|
public Builder setEarliestStart(double earliest_startTime) {
|
||||||
if(earliest_startTime < 0) throw new IllegalArgumentException("earliest start of vehicle " + id + " must not be negative");
|
if (earliest_startTime < 0)
|
||||||
|
throw new IllegalArgumentException("earliest start of vehicle " + id + " must not be negative");
|
||||||
this.earliestStart = earliest_startTime;
|
this.earliestStart = earliest_startTime;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
@ -199,7 +200,8 @@ public class VehicleImpl extends AbstractVehicle {
|
||||||
* @return this builder
|
* @return this builder
|
||||||
*/
|
*/
|
||||||
public Builder setLatestArrival(double latest_arrTime) {
|
public Builder setLatestArrival(double latest_arrTime) {
|
||||||
if(latest_arrTime < 0) throw new IllegalArgumentException("latest arrival time of vehicle " + id + " must not be negative");
|
if (latest_arrTime < 0)
|
||||||
|
throw new IllegalArgumentException("latest arrival time of vehicle " + id + " must not be negative");
|
||||||
this.latestArrival = latest_arrTime;
|
this.latestArrival = latest_arrTime;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
@ -226,7 +228,8 @@ public class VehicleImpl extends AbstractVehicle {
|
||||||
* or (endLocationId!=null AND returnToDepot=false)
|
* or (endLocationId!=null AND returnToDepot=false)
|
||||||
*/
|
*/
|
||||||
public VehicleImpl build() {
|
public VehicleImpl build() {
|
||||||
if(latestArrival < earliestStart) throw new IllegalStateException("latest arrival of vehicle " + id + " must not be smaller than its start time");
|
if (latestArrival < earliestStart)
|
||||||
|
throw new IllegalStateException("latest arrival of vehicle " + id + " must not be smaller than its start time");
|
||||||
if (startLocation != null && endLocation != null) {
|
if (startLocation != null && endLocation != null) {
|
||||||
if (!startLocation.getId().equals(endLocation.getId()) && !returnToDepot)
|
if (!startLocation.getId().equals(endLocation.getId()) && !returnToDepot)
|
||||||
throw new IllegalStateException("this must not be. you specified both endLocationId and open-routes. this is contradictory. <br>" +
|
throw new IllegalStateException("this must not be. you specified both endLocationId and open-routes. this is contradictory. <br>" +
|
||||||
|
|
@ -265,7 +268,7 @@ public class VehicleImpl extends AbstractVehicle {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns empty/noVehicle which is a vehicle having no capacity, no type and no reasonable id.
|
* Returns empty/noVehicle which is a vehicle having no capacity, no type and no reasonable id.
|
||||||
*
|
* <p/>
|
||||||
* <p>NoVehicle has id="noVehicle" and extends {@link VehicleImpl}
|
* <p>NoVehicle has id="noVehicle" and extends {@link VehicleImpl}
|
||||||
*
|
*
|
||||||
* @return emptyVehicle
|
* @return emptyVehicle
|
||||||
|
|
@ -308,7 +311,7 @@ public class VehicleImpl extends AbstractVehicle {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns String with attributes of this vehicle
|
* Returns String with attributes of this vehicle
|
||||||
*
|
* <p/>
|
||||||
* <p>String has the following format [attr1=val1][attr2=val2]...[attrn=valn]
|
* <p>String has the following format [attr1=val1][attr2=val2]...[attrn=valn]
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,6 @@ public class VehicleTypeImpl implements VehicleType {
|
||||||
public static class VehicleCostParams {
|
public static class VehicleCostParams {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static VehicleTypeImpl.VehicleCostParams newInstance(double fix, double perTimeUnit, double perDistanceUnit) {
|
public static VehicleTypeImpl.VehicleCostParams newInstance(double fix, double perTimeUnit, double perDistanceUnit) {
|
||||||
return new VehicleCostParams(fix, perTimeUnit, perDistanceUnit);
|
return new VehicleCostParams(fix, perTimeUnit, perDistanceUnit);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,6 @@ import static org.junit.Assert.*;
|
||||||
public class VehicleImplTest {
|
public class VehicleImplTest {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Test(expected = IllegalStateException.class)
|
@Test(expected = IllegalStateException.class)
|
||||||
public void whenVehicleIsBuiltWithoutSettingNeitherLocationNorCoord_itThrowsAnIllegalStateException() {
|
public void whenVehicleIsBuiltWithoutSettingNeitherLocationNorCoord_itThrowsAnIllegalStateException() {
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
|
|
@ -52,7 +51,6 @@ public class VehicleImplTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenAddingSkills_theyShouldBeAddedCorrectly() {
|
public void whenAddingSkills_theyShouldBeAddedCorrectly() {
|
||||||
VehicleTypeImpl type1 = VehicleTypeImpl.Builder.newInstance("type").build();
|
VehicleTypeImpl type1 = VehicleTypeImpl.Builder.newInstance("type").build();
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,6 @@ import java.util.Collection;
|
||||||
public class BreakExample {
|
public class BreakExample {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue