mirror of
https://github.com/graphhopper/jsprit.git
synced 2020-01-24 07:45:05 +01:00
Merge branch 'master' of https://github.com/graphhopper/jsprit
This commit is contained in:
commit
0a2840428a
18 changed files with 471 additions and 91 deletions
|
|
@ -14,6 +14,7 @@ import com.graphhopper.jsprit.core.algorithm.selector.SelectBest;
|
||||||
import com.graphhopper.jsprit.core.algorithm.state.StateManager;
|
import com.graphhopper.jsprit.core.algorithm.state.StateManager;
|
||||||
import com.graphhopper.jsprit.core.problem.VehicleRoutingProblem;
|
import com.graphhopper.jsprit.core.problem.VehicleRoutingProblem;
|
||||||
import com.graphhopper.jsprit.core.problem.constraint.ConstraintManager;
|
import com.graphhopper.jsprit.core.problem.constraint.ConstraintManager;
|
||||||
|
import com.graphhopper.jsprit.core.problem.job.Job;
|
||||||
import com.graphhopper.jsprit.core.problem.solution.SolutionCostCalculator;
|
import com.graphhopper.jsprit.core.problem.solution.SolutionCostCalculator;
|
||||||
import com.graphhopper.jsprit.core.problem.solution.VehicleRoutingProblemSolution;
|
import com.graphhopper.jsprit.core.problem.solution.VehicleRoutingProblemSolution;
|
||||||
import com.graphhopper.jsprit.core.problem.solution.route.VehicleRoute;
|
import com.graphhopper.jsprit.core.problem.solution.route.VehicleRoute;
|
||||||
|
|
@ -568,8 +569,7 @@ public class Jsprit {
|
||||||
}
|
}
|
||||||
|
|
||||||
private DefaultScorer getRegretScorer(VehicleRoutingProblem vrp) {
|
private DefaultScorer getRegretScorer(VehicleRoutingProblem vrp) {
|
||||||
DefaultScorer scorer;
|
DefaultScorer scorer = new DefaultScorer(vrp);
|
||||||
scorer = new DefaultScorer(vrp);
|
|
||||||
scorer.setTimeWindowParam(Double.valueOf(properties.getProperty(Parameter.REGRET_TIME_WINDOW_SCORER.toString())));
|
scorer.setTimeWindowParam(Double.valueOf(properties.getProperty(Parameter.REGRET_TIME_WINDOW_SCORER.toString())));
|
||||||
scorer.setDepotDistanceParam(Double.valueOf(properties.getProperty(Parameter.REGRET_DISTANCE_SCORER.toString())));
|
scorer.setDepotDistanceParam(Double.valueOf(properties.getProperty(Parameter.REGRET_DISTANCE_SCORER.toString())));
|
||||||
return scorer;
|
return scorer;
|
||||||
|
|
@ -638,14 +638,14 @@ public class Jsprit {
|
||||||
if (!hasBreak) {
|
if (!hasBreak) {
|
||||||
//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 += 4 * (maxCosts * 2 + route.getVehicle().getBreak().getServiceDuration() * route.getVehicle().getType().getVehicleCostParams().perServiceTimeUnit);
|
||||||
} else {
|
|
||||||
costs -= maxCosts * 2;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
costs += solution.getUnassignedJobs().size() * maxCosts * 2;
|
for(Job j : solution.getUnassignedJobs()){
|
||||||
|
costs += maxCosts * 2 * (4 - j.getPriority());
|
||||||
|
}
|
||||||
return costs;
|
return costs;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -23,10 +23,7 @@ import com.graphhopper.jsprit.core.util.NoiseMaker;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -65,6 +62,7 @@ public final class BestInsertion extends AbstractInsertionStrategy {
|
||||||
List<Job> badJobs = new ArrayList<Job>(unassignedJobs.size());
|
List<Job> badJobs = new ArrayList<Job>(unassignedJobs.size());
|
||||||
List<Job> unassignedJobList = new ArrayList<Job>(unassignedJobs);
|
List<Job> unassignedJobList = new ArrayList<Job>(unassignedJobs);
|
||||||
Collections.shuffle(unassignedJobList, random);
|
Collections.shuffle(unassignedJobList, random);
|
||||||
|
sometimesSortPriorities(unassignedJobList);
|
||||||
for (Job unassignedJob : unassignedJobList) {
|
for (Job unassignedJob : unassignedJobList) {
|
||||||
Insertion bestInsertion = null;
|
Insertion bestInsertion = null;
|
||||||
double bestInsertionCost = Double.MAX_VALUE;
|
double bestInsertionCost = Double.MAX_VALUE;
|
||||||
|
|
@ -93,4 +91,15 @@ public final class BestInsertion extends AbstractInsertionStrategy {
|
||||||
return badJobs;
|
return badJobs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void sometimesSortPriorities(List<Job> unassignedJobList) {
|
||||||
|
if(random.nextDouble() < 0.5){
|
||||||
|
Collections.sort(unassignedJobList, new Comparator<Job>() {
|
||||||
|
@Override
|
||||||
|
public int compare(Job o1, Job o2) {
|
||||||
|
return o1.getPriority() - o2.getPriority();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,10 +26,7 @@ import com.graphhopper.jsprit.core.problem.vehicle.Vehicle;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -101,6 +98,7 @@ public final class BestInsertionConcurrent extends AbstractInsertionStrategy {
|
||||||
List<Job> badJobs = new ArrayList<Job>(unassignedJobs.size());
|
List<Job> badJobs = new ArrayList<Job>(unassignedJobs.size());
|
||||||
List<Job> unassignedJobList = new ArrayList<Job>(unassignedJobs);
|
List<Job> unassignedJobList = new ArrayList<Job>(unassignedJobs);
|
||||||
Collections.shuffle(unassignedJobList, random);
|
Collections.shuffle(unassignedJobList, random);
|
||||||
|
sometimesSortPriorities(unassignedJobList);
|
||||||
List<Batch> batches = distributeRoutes(vehicleRoutes, nuOfBatches);
|
List<Batch> batches = distributeRoutes(vehicleRoutes, nuOfBatches);
|
||||||
for (final Job unassignedJob : unassignedJobList) {
|
for (final Job unassignedJob : unassignedJobList) {
|
||||||
Insertion bestInsertion = null;
|
Insertion bestInsertion = null;
|
||||||
|
|
@ -143,6 +141,17 @@ public final class BestInsertionConcurrent extends AbstractInsertionStrategy {
|
||||||
return badJobs;
|
return badJobs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void sometimesSortPriorities(List<Job> unassignedJobList) {
|
||||||
|
if(random.nextDouble() < 0.5){
|
||||||
|
Collections.sort(unassignedJobList, new Comparator<Job>() {
|
||||||
|
@Override
|
||||||
|
public int compare(Job o1, Job o2) {
|
||||||
|
return o1.getPriority() - o2.getPriority();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Insertion getBestInsertion(Batch batch, Job unassignedJob) {
|
private Insertion getBestInsertion(Batch batch, Job unassignedJob) {
|
||||||
Insertion bestInsertion = null;
|
Insertion bestInsertion = null;
|
||||||
double bestInsertionCost = Double.MAX_VALUE;
|
double bestInsertionCost = Double.MAX_VALUE;
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,9 @@ public class DefaultScorer implements ScoringFunction {
|
||||||
|
|
||||||
private VehicleRoutingProblem vrp;
|
private VehicleRoutingProblem vrp;
|
||||||
|
|
||||||
private double tw_param = -0.5;
|
private double timeWindowParam = -0.5;
|
||||||
|
|
||||||
private double depotDistance_param = +0.1;
|
private double depotDistanceParam = +0.1;
|
||||||
|
|
||||||
private double minTimeWindowScore = -100000;
|
private double minTimeWindowScore = -100000;
|
||||||
|
|
||||||
|
|
@ -24,11 +24,11 @@ public class DefaultScorer implements ScoringFunction {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTimeWindowParam(double tw_param) {
|
public void setTimeWindowParam(double tw_param) {
|
||||||
this.tw_param = tw_param;
|
this.timeWindowParam = tw_param;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDepotDistanceParam(double depotDistance_param) {
|
public void setDepotDistanceParam(double depotDistance_param) {
|
||||||
this.depotDistance_param = depotDistance_param;
|
this.depotDistanceParam = depotDistance_param;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -55,7 +55,7 @@ public class DefaultScorer implements ScoringFunction {
|
||||||
double maxDepotDistance = Math.max(maxDepotDistance_1, maxDepotDistance_2);
|
double maxDepotDistance = Math.max(maxDepotDistance_1, maxDepotDistance_2);
|
||||||
double minTimeToOperate = Math.min(shipment.getPickupTimeWindow().getEnd() - shipment.getPickupTimeWindow().getStart(),
|
double minTimeToOperate = Math.min(shipment.getPickupTimeWindow().getEnd() - shipment.getPickupTimeWindow().getStart(),
|
||||||
shipment.getDeliveryTimeWindow().getEnd() - shipment.getDeliveryTimeWindow().getStart());
|
shipment.getDeliveryTimeWindow().getEnd() - shipment.getDeliveryTimeWindow().getStart());
|
||||||
return Math.max(tw_param * minTimeToOperate, minTimeWindowScore) + depotDistance_param * maxDepotDistance;
|
return Math.max(timeWindowParam * minTimeToOperate, minTimeWindowScore) + depotDistanceParam * maxDepotDistance;
|
||||||
}
|
}
|
||||||
|
|
||||||
private double scoreService(InsertionData best, Job job) {
|
private double scoreService(InsertionData best, Job job) {
|
||||||
|
|
@ -67,8 +67,8 @@ public class DefaultScorer implements ScoringFunction {
|
||||||
getDistance(best.getSelectedVehicle().getEndLocation(), location)
|
getDistance(best.getSelectedVehicle().getEndLocation(), location)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return Math.max(tw_param * (((Service) job).getTimeWindow().getEnd() - ((Service) job).getTimeWindow().getStart()), minTimeWindowScore) +
|
return Math.max(timeWindowParam * (((Service) job).getTimeWindow().getEnd() - ((Service) job).getTimeWindow().getStart()), minTimeWindowScore) +
|
||||||
depotDistance_param * maxDepotDistance;
|
depotDistanceParam * maxDepotDistance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -78,6 +78,6 @@ public class DefaultScorer implements ScoringFunction {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "[name=defaultScorer][twParam=" + tw_param + "][depotDistanceParam=" + depotDistance_param + "]";
|
return "[name=defaultScorer][twParam=" + timeWindowParam + "][depotDistanceParam=" + depotDistanceParam + "]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -140,18 +140,7 @@ class InsertionDataUpdater {
|
||||||
}
|
}
|
||||||
|
|
||||||
static double score(Job unassignedJob, InsertionData best, InsertionData secondBest, ScoringFunction scoringFunction) {
|
static double score(Job unassignedJob, InsertionData best, InsertionData secondBest, ScoringFunction scoringFunction) {
|
||||||
if (best == null) {
|
return Scorer.score(unassignedJob,best,secondBest,scoringFunction);
|
||||||
throw new IllegalStateException("cannot insert job " + unassignedJob.getId());
|
|
||||||
}
|
|
||||||
double score;
|
|
||||||
if (secondBest == null) { //either there is only one vehicle or there are more vehicles, but they cannot load unassignedJob
|
|
||||||
//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
|
|
||||||
score = Integer.MAX_VALUE - best.getInsertionCost() + scoringFunction.score(best, unassignedJob);
|
|
||||||
} else {
|
|
||||||
score = (secondBest.getInsertionCost() - best.getInsertionCost()) + scoringFunction.score(best, unassignedJob);
|
|
||||||
}
|
|
||||||
return score;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -204,18 +204,7 @@ public class RegretInsertion extends AbstractInsertionStrategy {
|
||||||
|
|
||||||
|
|
||||||
static double score(Job unassignedJob, InsertionData best, InsertionData secondBest, ScoringFunction scoringFunction) {
|
static double score(Job unassignedJob, InsertionData best, InsertionData secondBest, ScoringFunction scoringFunction) {
|
||||||
if (best == null) {
|
return Scorer.score(unassignedJob,best,secondBest,scoringFunction);
|
||||||
throw new IllegalStateException("cannot insert job " + unassignedJob.getId());
|
|
||||||
}
|
|
||||||
double score;
|
|
||||||
if (secondBest == null) { //either there is only one vehicle or there are more vehicles, but they cannot load unassignedJob
|
|
||||||
//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
|
|
||||||
score = Integer.MAX_VALUE - best.getInsertionCost() + scoringFunction.score(best, unassignedJob);
|
|
||||||
} else {
|
|
||||||
score = (secondBest.getInsertionCost() - best.getInsertionCost()) + scoringFunction.score(best, unassignedJob);
|
|
||||||
}
|
|
||||||
return score;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
package com.graphhopper.jsprit.core.algorithm.recreate;
|
||||||
|
|
||||||
|
import com.graphhopper.jsprit.core.problem.job.Job;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by schroeder on 24/05/16.
|
||||||
|
*/
|
||||||
|
class Scorer {
|
||||||
|
|
||||||
|
static double score(Job unassignedJob, InsertionData best, InsertionData secondBest, ScoringFunction scoringFunction){
|
||||||
|
if (best == null) {
|
||||||
|
throw new IllegalStateException("cannot insert job " + unassignedJob.getId());
|
||||||
|
}
|
||||||
|
double score;
|
||||||
|
if (secondBest == null) { //either there is only one vehicle or there are more vehicles, but they cannot load unassignedJob
|
||||||
|
//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
|
||||||
|
score = (4 - unassignedJob.getPriority()) * (Integer.MAX_VALUE - best.getInsertionCost()) + scoringFunction.score(best, unassignedJob);
|
||||||
|
} else {
|
||||||
|
score = (4 - unassignedJob.getPriority()) * (secondBest.getInsertionCost() - best.getInsertionCost()) + scoringFunction.score(best, unassignedJob);
|
||||||
|
}
|
||||||
|
return score;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -51,4 +51,14 @@ public interface Job extends HasId, HasIndex {
|
||||||
* @return name
|
* @return name
|
||||||
*/
|
*/
|
||||||
public String getName();
|
public String getName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get priority of job. Only 1 = high priority, 2 = medium and 3 = low are allowed.
|
||||||
|
* <p>
|
||||||
|
* Default is 2 = medium.
|
||||||
|
*
|
||||||
|
* @return priority
|
||||||
|
*/
|
||||||
|
public int getPriority();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,6 @@ import java.util.Collection;
|
||||||
*/
|
*/
|
||||||
public class Service extends AbstractJob {
|
public class Service extends AbstractJob {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builder that builds a service.
|
* Builder that builds a service.
|
||||||
*
|
*
|
||||||
|
|
@ -48,6 +47,8 @@ public class Service extends AbstractJob {
|
||||||
public static class Builder<T extends Service> {
|
public static class Builder<T extends Service> {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a new instance of builder that builds a service.
|
* Returns a new instance of builder that builds a service.
|
||||||
*
|
*
|
||||||
|
|
@ -86,6 +87,8 @@ public class Service extends AbstractJob {
|
||||||
|
|
||||||
private boolean twAdded = false;
|
private boolean twAdded = false;
|
||||||
|
|
||||||
|
private int priority = 2;
|
||||||
|
|
||||||
Builder(String id){
|
Builder(String id){
|
||||||
this.id = id;
|
this.id = id;
|
||||||
timeWindows = new TimeWindowsImpl();
|
timeWindows = new TimeWindowsImpl();
|
||||||
|
|
@ -206,6 +209,20 @@ public class Service extends AbstractJob {
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set priority to service. Only 1 = high priority, 2 = medium and 3 = low are allowed.
|
||||||
|
* <p>
|
||||||
|
* Default is 2 = medium.
|
||||||
|
*
|
||||||
|
* @param priority
|
||||||
|
* @return builder
|
||||||
|
*/
|
||||||
|
public Builder<T> setPriority(int priority) {
|
||||||
|
if(priority < 1 || priority > 3) throw new IllegalStateException("incorrect priority. only 1 = high, 2 = medium and 3 = low is allowed");
|
||||||
|
this.priority = priority;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final String id;
|
private final String id;
|
||||||
|
|
@ -226,6 +243,8 @@ public class Service extends AbstractJob {
|
||||||
|
|
||||||
private final TimeWindows timeWindowManager;
|
private final TimeWindows timeWindowManager;
|
||||||
|
|
||||||
|
private final int priority;
|
||||||
|
|
||||||
Service(Builder builder) {
|
Service(Builder builder) {
|
||||||
id = builder.id;
|
id = builder.id;
|
||||||
serviceTime = builder.serviceTime;
|
serviceTime = builder.serviceTime;
|
||||||
|
|
@ -236,6 +255,7 @@ public class Service extends AbstractJob {
|
||||||
name = builder.name;
|
name = builder.name;
|
||||||
location = builder.location;
|
location = builder.location;
|
||||||
timeWindowManager = builder.timeWindows;
|
timeWindowManager = builder.timeWindows;
|
||||||
|
priority = builder.priority;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<TimeWindow> getTimeWindows(){
|
public Collection<TimeWindow> getTimeWindows(){
|
||||||
|
|
@ -338,4 +358,15 @@ public class Service extends AbstractJob {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get priority of service. Only 1 = high priority, 2 = medium and 3 = low are allowed.
|
||||||
|
* <p>
|
||||||
|
* Default is 2 = medium.
|
||||||
|
*
|
||||||
|
* @return priority
|
||||||
|
*/
|
||||||
|
public int getPriority() {
|
||||||
|
return priority;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,7 @@ public class Shipment extends AbstractJob {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builder that builds the shipment.
|
* Builder that builds the shipment.
|
||||||
*
|
*
|
||||||
|
|
@ -85,6 +86,8 @@ public class Shipment extends AbstractJob {
|
||||||
|
|
||||||
private TimeWindowsImpl pickupTimeWindows;
|
private TimeWindowsImpl pickupTimeWindows;
|
||||||
|
|
||||||
|
private int priority = 2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns new instance of this builder.
|
* Returns new instance of this builder.
|
||||||
*
|
*
|
||||||
|
|
@ -263,6 +266,20 @@ public class Shipment extends AbstractJob {
|
||||||
public Builder addPickupTimeWindow(double earliest, double latest) {
|
public Builder addPickupTimeWindow(double earliest, double latest) {
|
||||||
return addPickupTimeWindow(TimeWindow.newInstance(earliest, latest));
|
return addPickupTimeWindow(TimeWindow.newInstance(earliest, latest));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set priority to shipment. Only 1 = high priority, 2 = medium and 3 = low are allowed.
|
||||||
|
* <p>
|
||||||
|
* Default is 2 = medium.
|
||||||
|
*
|
||||||
|
* @param priority
|
||||||
|
* @return builder
|
||||||
|
*/
|
||||||
|
public Builder setPriority(int priority) {
|
||||||
|
if(priority < 1 || priority > 3) throw new IllegalStateException("incorrect priority. only 1 = high, 2 = medium and 3 = low is allowed");
|
||||||
|
this.priority = priority;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final String id;
|
private final String id;
|
||||||
|
|
@ -289,6 +306,8 @@ public class Shipment extends AbstractJob {
|
||||||
|
|
||||||
private final TimeWindowsImpl pickupTimeWindows;
|
private final TimeWindowsImpl pickupTimeWindows;
|
||||||
|
|
||||||
|
private final int priority;
|
||||||
|
|
||||||
Shipment(Builder builder) {
|
Shipment(Builder builder) {
|
||||||
this.id = builder.id;
|
this.id = builder.id;
|
||||||
this.pickupServiceTime = builder.pickupServiceTime;
|
this.pickupServiceTime = builder.pickupServiceTime;
|
||||||
|
|
@ -302,6 +321,7 @@ public class Shipment extends AbstractJob {
|
||||||
this.deliveryLocation_ = builder.deliveryLocation_;
|
this.deliveryLocation_ = builder.deliveryLocation_;
|
||||||
this.deliveryTimeWindows = builder.deliveryTimeWindows;
|
this.deliveryTimeWindows = builder.deliveryTimeWindows;
|
||||||
this.pickupTimeWindows = builder.pickupTimeWindows;
|
this.pickupTimeWindows = builder.pickupTimeWindows;
|
||||||
|
this.priority = builder.priority;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -409,5 +429,14 @@ public class Shipment extends AbstractJob {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get priority of shipment. Only 1 = high priority, 2 = medium and 3 = low are allowed.
|
||||||
|
* <p>
|
||||||
|
* Default is 2 = medium.
|
||||||
|
*
|
||||||
|
* @return priority
|
||||||
|
*/
|
||||||
|
public int getPriority() {
|
||||||
|
return priority;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ package com.graphhopper.jsprit.core.algorithm;
|
||||||
|
|
||||||
import com.graphhopper.jsprit.core.IntegrationTest;
|
import com.graphhopper.jsprit.core.IntegrationTest;
|
||||||
import com.graphhopper.jsprit.core.algorithm.box.GreedySchrimpfFactory;
|
import com.graphhopper.jsprit.core.algorithm.box.GreedySchrimpfFactory;
|
||||||
import com.graphhopper.jsprit.core.algorithm.termination.IterationWithoutImprovementTermination;
|
|
||||||
import com.graphhopper.jsprit.core.problem.Location;
|
import com.graphhopper.jsprit.core.problem.Location;
|
||||||
import com.graphhopper.jsprit.core.problem.VehicleRoutingProblem;
|
import com.graphhopper.jsprit.core.problem.VehicleRoutingProblem;
|
||||||
import com.graphhopper.jsprit.core.problem.job.Service;
|
import com.graphhopper.jsprit.core.problem.job.Service;
|
||||||
|
|
@ -143,7 +142,7 @@ public class RefuseCollectionWithCostsHigherThanTimesAndFiniteFleet_IT {
|
||||||
vrpBuilder.setRoutingCost(matrixBuilder.build());
|
vrpBuilder.setRoutingCost(matrixBuilder.build());
|
||||||
VehicleRoutingProblem vrp = vrpBuilder.build();
|
VehicleRoutingProblem vrp = vrpBuilder.build();
|
||||||
VehicleRoutingAlgorithm vra = new GreedySchrimpfFactory().createAlgorithm(vrp);
|
VehicleRoutingAlgorithm vra = new GreedySchrimpfFactory().createAlgorithm(vrp);
|
||||||
vra.setPrematureAlgorithmTermination(new IterationWithoutImprovementTermination(100));
|
// vra.setPrematureAlgorithmTermination(new IterationWithoutImprovementTermination(100));
|
||||||
Collection<VehicleRoutingProblemSolution> solutions = vra.searchSolutions();
|
Collection<VehicleRoutingProblemSolution> solutions = vra.searchSolutions();
|
||||||
|
|
||||||
SolutionPrinter.print(vrp, Solutions.bestOf(solutions), SolutionPrinter.Print.VERBOSE);
|
SolutionPrinter.print(vrp, Solutions.bestOf(solutions), SolutionPrinter.Print.VERBOSE);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
package com.graphhopper.jsprit.core.algorithm.recreate;
|
||||||
|
|
||||||
|
import com.graphhopper.jsprit.core.problem.Location;
|
||||||
|
import com.graphhopper.jsprit.core.problem.job.Job;
|
||||||
|
import com.graphhopper.jsprit.core.problem.job.Service;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by schroeder on 24/05/16.
|
||||||
|
*/
|
||||||
|
public class TestComparator {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test(){
|
||||||
|
Service s = Service.Builder.newInstance("1").setLocation(Location.newInstance("loc"))
|
||||||
|
.setPriority(1).build();
|
||||||
|
Service s2 = Service.Builder.newInstance("2").setLocation(Location.newInstance("loc"))
|
||||||
|
.setPriority(2).build();
|
||||||
|
Service s3 = Service.Builder.newInstance("3").setLocation(Location.newInstance("loc"))
|
||||||
|
.setPriority(3).build();
|
||||||
|
Service s4 = Service.Builder.newInstance("4").setLocation(Location.newInstance("loc"))
|
||||||
|
.setPriority(1).build();
|
||||||
|
List<Job> jobs = new ArrayList<Job>();
|
||||||
|
jobs.add(s2);
|
||||||
|
jobs.add(s3);
|
||||||
|
jobs.add(s4);
|
||||||
|
jobs.add(s);
|
||||||
|
Collections.sort(jobs, new Comparator<Job>() {
|
||||||
|
@Override
|
||||||
|
public int compare(Job o1, Job o2) {
|
||||||
|
return o1.getPriority() - o2.getPriority();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
for(Job j : jobs){
|
||||||
|
System.out.println(j.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
package com.graphhopper.jsprit.core.problem.job;
|
package com.graphhopper.jsprit.core.problem.job;
|
||||||
|
|
||||||
import com.graphhopper.jsprit.core.problem.Location;
|
import com.graphhopper.jsprit.core.problem.Location;
|
||||||
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
@ -30,7 +31,7 @@ public class DeliveryTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenAddingTwoCapDimension_nuOfDimsShouldBeTwo() {
|
public void whenAddingTwoCapDimension_nuOfDimsShouldBeTwo() {
|
||||||
Delivery one = (Delivery) Delivery.Builder.newInstance("s").setLocation(Location.newInstance("foofoo"))
|
Delivery one = Delivery.Builder.newInstance("s").setLocation(Location.newInstance("foofoo"))
|
||||||
.addSizeDimension(0, 2)
|
.addSizeDimension(0, 2)
|
||||||
.addSizeDimension(1, 4)
|
.addSizeDimension(1, 4)
|
||||||
.build();
|
.build();
|
||||||
|
|
@ -42,7 +43,7 @@ public class DeliveryTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenPickupIsBuiltWithoutSpecifyingCapacity_itShouldHvCapWithOneDimAndDimValOfZero() {
|
public void whenPickupIsBuiltWithoutSpecifyingCapacity_itShouldHvCapWithOneDimAndDimValOfZero() {
|
||||||
Delivery one = (Delivery) Delivery.Builder.newInstance("s").setLocation(Location.newInstance("foofoo"))
|
Delivery one = Delivery.Builder.newInstance("s").setLocation(Location.newInstance("foofoo"))
|
||||||
.build();
|
.build();
|
||||||
assertEquals(1, one.getSize().getNuOfDimensions());
|
assertEquals(1, one.getSize().getNuOfDimensions());
|
||||||
assertEquals(0, one.getSize().get(0));
|
assertEquals(0, one.getSize().get(0));
|
||||||
|
|
@ -50,7 +51,7 @@ public class DeliveryTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenPickupIsBuiltWithConstructorWhereSizeIsSpecified_capacityShouldBeSetCorrectly() {
|
public void whenPickupIsBuiltWithConstructorWhereSizeIsSpecified_capacityShouldBeSetCorrectly() {
|
||||||
Delivery one = (Delivery) Delivery.Builder.newInstance("s").addSizeDimension(0, 1).setLocation(Location.newInstance("foofoo"))
|
Delivery one = Delivery.Builder.newInstance("s").addSizeDimension(0, 1).setLocation(Location.newInstance("foofoo"))
|
||||||
.build();
|
.build();
|
||||||
assertEquals(1, one.getSize().getNuOfDimensions());
|
assertEquals(1, one.getSize().getNuOfDimensions());
|
||||||
assertEquals(1, one.getSize().get(0));
|
assertEquals(1, one.getSize().get(0));
|
||||||
|
|
@ -58,7 +59,7 @@ public class DeliveryTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenAddingSkills_theyShouldBeAddedCorrectly() {
|
public void whenAddingSkills_theyShouldBeAddedCorrectly() {
|
||||||
Delivery s = (Delivery) Delivery.Builder.newInstance("s").setLocation(Location.newInstance("loc"))
|
Delivery s = Delivery.Builder.newInstance("s").setLocation(Location.newInstance("loc"))
|
||||||
.addRequiredSkill("drill").addRequiredSkill("screwdriver").build();
|
.addRequiredSkill("drill").addRequiredSkill("screwdriver").build();
|
||||||
assertTrue(s.getRequiredSkills().containsSkill("drill"));
|
assertTrue(s.getRequiredSkills().containsSkill("drill"));
|
||||||
assertTrue(s.getRequiredSkills().containsSkill("ScrewDriver"));
|
assertTrue(s.getRequiredSkills().containsSkill("ScrewDriver"));
|
||||||
|
|
@ -66,7 +67,7 @@ public class DeliveryTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenAddingSkillsCaseSens_theyShouldBeAddedCorrectly() {
|
public void whenAddingSkillsCaseSens_theyShouldBeAddedCorrectly() {
|
||||||
Delivery s = (Delivery) Delivery.Builder.newInstance("s").setLocation(Location.newInstance("loc"))
|
Delivery s = Delivery.Builder.newInstance("s").setLocation(Location.newInstance("loc"))
|
||||||
.addRequiredSkill("DriLl").addRequiredSkill("screwDriver").build();
|
.addRequiredSkill("DriLl").addRequiredSkill("screwDriver").build();
|
||||||
assertTrue(s.getRequiredSkills().containsSkill("drill"));
|
assertTrue(s.getRequiredSkills().containsSkill("drill"));
|
||||||
assertTrue(s.getRequiredSkills().containsSkill("drilL"));
|
assertTrue(s.getRequiredSkills().containsSkill("drilL"));
|
||||||
|
|
@ -74,7 +75,7 @@ public class DeliveryTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenAddingSkillsCaseSensV2_theyShouldBeAddedCorrectly() {
|
public void whenAddingSkillsCaseSensV2_theyShouldBeAddedCorrectly() {
|
||||||
Delivery s = (Delivery) Delivery.Builder.newInstance("s").setLocation(Location.newInstance("loc"))
|
Delivery s = Delivery.Builder.newInstance("s").setLocation(Location.newInstance("loc"))
|
||||||
.addRequiredSkill("screwDriver").build();
|
.addRequiredSkill("screwDriver").build();
|
||||||
assertFalse(s.getRequiredSkills().containsSkill("drill"));
|
assertFalse(s.getRequiredSkills().containsSkill("drill"));
|
||||||
assertFalse(s.getRequiredSkills().containsSkill("drilL"));
|
assertFalse(s.getRequiredSkills().containsSkill("drilL"));
|
||||||
|
|
@ -82,10 +83,24 @@ public class DeliveryTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void nameShouldBeAssigned() {
|
public void nameShouldBeAssigned() {
|
||||||
Delivery s = (Delivery) Delivery.Builder.newInstance("s").setLocation(Location.newInstance("loc"))
|
Delivery s = Delivery.Builder.newInstance("s").setLocation(Location.newInstance("loc"))
|
||||||
.setName("name").build();
|
.setName("name").build();
|
||||||
assertEquals("name", s.getName());
|
assertEquals("name", s.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenSettingPriorities_itShouldBeSetCorrectly(){
|
||||||
|
Delivery s = Delivery.Builder.newInstance("s").setLocation(Location.newInstance("loc"))
|
||||||
|
.setPriority(3).build();
|
||||||
|
Assert.assertEquals(3, s.getPriority());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenNotSettingPriorities_defaultShouldBe(){
|
||||||
|
Delivery s = Delivery.Builder.newInstance("s").setLocation(Location.newInstance("loc"))
|
||||||
|
.build();
|
||||||
|
Assert.assertEquals(2, s.getPriority());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
package com.graphhopper.jsprit.core.problem.job;
|
package com.graphhopper.jsprit.core.problem.job;
|
||||||
|
|
||||||
import com.graphhopper.jsprit.core.problem.Location;
|
import com.graphhopper.jsprit.core.problem.Location;
|
||||||
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
@ -30,7 +31,7 @@ public class PickupTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenAddingTwoCapDimension_nuOfDimsShouldBeTwo() {
|
public void whenAddingTwoCapDimension_nuOfDimsShouldBeTwo() {
|
||||||
Pickup one = (Pickup) Pickup.Builder.newInstance("s").setLocation(Location.newInstance("foofoo"))
|
Pickup one = Pickup.Builder.newInstance("s").setLocation(Location.newInstance("foofoo"))
|
||||||
.addSizeDimension(0, 2)
|
.addSizeDimension(0, 2)
|
||||||
.addSizeDimension(1, 4)
|
.addSizeDimension(1, 4)
|
||||||
.build();
|
.build();
|
||||||
|
|
@ -42,7 +43,7 @@ public class PickupTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenPickupIsBuiltWithoutSpecifyingCapacity_itShouldHvCapWithOneDimAndDimValOfZero() {
|
public void whenPickupIsBuiltWithoutSpecifyingCapacity_itShouldHvCapWithOneDimAndDimValOfZero() {
|
||||||
Pickup one = (Pickup) Pickup.Builder.newInstance("s").setLocation(Location.newInstance("foofoo"))
|
Pickup one = Pickup.Builder.newInstance("s").setLocation(Location.newInstance("foofoo"))
|
||||||
.build();
|
.build();
|
||||||
assertEquals(1, one.getSize().getNuOfDimensions());
|
assertEquals(1, one.getSize().getNuOfDimensions());
|
||||||
assertEquals(0, one.getSize().get(0));
|
assertEquals(0, one.getSize().get(0));
|
||||||
|
|
@ -50,7 +51,7 @@ public class PickupTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenPickupIsBuiltWithConstructorWhereSizeIsSpecified_capacityShouldBeSetCorrectly() {
|
public void whenPickupIsBuiltWithConstructorWhereSizeIsSpecified_capacityShouldBeSetCorrectly() {
|
||||||
Pickup one = (Pickup) Pickup.Builder.newInstance("s").addSizeDimension(0, 1).setLocation(Location.newInstance("foofoo"))
|
Pickup one = Pickup.Builder.newInstance("s").addSizeDimension(0, 1).setLocation(Location.newInstance("foofoo"))
|
||||||
.build();
|
.build();
|
||||||
assertEquals(1, one.getSize().getNuOfDimensions());
|
assertEquals(1, one.getSize().getNuOfDimensions());
|
||||||
assertEquals(1, one.getSize().get(0));
|
assertEquals(1, one.getSize().get(0));
|
||||||
|
|
@ -58,7 +59,7 @@ public class PickupTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenAddingSkills_theyShouldBeAddedCorrectly() {
|
public void whenAddingSkills_theyShouldBeAddedCorrectly() {
|
||||||
Pickup s = (Pickup) Pickup.Builder.newInstance("s").setLocation(Location.newInstance("loc"))
|
Pickup s = Pickup.Builder.newInstance("s").setLocation(Location.newInstance("loc"))
|
||||||
.addRequiredSkill("drill").addRequiredSkill("screwdriver").build();
|
.addRequiredSkill("drill").addRequiredSkill("screwdriver").build();
|
||||||
assertTrue(s.getRequiredSkills().containsSkill("drill"));
|
assertTrue(s.getRequiredSkills().containsSkill("drill"));
|
||||||
assertTrue(s.getRequiredSkills().containsSkill("drill"));
|
assertTrue(s.getRequiredSkills().containsSkill("drill"));
|
||||||
|
|
@ -67,7 +68,7 @@ public class PickupTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenAddingSkillsCaseSens_theyShouldBeAddedCorrectly() {
|
public void whenAddingSkillsCaseSens_theyShouldBeAddedCorrectly() {
|
||||||
Pickup s = (Pickup) Pickup.Builder.newInstance("s").setLocation(Location.newInstance("loc"))
|
Pickup s = Pickup.Builder.newInstance("s").setLocation(Location.newInstance("loc"))
|
||||||
.addRequiredSkill("DriLl").addRequiredSkill("screwDriver").build();
|
.addRequiredSkill("DriLl").addRequiredSkill("screwDriver").build();
|
||||||
assertTrue(s.getRequiredSkills().containsSkill("drill"));
|
assertTrue(s.getRequiredSkills().containsSkill("drill"));
|
||||||
assertTrue(s.getRequiredSkills().containsSkill("drilL"));
|
assertTrue(s.getRequiredSkills().containsSkill("drilL"));
|
||||||
|
|
@ -75,7 +76,7 @@ public class PickupTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenAddingSkillsCaseSensV2_theyShouldBeAddedCorrectly() {
|
public void whenAddingSkillsCaseSensV2_theyShouldBeAddedCorrectly() {
|
||||||
Pickup s = (Pickup) Pickup.Builder.newInstance("s").setLocation(Location.newInstance("loc"))
|
Pickup s = Pickup.Builder.newInstance("s").setLocation(Location.newInstance("loc"))
|
||||||
.addRequiredSkill("screwDriver").build();
|
.addRequiredSkill("screwDriver").build();
|
||||||
assertFalse(s.getRequiredSkills().containsSkill("drill"));
|
assertFalse(s.getRequiredSkills().containsSkill("drill"));
|
||||||
assertFalse(s.getRequiredSkills().containsSkill("drilL"));
|
assertFalse(s.getRequiredSkills().containsSkill("drilL"));
|
||||||
|
|
@ -83,10 +84,24 @@ public class PickupTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void nameShouldBeAssigned() {
|
public void nameShouldBeAssigned() {
|
||||||
Pickup s = (Pickup) Pickup.Builder.newInstance("s").setLocation(Location.newInstance("loc"))
|
Pickup s = Pickup.Builder.newInstance("s").setLocation(Location.newInstance("loc"))
|
||||||
.setName("name").build();
|
.setName("name").build();
|
||||||
assertEquals("name", s.getName());
|
assertEquals("name", s.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenSettingPriorities_itShouldBeSetCorrectly(){
|
||||||
|
Pickup s = Pickup.Builder.newInstance("s").setLocation(Location.newInstance("loc"))
|
||||||
|
.setPriority(3).build();
|
||||||
|
Assert.assertEquals(3, s.getPriority());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenNotSettingPriorities_defaultShouldBe(){
|
||||||
|
Pickup s = Pickup.Builder.newInstance("s").setLocation(Location.newInstance("loc"))
|
||||||
|
.build();
|
||||||
|
Assert.assertEquals(2, s.getPriority());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ package com.graphhopper.jsprit.core.problem.job;
|
||||||
|
|
||||||
import com.graphhopper.jsprit.core.problem.Location;
|
import com.graphhopper.jsprit.core.problem.Location;
|
||||||
import com.graphhopper.jsprit.core.problem.solution.route.activity.TimeWindow;
|
import com.graphhopper.jsprit.core.problem.solution.route.activity.TimeWindow;
|
||||||
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
|
@ -234,4 +235,39 @@ public class ServiceTest {
|
||||||
.setName("name").build();
|
.setName("name").build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenSettingPriorities_itShouldBeSetCorrectly(){
|
||||||
|
Service s = Service.Builder.newInstance("s").setLocation(Location.newInstance("loc"))
|
||||||
|
.setPriority(1).build();
|
||||||
|
Assert.assertEquals(1, s.getPriority());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenSettingPriorities_itShouldBeSetCorrectly2(){
|
||||||
|
Service s = Service.Builder.newInstance("s").setLocation(Location.newInstance("loc"))
|
||||||
|
.setPriority(3).build();
|
||||||
|
Assert.assertEquals(3, s.getPriority());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenNotSettingPriorities_defaultShouldBe2(){
|
||||||
|
Service s = Service.Builder.newInstance("s").setLocation(Location.newInstance("loc"))
|
||||||
|
.build();
|
||||||
|
Assert.assertEquals(2, s.getPriority());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalStateException.class)
|
||||||
|
public void whenSettingIncorrectPriorities_itShouldThrowException(){
|
||||||
|
Service s = Service.Builder.newInstance("s").setLocation(Location.newInstance("loc"))
|
||||||
|
.setPriority(30).build();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalStateException.class)
|
||||||
|
public void whenSettingIncorrectPriorities_itShouldThrowException2(){
|
||||||
|
Service s = Service.Builder.newInstance("s").setLocation(Location.newInstance("loc"))
|
||||||
|
.setPriority(0).build();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import com.graphhopper.jsprit.core.problem.Location;
|
||||||
import com.graphhopper.jsprit.core.problem.solution.route.activity.TimeWindow;
|
import com.graphhopper.jsprit.core.problem.solution.route.activity.TimeWindow;
|
||||||
import com.graphhopper.jsprit.core.util.Coordinate;
|
import com.graphhopper.jsprit.core.util.Coordinate;
|
||||||
import com.graphhopper.jsprit.core.util.TestUtils;
|
import com.graphhopper.jsprit.core.util.TestUtils;
|
||||||
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import static org.hamcrest.core.Is.is;
|
import static org.hamcrest.core.Is.is;
|
||||||
|
|
@ -382,4 +383,45 @@ public class ShipmentTest {
|
||||||
assertEquals("del", s.getDeliveryLocation().getId());
|
assertEquals("del", s.getDeliveryLocation().getId());
|
||||||
assertEquals("del", s.getDeliveryLocation().getId());
|
assertEquals("del", s.getDeliveryLocation().getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenSettingPriorities_itShouldBeSetCorrectly(){
|
||||||
|
Shipment s = Shipment.Builder.newInstance("s").setPickupLocation(Location.newInstance("loc"))
|
||||||
|
.setDeliveryLocation(Location.newInstance("loc"))
|
||||||
|
.setPriority(1).build();
|
||||||
|
Assert.assertEquals(1, s.getPriority());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenSettingPriorities_itShouldBeSetCorrectly2(){
|
||||||
|
Shipment s = Shipment.Builder.newInstance("s").setPickupLocation(Location.newInstance("loc"))
|
||||||
|
.setDeliveryLocation(Location.newInstance("loc"))
|
||||||
|
.setPriority(3).build();
|
||||||
|
Assert.assertEquals(3, s.getPriority());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenNotSettingPriorities_defaultShouldBe2(){
|
||||||
|
Shipment s = Shipment.Builder.newInstance("s").setPickupLocation(Location.newInstance("loc"))
|
||||||
|
.setDeliveryLocation(Location.newInstance("loc"))
|
||||||
|
.build();
|
||||||
|
Assert.assertEquals(2, s.getPriority());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalStateException.class)
|
||||||
|
public void whenSettingIncorrectPriorities_itShouldThrowException(){
|
||||||
|
Shipment s = Shipment.Builder.newInstance("s").setPickupLocation(Location.newInstance("loc"))
|
||||||
|
.setDeliveryLocation(Location.newInstance("loc"))
|
||||||
|
.setPriority(30).build();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalStateException.class)
|
||||||
|
public void whenSettingIncorrectPriorities_itShouldThrowException2(){
|
||||||
|
Shipment s = Shipment.Builder.newInstance("s").setPickupLocation(Location.newInstance("loc"))
|
||||||
|
.setDeliveryLocation(Location.newInstance("loc"))
|
||||||
|
.setPriority(0).build();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
<problem xmlns="http://www.w3schools.com"
|
<problem xmlns="http://www.w3schools.com"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3schools.com vrp_xml_schema.xsd">
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3schools.com vrp_xml_schema.xsd">
|
||||||
<problemType>
|
<problemType>
|
||||||
<fleetSize>FINITE</fleetSize>
|
<fleetSize>INFINITE</fleetSize>
|
||||||
</problemType>
|
</problemType>
|
||||||
<vehicles>
|
<vehicles>
|
||||||
<vehicle>
|
<vehicle>
|
||||||
|
|
@ -20,21 +20,6 @@
|
||||||
</timeSchedule>
|
</timeSchedule>
|
||||||
<returnToDepot>true</returnToDepot>
|
<returnToDepot>true</returnToDepot>
|
||||||
</vehicle>
|
</vehicle>
|
||||||
<vehicle>
|
|
||||||
<id>v2</id>
|
|
||||||
<typeId>vehType2</typeId>
|
|
||||||
<startLocation>
|
|
||||||
<id>loc</id>
|
|
||||||
</startLocation>
|
|
||||||
<endLocation>
|
|
||||||
<id>loc</id>
|
|
||||||
</endLocation>
|
|
||||||
<timeSchedule>
|
|
||||||
<start>0.0</start>
|
|
||||||
<end>1.7976931348623157E308</end>
|
|
||||||
</timeSchedule>
|
|
||||||
<returnToDepot>true</returnToDepot>
|
|
||||||
</vehicle>
|
|
||||||
</vehicles>
|
</vehicles>
|
||||||
<vehicleTypes>
|
<vehicleTypes>
|
||||||
<type>
|
<type>
|
||||||
|
|
@ -48,16 +33,58 @@
|
||||||
<time>0.0</time>
|
<time>0.0</time>
|
||||||
</costs>
|
</costs>
|
||||||
</type>
|
</type>
|
||||||
<type>
|
|
||||||
<id>vehType2</id>
|
|
||||||
<capacity-dimensions>
|
|
||||||
<dimension index="0">200</dimension>
|
|
||||||
</capacity-dimensions>
|
|
||||||
<costs>
|
|
||||||
<fixed>0.0</fixed>
|
|
||||||
<distance>1.0</distance>
|
|
||||||
<time>0.0</time>
|
|
||||||
</costs>
|
|
||||||
</type>
|
|
||||||
</vehicleTypes>
|
</vehicleTypes>
|
||||||
|
<services>
|
||||||
|
<service id="1" type="service">
|
||||||
|
<location>
|
||||||
|
<id>loc</id>
|
||||||
|
</location>
|
||||||
|
<capacity-dimensions>
|
||||||
|
<dimension index="0">1</dimension>
|
||||||
|
</capacity-dimensions>
|
||||||
|
<duration>2.0</duration>
|
||||||
|
<timeWindows>
|
||||||
|
<timeWindow>
|
||||||
|
<start>0.0</start>
|
||||||
|
<end>1.7976931348623157E308</end>
|
||||||
|
</timeWindow>
|
||||||
|
</timeWindows>
|
||||||
|
</service>
|
||||||
|
<service id="2" type="service">
|
||||||
|
<location>
|
||||||
|
<id>loc2</id>
|
||||||
|
</location>
|
||||||
|
<capacity-dimensions>
|
||||||
|
<dimension index="0">1</dimension>
|
||||||
|
</capacity-dimensions>
|
||||||
|
<duration>4.0</duration>
|
||||||
|
<timeWindows>
|
||||||
|
<timeWindow>
|
||||||
|
<start>0.0</start>
|
||||||
|
<end>1.7976931348623157E308</end>
|
||||||
|
</timeWindow>
|
||||||
|
</timeWindows>
|
||||||
|
</service>
|
||||||
|
</services>
|
||||||
|
<solutions>
|
||||||
|
<solution>
|
||||||
|
<cost>10.0</cost>
|
||||||
|
<routes>
|
||||||
|
<route>
|
||||||
|
<driverId>noDriver</driverId>
|
||||||
|
<vehicleId>v1</vehicleId>
|
||||||
|
<start>0.0</start>
|
||||||
|
<act type="service">
|
||||||
|
<serviceId>1</serviceId>
|
||||||
|
<arrTime>0.0</arrTime>
|
||||||
|
<endTime>0.0</endTime>
|
||||||
|
</act>
|
||||||
|
<end>0.0</end>
|
||||||
|
</route>
|
||||||
|
</routes>
|
||||||
|
<unassignedJobs>
|
||||||
|
<job id="2"/>
|
||||||
|
</unassignedJobs>
|
||||||
|
</solution>
|
||||||
|
</solutions>
|
||||||
</problem>
|
</problem>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,112 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (C) 2014 Stefan Schroeder
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 3.0 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
******************************************************************************/
|
||||||
|
package com.graphhopper.jsprit.examples;
|
||||||
|
|
||||||
|
import com.graphhopper.jsprit.analysis.toolbox.GraphStreamViewer;
|
||||||
|
import com.graphhopper.jsprit.analysis.toolbox.GraphStreamViewer.Label;
|
||||||
|
import com.graphhopper.jsprit.core.algorithm.VehicleRoutingAlgorithm;
|
||||||
|
import com.graphhopper.jsprit.core.algorithm.box.Jsprit;
|
||||||
|
import com.graphhopper.jsprit.core.problem.Location;
|
||||||
|
import com.graphhopper.jsprit.core.problem.VehicleRoutingProblem;
|
||||||
|
import com.graphhopper.jsprit.core.problem.io.VrpXMLWriter;
|
||||||
|
import com.graphhopper.jsprit.core.problem.job.Service;
|
||||||
|
import com.graphhopper.jsprit.core.problem.solution.VehicleRoutingProblemSolution;
|
||||||
|
import com.graphhopper.jsprit.core.problem.vehicle.VehicleImpl;
|
||||||
|
import com.graphhopper.jsprit.core.problem.vehicle.VehicleImpl.Builder;
|
||||||
|
import com.graphhopper.jsprit.core.problem.vehicle.VehicleType;
|
||||||
|
import com.graphhopper.jsprit.core.problem.vehicle.VehicleTypeImpl;
|
||||||
|
import com.graphhopper.jsprit.core.reporting.SolutionPrinter;
|
||||||
|
import com.graphhopper.jsprit.core.util.Solutions;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
|
||||||
|
public class SimpleExampleWithPriorities {
|
||||||
|
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
/*
|
||||||
|
* some preparation - create output folder
|
||||||
|
*/
|
||||||
|
File dir = new File("output");
|
||||||
|
// if the directory does not exist, create it
|
||||||
|
if (!dir.exists()) {
|
||||||
|
System.out.println("creating directory ./output");
|
||||||
|
boolean result = dir.mkdir();
|
||||||
|
if (result) System.out.println("./output created");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* get a vehicle type-builder and build a type with the typeId "vehicleType" and one capacity dimension, i.e. weight, and capacity dimension value of 2
|
||||||
|
*/
|
||||||
|
final int WEIGHT_INDEX = 0;
|
||||||
|
VehicleTypeImpl.Builder vehicleTypeBuilder = VehicleTypeImpl.Builder.newInstance("vehicleType").addCapacityDimension(WEIGHT_INDEX, 2);
|
||||||
|
VehicleType vehicleType = vehicleTypeBuilder.build();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* get a vehicle-builder and build a vehicle located at (10,10) with type "vehicleType"
|
||||||
|
*/
|
||||||
|
Builder vehicleBuilder = Builder.newInstance("vehicle");
|
||||||
|
vehicleBuilder.setStartLocation(Location.newInstance(10, 10));
|
||||||
|
vehicleBuilder.setType(vehicleType);
|
||||||
|
VehicleImpl vehicle = vehicleBuilder.build();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* build services at the required locations, each with a capacity-demand of 1.
|
||||||
|
*/
|
||||||
|
Service service1 = Service.Builder.newInstance("1").setPriority(1).addSizeDimension(WEIGHT_INDEX, 1).setLocation(Location.newInstance(5, 7)).build();
|
||||||
|
Service service2 = Service.Builder.newInstance("2").addSizeDimension(WEIGHT_INDEX, 1).setLocation(Location.newInstance(5, 13)).build();
|
||||||
|
|
||||||
|
Service service3 = Service.Builder.newInstance("3").addSizeDimension(WEIGHT_INDEX, 1).setLocation(Location.newInstance(15, 7)).build();
|
||||||
|
Service service4 = Service.Builder.newInstance("4").setPriority(1).addSizeDimension(WEIGHT_INDEX, 1).setLocation(Location.newInstance(15, 13)).build();
|
||||||
|
|
||||||
|
|
||||||
|
VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
|
||||||
|
vrpBuilder.addVehicle(vehicle);
|
||||||
|
vrpBuilder.addJob(service1).addJob(service2).addJob(service3).addJob(service4).setFleetSize(VehicleRoutingProblem.FleetSize.FINITE);
|
||||||
|
|
||||||
|
VehicleRoutingProblem problem = vrpBuilder.build();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* get the algorithm out-of-the-box.
|
||||||
|
*/
|
||||||
|
VehicleRoutingAlgorithm algorithm = Jsprit.createAlgorithm(problem);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* and search a solution
|
||||||
|
*/
|
||||||
|
Collection<VehicleRoutingProblemSolution> solutions = algorithm.searchSolutions();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* get the best
|
||||||
|
*/
|
||||||
|
VehicleRoutingProblemSolution bestSolution = Solutions.bestOf(solutions);
|
||||||
|
|
||||||
|
new VrpXMLWriter(problem, solutions).write("output/problem-with-solution.xml");
|
||||||
|
|
||||||
|
SolutionPrinter.print(problem, bestSolution, SolutionPrinter.Print.VERBOSE);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* plot
|
||||||
|
*/
|
||||||
|
// SolutionPlotter.plotSolutionAsPNG(problem, bestSolution, "output/solution.png", "solution");
|
||||||
|
|
||||||
|
new GraphStreamViewer(problem, bestSolution).labelWith(Label.ID).setRenderDelay(200).display();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue