mirror of
https://github.com/graphhopper/jsprit.git
synced 2020-01-24 07:45:05 +01:00
Merge branch 'master' into bicycle-messenger
Conflicts: jsprit-examples/src/main/java/jsprit/examples/BicycleMessenger.java
This commit is contained in:
commit
70ff6a83d7
24 changed files with 1904 additions and 212 deletions
|
|
@ -22,6 +22,7 @@ import java.util.List;
|
||||||
import jsprit.core.problem.cost.VehicleRoutingActivityCosts;
|
import jsprit.core.problem.cost.VehicleRoutingActivityCosts;
|
||||||
import jsprit.core.problem.cost.VehicleRoutingTransportCosts;
|
import jsprit.core.problem.cost.VehicleRoutingTransportCosts;
|
||||||
import jsprit.core.problem.driver.Driver;
|
import jsprit.core.problem.driver.Driver;
|
||||||
|
import jsprit.core.problem.solution.route.activity.End;
|
||||||
import jsprit.core.problem.solution.route.activity.TourActivity;
|
import jsprit.core.problem.solution.route.activity.TourActivity;
|
||||||
import jsprit.core.problem.vehicle.Vehicle;
|
import jsprit.core.problem.vehicle.Vehicle;
|
||||||
|
|
||||||
|
|
@ -33,10 +34,10 @@ final class AuxilliaryCostCalculator {
|
||||||
|
|
||||||
private final VehicleRoutingActivityCosts activityCosts;
|
private final VehicleRoutingActivityCosts activityCosts;
|
||||||
|
|
||||||
public AuxilliaryCostCalculator(final VehicleRoutingTransportCosts routingCosts, final VehicleRoutingActivityCosts costFunction) {
|
public AuxilliaryCostCalculator(final VehicleRoutingTransportCosts routingCosts, final VehicleRoutingActivityCosts actCosts) {
|
||||||
super();
|
super();
|
||||||
this.routingCosts = routingCosts;
|
this.routingCosts = routingCosts;
|
||||||
this.activityCosts = costFunction;
|
this.activityCosts = actCosts;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -59,6 +60,11 @@ final class AuxilliaryCostCalculator {
|
||||||
double departureTimePrevAct = depTime;
|
double departureTimePrevAct = depTime;
|
||||||
while(actIter.hasNext()){
|
while(actIter.hasNext()){
|
||||||
TourActivity act = actIter.next();
|
TourActivity act = actIter.next();
|
||||||
|
if(act instanceof End){
|
||||||
|
if(!vehicle.isReturnToDepot()){
|
||||||
|
return cost;
|
||||||
|
}
|
||||||
|
}
|
||||||
double transportCost = routingCosts.getTransportCost(prevAct.getLocationId(), act.getLocationId(), departureTimePrevAct, driver, vehicle);
|
double transportCost = routingCosts.getTransportCost(prevAct.getLocationId(), act.getLocationId(), departureTimePrevAct, driver, vehicle);
|
||||||
double transportTime = routingCosts.getTransportTime(prevAct.getLocationId(), act.getLocationId(), departureTimePrevAct, driver, vehicle);
|
double transportTime = routingCosts.getTransportTime(prevAct.getLocationId(), act.getLocationId(), departureTimePrevAct, driver, vehicle);
|
||||||
cost += transportCost;
|
cost += transportCost;
|
||||||
|
|
@ -72,37 +78,5 @@ final class AuxilliaryCostCalculator {
|
||||||
return cost;
|
return cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double costOfPath(String startLocationId, final double startTime, final List<TourActivity> path, String endLocationId, final Driver driver, final Vehicle vehicle){
|
|
||||||
if(path.isEmpty()){
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
double cost = 0.0;
|
|
||||||
// Iterator<TourActivity> actIter = path.iterator();
|
|
||||||
String prevActLocation = startLocationId;
|
|
||||||
// TourActivity prevAct = actIter.next();
|
|
||||||
double startCost = 0.0;
|
|
||||||
cost += startCost;
|
|
||||||
double departureTimePrevAct = startTime;
|
|
||||||
for(TourActivity act : path){
|
|
||||||
// TourActivity act = actIter.next();
|
|
||||||
double transportCost = routingCosts.getTransportCost(prevActLocation, act.getLocationId(), departureTimePrevAct, driver, vehicle);
|
|
||||||
double transportTime = routingCosts.getTransportTime(prevActLocation, act.getLocationId(), departureTimePrevAct, driver, vehicle);
|
|
||||||
cost += transportCost;
|
|
||||||
double actStartTime = departureTimePrevAct + transportTime;
|
|
||||||
double earliestOperationStartTime = Math.max(actStartTime, act.getTheoreticalEarliestOperationStartTime());
|
|
||||||
double actEndTime = earliestOperationStartTime + act.getOperationTime();
|
|
||||||
departureTimePrevAct = actEndTime;
|
|
||||||
cost += activityCosts.getActivityCost(act, actStartTime, driver, vehicle);
|
|
||||||
prevActLocation = act.getLocationId();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
*!!! ENDLOCATION
|
|
||||||
=> Start u. End können primitiv sein.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
return cost;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,6 @@ class Inserter {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setEndLocation(VehicleRoute route, Service service) {
|
private void setEndLocation(VehicleRoute route, Service service) {
|
||||||
route.getEnd().setCoordinate(service.getCoord());
|
|
||||||
route.getEnd().setLocationId(service.getLocationId());
|
route.getEnd().setLocationId(service.getLocationId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -106,7 +105,6 @@ class Inserter {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setEndLocation(VehicleRoute route, Shipment shipment) {
|
private void setEndLocation(VehicleRoute route, Shipment shipment) {
|
||||||
route.getEnd().setCoordinate(shipment.getDeliveryCoord());
|
|
||||||
route.getEnd().setLocationId(shipment.getDeliveryLocation());
|
route.getEnd().setLocationId(shipment.getDeliveryLocation());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,9 +25,7 @@ import java.util.Map;
|
||||||
import jsprit.core.problem.cost.VehicleRoutingActivityCosts;
|
import jsprit.core.problem.cost.VehicleRoutingActivityCosts;
|
||||||
import jsprit.core.problem.cost.VehicleRoutingTransportCosts;
|
import jsprit.core.problem.cost.VehicleRoutingTransportCosts;
|
||||||
import jsprit.core.problem.driver.Driver;
|
import jsprit.core.problem.driver.Driver;
|
||||||
import jsprit.core.problem.job.Delivery;
|
|
||||||
import jsprit.core.problem.job.Job;
|
import jsprit.core.problem.job.Job;
|
||||||
import jsprit.core.problem.job.Pickup;
|
|
||||||
import jsprit.core.problem.job.Service;
|
import jsprit.core.problem.job.Service;
|
||||||
import jsprit.core.problem.job.Shipment;
|
import jsprit.core.problem.job.Shipment;
|
||||||
import jsprit.core.problem.solution.route.activity.TourActivity;
|
import jsprit.core.problem.solution.route.activity.TourActivity;
|
||||||
|
|
@ -64,9 +62,11 @@ public class VehicleRoutingProblem {
|
||||||
*
|
*
|
||||||
* <p>DELIVERIES_FIRST corresponds to the vehicle routing problem with back hauls, i.e. before a vehicle is not entirely unloaded, no pickup can be made.
|
* <p>DELIVERIES_FIRST corresponds to the vehicle routing problem with back hauls, i.e. before a vehicle is not entirely unloaded, no pickup can be made.
|
||||||
*
|
*
|
||||||
|
* @deprecated define constraint directly - since constraints are too diverse to put them in an enum
|
||||||
* @author stefan
|
* @author stefan
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public enum Constraint {
|
public enum Constraint {
|
||||||
DELIVERIES_FIRST
|
DELIVERIES_FIRST
|
||||||
}
|
}
|
||||||
|
|
@ -186,12 +186,6 @@ public class VehicleRoutingProblem {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void addProblemConstraint(Constraint constraint){
|
|
||||||
if(!problemConstraints.contains(constraint)) problemConstraints.add(constraint);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets routing costs.
|
* Sets routing costs.
|
||||||
*
|
*
|
||||||
|
|
@ -218,39 +212,6 @@ public class VehicleRoutingProblem {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the fleetComposition.
|
|
||||||
*
|
|
||||||
* <p>FleetComposition is either FleetComposition.HETEROGENEOUS or FleetComposition.HOMOGENEOUS
|
|
||||||
*
|
|
||||||
* @deprecated has no effect
|
|
||||||
* @param fleetComposition
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public Builder setFleetComposition(FleetComposition fleetComposition){
|
|
||||||
this.fleetComposition = fleetComposition;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a service to jobList.
|
|
||||||
*
|
|
||||||
* <p>If jobList already contains service, a warning message is printed, and the existing job will be overwritten.
|
|
||||||
*
|
|
||||||
* @deprecated use addJob(...) instead
|
|
||||||
* @param service
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public Builder addService(Service service){
|
|
||||||
coordinates.put(service.getLocationId(), service.getCoord());
|
|
||||||
if(jobs.containsKey(service.getId())){ logger.warn("service " + service + " already in job list. overrides existing job."); }
|
|
||||||
jobs.put(service.getId(),service);
|
|
||||||
services.add(service);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a job which is either a service or a shipment.
|
* Adds a job which is either a service or a shipment.
|
||||||
*
|
*
|
||||||
|
|
@ -297,30 +258,6 @@ public class VehicleRoutingProblem {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a vehicleType.
|
|
||||||
*
|
|
||||||
* @deprecated use add vehicle instead
|
|
||||||
* @param type
|
|
||||||
* @return builder
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public Builder addVehicleType(VehicleType type){
|
|
||||||
vehicleTypes.add(type);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the neighborhood.
|
|
||||||
*
|
|
||||||
* @param neighborhood
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public Builder setNeighborhood(Neighborhood neighborhood){
|
|
||||||
this.neighborhood = neighborhood;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the activityCostFunction that considers also activities on a vehicle-route.
|
* Sets the activityCostFunction that considers also activities on a vehicle-route.
|
||||||
*
|
*
|
||||||
|
|
@ -391,8 +328,15 @@ public class VehicleRoutingProblem {
|
||||||
return Collections.unmodifiableCollection(vehicles);
|
return Collections.unmodifiableCollection(vehicles);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addConstraint(jsprit.core.problem.constraint.Constraint constraint){
|
/**
|
||||||
|
* Adds constraint to problem.
|
||||||
|
*
|
||||||
|
* @param constraint
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Builder addConstraint(jsprit.core.problem.constraint.Constraint constraint){
|
||||||
constraints.add(constraint);
|
constraints.add(constraint);
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -407,6 +351,75 @@ public class VehicleRoutingProblem {
|
||||||
public Collection<Job> getAddedJobs(){
|
public Collection<Job> getAddedJobs(){
|
||||||
return Collections.unmodifiableCollection(jobs.values());
|
return Collections.unmodifiableCollection(jobs.values());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the fleetComposition.
|
||||||
|
*
|
||||||
|
* <p>FleetComposition is either FleetComposition.HETEROGENEOUS or FleetComposition.HOMOGENEOUS
|
||||||
|
*
|
||||||
|
* @deprecated has no effect
|
||||||
|
* @param fleetComposition
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public Builder setFleetComposition(FleetComposition fleetComposition){
|
||||||
|
this.fleetComposition = fleetComposition;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a service to jobList.
|
||||||
|
*
|
||||||
|
* <p>If jobList already contains service, a warning message is printed, and the existing job will be overwritten.
|
||||||
|
*
|
||||||
|
* @deprecated use addJob(...) instead
|
||||||
|
* @param service
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public Builder addService(Service service){
|
||||||
|
coordinates.put(service.getLocationId(), service.getCoord());
|
||||||
|
if(jobs.containsKey(service.getId())){ logger.warn("service " + service + " already in job list. overrides existing job."); }
|
||||||
|
jobs.put(service.getId(),service);
|
||||||
|
services.add(service);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a vehicleType.
|
||||||
|
*
|
||||||
|
* @deprecated use add vehicle instead
|
||||||
|
* @param type
|
||||||
|
* @return builder
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public Builder addVehicleType(VehicleType type){
|
||||||
|
vehicleTypes.add(type);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the neighborhood.
|
||||||
|
*
|
||||||
|
* @deprecated use HardRoute- or ActivityLevelConstraint instead
|
||||||
|
* @param neighborhood
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public Builder setNeighborhood(Neighborhood neighborhood){
|
||||||
|
this.neighborhood = neighborhood;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @deprecated use .addConstraint(new ServiceDeliveriesFirstConstraint())
|
||||||
|
* @param constraint
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public void addProblemConstraint(Constraint constraint){
|
||||||
|
if(!problemConstraints.contains(constraint)) problemConstraints.add(constraint);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -485,13 +498,6 @@ public class VehicleRoutingProblem {
|
||||||
"transportCost="+transportCosts+"][activityCosts="+activityCosts+"]";
|
"transportCost="+transportCosts+"][activityCosts="+activityCosts+"]";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the neighborhood
|
|
||||||
*/
|
|
||||||
public Neighborhood getNeighborhood() {
|
|
||||||
return neighborhood;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns fleet-composition.
|
* Returns fleet-composition.
|
||||||
*
|
*
|
||||||
|
|
@ -521,15 +527,6 @@ public class VehicleRoutingProblem {
|
||||||
return Collections.unmodifiableMap(jobs);
|
return Collections.unmodifiableMap(jobs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns unmodifiable collection of problem-constraints.
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public Collection<Constraint> getProblemConstraints(){
|
|
||||||
return Collections.unmodifiableCollection(problemConstraints);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the entire, unmodifiable collection of types.
|
* Returns the entire, unmodifiable collection of types.
|
||||||
*
|
*
|
||||||
|
|
@ -568,9 +565,34 @@ public class VehicleRoutingProblem {
|
||||||
return activityCosts;
|
return activityCosts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an unmodifiable collection of constraints.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
public Collection<jsprit.core.problem.constraint.Constraint> getConstraints(){
|
public Collection<jsprit.core.problem.constraint.Constraint> getConstraints(){
|
||||||
return Collections.unmodifiableCollection(constraints);
|
return Collections.unmodifiableCollection(constraints);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated see builder.setNeighborhood(...). addConstraint(...) instead.
|
||||||
|
* @return the neighborhood
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public Neighborhood getNeighborhood() {
|
||||||
|
return neighborhood;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns unmodifiable collection of problem-constraints.
|
||||||
|
*
|
||||||
|
* @deprecated use .getConstraints() and builder.add
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public Collection<Constraint> getProblemConstraints(){
|
||||||
|
return Collections.unmodifiableCollection(problemConstraints);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
package jsprit.core.problem.constraint;
|
package jsprit.core.problem.constraint;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import org.apache.log4j.Logger;
|
import java.util.List;
|
||||||
|
|
||||||
import jsprit.core.problem.VehicleRoutingProblem;
|
import jsprit.core.problem.VehicleRoutingProblem;
|
||||||
import jsprit.core.problem.VehicleRoutingProblem.Constraint;
|
import jsprit.core.problem.VehicleRoutingProblem.Constraint;
|
||||||
|
|
@ -10,6 +11,8 @@ import jsprit.core.problem.misc.JobInsertionContext;
|
||||||
import jsprit.core.problem.solution.route.activity.TourActivity;
|
import jsprit.core.problem.solution.route.activity.TourActivity;
|
||||||
import jsprit.core.problem.solution.route.state.RouteAndActivityStateGetter;
|
import jsprit.core.problem.solution.route.state.RouteAndActivityStateGetter;
|
||||||
|
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
public class ConstraintManager implements HardActivityStateLevelConstraint, HardRouteStateLevelConstraint{
|
public class ConstraintManager implements HardActivityStateLevelConstraint, HardRouteStateLevelConstraint{
|
||||||
|
|
||||||
public static enum Priority {
|
public static enum Priority {
|
||||||
|
|
@ -96,4 +99,11 @@ public class ConstraintManager implements HardActivityStateLevelConstraint, Hard
|
||||||
return actLevelConstraintManager.fulfilled(iFacts, prevAct, newAct, nextAct, prevActDepTime);
|
return actLevelConstraintManager.fulfilled(iFacts, prevAct, newAct, nextAct, prevActDepTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Collection<jsprit.core.problem.constraint.Constraint> getConstraints(){
|
||||||
|
List<jsprit.core.problem.constraint.Constraint> constraints = new ArrayList<jsprit.core.problem.constraint.Constraint>();
|
||||||
|
constraints.addAll(actLevelConstraintManager.getAllConstraints());
|
||||||
|
constraints.addAll(routeLevelConstraintManager.getConstraints());
|
||||||
|
return Collections.unmodifiableCollection(constraints);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -2,6 +2,8 @@ package jsprit.core.problem.constraint;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import jsprit.core.problem.constraint.ConstraintManager.Priority;
|
import jsprit.core.problem.constraint.ConstraintManager.Priority;
|
||||||
import jsprit.core.problem.misc.JobInsertionContext;
|
import jsprit.core.problem.misc.JobInsertionContext;
|
||||||
|
|
@ -28,6 +30,20 @@ class HardActivityLevelConstraintManager implements HardActivityStateLevelConstr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Collection<HardActivityStateLevelConstraint> getCriticalConstraints(){ return Collections.unmodifiableCollection(criticalConstraints); }
|
||||||
|
|
||||||
|
Collection<HardActivityStateLevelConstraint> getHighPrioConstraints(){ return Collections.unmodifiableCollection(highPrioConstraints); }
|
||||||
|
|
||||||
|
Collection<HardActivityStateLevelConstraint> getLowPrioConstraints(){ return Collections.unmodifiableCollection(lowPrioConstraints); }
|
||||||
|
|
||||||
|
Collection<HardActivityStateLevelConstraint> getAllConstraints(){
|
||||||
|
List<HardActivityStateLevelConstraint> c = new ArrayList<HardActivityStateLevelConstraint>();
|
||||||
|
c.addAll(criticalConstraints);
|
||||||
|
c.addAll(highPrioConstraints);
|
||||||
|
c.addAll(lowPrioConstraints);
|
||||||
|
return Collections.unmodifiableCollection(c);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ConstraintsStatus fulfilled(JobInsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
|
public ConstraintsStatus fulfilled(JobInsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
|
||||||
ConstraintsStatus notFulfilled = null;
|
ConstraintsStatus notFulfilled = null;
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package jsprit.core.problem.constraint;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
import jsprit.core.problem.misc.JobInsertionContext;
|
import jsprit.core.problem.misc.JobInsertionContext;
|
||||||
|
|
||||||
|
|
@ -13,6 +14,8 @@ class HardRouteLevelConstraintManager implements HardRouteStateLevelConstraint {
|
||||||
public void addConstraint(HardRouteStateLevelConstraint constraint){
|
public void addConstraint(HardRouteStateLevelConstraint constraint){
|
||||||
hardConstraints.add(constraint);
|
hardConstraints.add(constraint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Collection<HardRouteStateLevelConstraint> getConstraints(){ return Collections.unmodifiableCollection(hardConstraints); }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean fulfilled(JobInsertionContext insertionContext) {
|
public boolean fulfilled(JobInsertionContext insertionContext) {
|
||||||
|
|
|
||||||
|
|
@ -35,11 +35,11 @@ public final class End implements TourActivity {
|
||||||
|
|
||||||
private Coordinate coordinate;
|
private Coordinate coordinate;
|
||||||
|
|
||||||
public Coordinate getCoordinate() {
|
Coordinate getCoordinate() {
|
||||||
return coordinate;
|
return coordinate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCoordinate(Coordinate coordinate) {
|
void setCoordinate(Coordinate coordinate) {
|
||||||
this.coordinate = coordinate;
|
this.coordinate = coordinate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -65,11 +65,11 @@ public final class Start implements TourActivity {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public Coordinate getCoordinate() {
|
Coordinate getCoordinate() {
|
||||||
return coordinate;
|
return coordinate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCoordinate(Coordinate coordinate) {
|
void setCoordinate(Coordinate coordinate) {
|
||||||
this.coordinate = coordinate;
|
this.coordinate = coordinate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,14 @@ public class VehicleImpl implements Vehicle {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* builds the vehicle.
|
||||||
|
*
|
||||||
|
* <p>by default, it returns to the depot.
|
||||||
|
*
|
||||||
|
* @author stefan
|
||||||
|
*
|
||||||
|
*/
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
static Logger log = Logger.getLogger(Builder.class);
|
static Logger log = Logger.getLogger(Builder.class);
|
||||||
private String id;
|
private String id;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,103 @@
|
||||||
|
package jsprit.core.algorithm.recreate;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import jsprit.core.problem.cost.VehicleRoutingActivityCosts;
|
||||||
|
import jsprit.core.problem.cost.VehicleRoutingTransportCosts;
|
||||||
|
import jsprit.core.problem.solution.route.activity.End;
|
||||||
|
import jsprit.core.problem.solution.route.activity.TourActivity;
|
||||||
|
import jsprit.core.problem.vehicle.Vehicle;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class TestAuxilliaryCostCalculator {
|
||||||
|
|
||||||
|
private VehicleRoutingTransportCosts routingCosts;
|
||||||
|
|
||||||
|
private VehicleRoutingActivityCosts actCosts;
|
||||||
|
|
||||||
|
private Vehicle vehicle;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void doBefore(){
|
||||||
|
vehicle = mock(Vehicle.class);
|
||||||
|
|
||||||
|
routingCosts = mock(VehicleRoutingTransportCosts.class);
|
||||||
|
actCosts = mock(VehicleRoutingActivityCosts.class);
|
||||||
|
|
||||||
|
when(routingCosts.getTransportCost("i", "j", 0.0, null, vehicle)).thenReturn(2.0);
|
||||||
|
when(routingCosts.getTransportTime("i", "j", 0.0, null, vehicle)).thenReturn(0.0);
|
||||||
|
when(routingCosts.getTransportCost("i", "k", 0.0, null, vehicle)).thenReturn(3.0);
|
||||||
|
when(routingCosts.getTransportTime("i", "k", 0.0, null, vehicle)).thenReturn(0.0);
|
||||||
|
when(routingCosts.getTransportCost("k", "j", 0.0, null, vehicle)).thenReturn(3.0);
|
||||||
|
when(routingCosts.getTransportTime("k", "j", 0.0, null, vehicle)).thenReturn(0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenRouteIsClosed_itCalculatesCostUpToEnd_v1(){
|
||||||
|
TourActivity prevAct = mock(TourActivity.class);
|
||||||
|
when(prevAct.getLocationId()).thenReturn("i");
|
||||||
|
TourActivity nextAct = mock(TourActivity.class);
|
||||||
|
when(nextAct.getLocationId()).thenReturn("j");
|
||||||
|
TourActivity newAct = mock(TourActivity.class);
|
||||||
|
when(newAct.getLocationId()).thenReturn("k");
|
||||||
|
|
||||||
|
when(vehicle.isReturnToDepot()).thenReturn(true);
|
||||||
|
|
||||||
|
AuxilliaryCostCalculator aCalc = new AuxilliaryCostCalculator(routingCosts, actCosts);
|
||||||
|
double costs = aCalc.costOfPath(Arrays.asList(prevAct,newAct,nextAct), 0.0, null, vehicle);
|
||||||
|
assertEquals(6.0,costs,0.01);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenRouteIsClosed_itCalculatesCostUpToEnd_v2(){
|
||||||
|
TourActivity prevAct = mock(TourActivity.class);
|
||||||
|
when(prevAct.getLocationId()).thenReturn("i");
|
||||||
|
End nextAct = End.newInstance("j", 0.0, 0.0);
|
||||||
|
TourActivity newAct = mock(TourActivity.class);
|
||||||
|
when(newAct.getLocationId()).thenReturn("k");
|
||||||
|
|
||||||
|
when(vehicle.isReturnToDepot()).thenReturn(true);
|
||||||
|
|
||||||
|
AuxilliaryCostCalculator aCalc = new AuxilliaryCostCalculator(routingCosts, actCosts);
|
||||||
|
double costs = aCalc.costOfPath(Arrays.asList(prevAct,newAct,nextAct), 0.0, null, vehicle);
|
||||||
|
assertEquals(6.0,costs,0.01);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenRouteIsOpen_itCalculatesCostUpToEnd_v1(){
|
||||||
|
TourActivity prevAct = mock(TourActivity.class);
|
||||||
|
when(prevAct.getLocationId()).thenReturn("i");
|
||||||
|
TourActivity nextAct = mock(TourActivity.class);
|
||||||
|
when(nextAct.getLocationId()).thenReturn("j");
|
||||||
|
TourActivity newAct = mock(TourActivity.class);
|
||||||
|
when(newAct.getLocationId()).thenReturn("k");
|
||||||
|
|
||||||
|
when(vehicle.isReturnToDepot()).thenReturn(false);
|
||||||
|
|
||||||
|
AuxilliaryCostCalculator aCalc = new AuxilliaryCostCalculator(routingCosts, actCosts);
|
||||||
|
double costs = aCalc.costOfPath(Arrays.asList(prevAct,newAct,nextAct), 0.0, null, vehicle);
|
||||||
|
assertEquals(6.0,costs,0.01);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenRouteIsOpen_itCalculatesCostUpToEnd_v2(){
|
||||||
|
TourActivity prevAct = mock(TourActivity.class);
|
||||||
|
when(prevAct.getLocationId()).thenReturn("i");
|
||||||
|
End nextAct = End.newInstance("j", 0.0, 0.0);
|
||||||
|
TourActivity newAct = mock(TourActivity.class);
|
||||||
|
when(newAct.getLocationId()).thenReturn("k");
|
||||||
|
|
||||||
|
when(vehicle.isReturnToDepot()).thenReturn(false);
|
||||||
|
|
||||||
|
AuxilliaryCostCalculator aCalc = new AuxilliaryCostCalculator(routingCosts, actCosts);
|
||||||
|
double costs = aCalc.costOfPath(Arrays.asList(prevAct,newAct,nextAct), 0.0, null, vehicle);
|
||||||
|
assertEquals(3.0,costs,0.01);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -267,9 +267,6 @@ public class TestCalculatesServiceInsertion {
|
||||||
assertEquals(2, iData.getDeliveryInsertionIndex());
|
assertEquals(2, iData.getDeliveryInsertionIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void whenInsertingAndRouteIsOpen(){
|
|
||||||
assertTrue(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -83,12 +83,14 @@ public class TestCalculatesServiceInsertionOnRouteLevel {
|
||||||
when(vehicle.getLocationId()).thenReturn("0,0");
|
when(vehicle.getLocationId()).thenReturn("0,0");
|
||||||
when(vehicle.getEarliestDeparture()).thenReturn(0.0);
|
when(vehicle.getEarliestDeparture()).thenReturn(0.0);
|
||||||
when(vehicle.getLatestArrival()).thenReturn(100.0);
|
when(vehicle.getLatestArrival()).thenReturn(100.0);
|
||||||
|
when(vehicle.isReturnToDepot()).thenReturn(true);
|
||||||
|
|
||||||
newVehicle = mock(Vehicle.class);
|
newVehicle = mock(Vehicle.class);
|
||||||
when(newVehicle.getCapacity()).thenReturn(1000);
|
when(newVehicle.getCapacity()).thenReturn(1000);
|
||||||
when(newVehicle.getLocationId()).thenReturn("0,0");
|
when(newVehicle.getLocationId()).thenReturn("0,0");
|
||||||
when(newVehicle.getEarliestDeparture()).thenReturn(0.0);
|
when(newVehicle.getEarliestDeparture()).thenReturn(0.0);
|
||||||
when(newVehicle.getLatestArrival()).thenReturn(100.0);
|
when(newVehicle.getLatestArrival()).thenReturn(100.0);
|
||||||
|
when(newVehicle.isReturnToDepot()).thenReturn(true);
|
||||||
|
|
||||||
driver = DriverImpl.noDriver();
|
driver = DriverImpl.noDriver();
|
||||||
|
|
||||||
|
|
@ -240,10 +242,5 @@ public class TestCalculatesServiceInsertionOnRouteLevel {
|
||||||
assertEquals(2, iData.getDeliveryInsertionIndex());
|
assertEquals(2, iData.getDeliveryInsertionIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void whenInsertingAndRouteIsOpen(){
|
|
||||||
assertTrue(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,122 @@
|
||||||
package jsprit.core.algorithm.recreate;
|
package jsprit.core.algorithm.recreate;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
import jsprit.core.algorithm.recreate.listener.InsertionListeners;
|
||||||
|
import jsprit.core.problem.driver.Driver;
|
||||||
|
import jsprit.core.problem.job.Service;
|
||||||
|
import jsprit.core.problem.job.Shipment;
|
||||||
|
import jsprit.core.problem.solution.route.VehicleRoute;
|
||||||
|
import jsprit.core.problem.vehicle.Vehicle;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
public class TestInserter {
|
public class TestInserter {
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenInsertingServiceAndRouteIsClosed_itInsertsCorrectly(){
|
||||||
|
Service service = mock(Service.class);
|
||||||
|
Vehicle vehicle = mock(Vehicle.class);
|
||||||
|
when(vehicle.getLocationId()).thenReturn("vehLoc");
|
||||||
|
when(vehicle.isReturnToDepot()).thenReturn(true);
|
||||||
|
when(vehicle.getId()).thenReturn("vehId");
|
||||||
|
|
||||||
|
VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, mock(Driver.class)).addService(service).build();
|
||||||
|
//start - pick(shipment) - del(shipment) - end
|
||||||
|
Service serviceToInsert = mock(Service.class);
|
||||||
|
when(serviceToInsert.getLocationId()).thenReturn("delLoc");
|
||||||
|
|
||||||
|
InsertionData iData = mock(InsertionData.class);
|
||||||
|
when(iData.getDeliveryInsertionIndex()).thenReturn(1);
|
||||||
|
when(iData.getSelectedVehicle()).thenReturn(vehicle);
|
||||||
|
|
||||||
|
Inserter inserter = new Inserter(mock(InsertionListeners.class));
|
||||||
|
inserter.insertJob(serviceToInsert, iData, route);
|
||||||
|
|
||||||
|
assertEquals(2,route.getTourActivities().getActivities().size());
|
||||||
|
assertEquals(route.getTourActivities().getActivities().get(1).getLocationId(),serviceToInsert.getLocationId());
|
||||||
|
assertEquals(route.getEnd().getLocationId(),vehicle.getLocationId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenInsertingServiceAndRouteIsOpen_itInsertsCorrectlyAndSwitchesEndLocation(){
|
||||||
|
Service service = mock(Service.class);
|
||||||
|
Vehicle vehicle = mock(Vehicle.class);
|
||||||
|
when(vehicle.getLocationId()).thenReturn("vehLoc");
|
||||||
|
when(vehicle.isReturnToDepot()).thenReturn(false);
|
||||||
|
when(vehicle.getId()).thenReturn("vehId");
|
||||||
|
|
||||||
|
VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, mock(Driver.class)).addService(service).build();
|
||||||
|
Service serviceToInsert = mock(Service.class);
|
||||||
|
when(serviceToInsert.getLocationId()).thenReturn("delLoc");
|
||||||
|
|
||||||
|
InsertionData iData = mock(InsertionData.class);
|
||||||
|
when(iData.getDeliveryInsertionIndex()).thenReturn(1);
|
||||||
|
when(iData.getSelectedVehicle()).thenReturn(vehicle);
|
||||||
|
|
||||||
|
Inserter inserter = new Inserter(mock(InsertionListeners.class));
|
||||||
|
inserter.insertJob(serviceToInsert, iData, route);
|
||||||
|
|
||||||
|
assertEquals(2,route.getTourActivities().getActivities().size());
|
||||||
|
assertEquals(route.getTourActivities().getActivities().get(1).getLocationId(),serviceToInsert.getLocationId());
|
||||||
|
assertEquals(route.getEnd().getLocationId(),serviceToInsert.getLocationId());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenInsertingShipmentAndRouteIsClosed_itInsertsCorrectly(){
|
||||||
|
Shipment shipment = mock(Shipment.class);
|
||||||
|
Vehicle vehicle = mock(Vehicle.class);
|
||||||
|
when(vehicle.getLocationId()).thenReturn("vehLoc");
|
||||||
|
when(vehicle.isReturnToDepot()).thenReturn(true);
|
||||||
|
when(vehicle.getId()).thenReturn("vehId");
|
||||||
|
|
||||||
|
VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, mock(Driver.class)).addPickup(shipment).addDelivery(shipment).build();
|
||||||
|
//start - pick(shipment) - del(shipment) - end
|
||||||
|
Shipment shipmentToInsert = mock(Shipment.class);
|
||||||
|
when(shipmentToInsert.getDeliveryLocation()).thenReturn("delLoc");
|
||||||
|
when(shipmentToInsert.getPickupLocation()).thenReturn("pickLoc");
|
||||||
|
InsertionData iData = mock(InsertionData.class);
|
||||||
|
when(iData.getPickupInsertionIndex()).thenReturn(2);
|
||||||
|
when(iData.getDeliveryInsertionIndex()).thenReturn(2);
|
||||||
|
when(iData.getSelectedVehicle()).thenReturn(vehicle);
|
||||||
|
|
||||||
|
Inserter inserter = new Inserter(mock(InsertionListeners.class));
|
||||||
|
inserter.insertJob(shipmentToInsert, iData, route);
|
||||||
|
|
||||||
|
assertEquals(4,route.getTourActivities().getActivities().size());
|
||||||
|
assertEquals(route.getTourActivities().getActivities().get(2).getLocationId(),shipmentToInsert.getPickupLocation());
|
||||||
|
assertEquals(route.getTourActivities().getActivities().get(3).getLocationId(),shipmentToInsert.getDeliveryLocation());
|
||||||
|
assertEquals(route.getEnd().getLocationId(),vehicle.getLocationId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenInsertingShipmentAndRouteIsOpen_itInsertsCorrectlyAndSwitchesEndLocation(){
|
||||||
|
Shipment shipment = mock(Shipment.class);
|
||||||
|
Vehicle vehicle = mock(Vehicle.class);
|
||||||
|
when(vehicle.getLocationId()).thenReturn("vehLoc");
|
||||||
|
when(vehicle.isReturnToDepot()).thenReturn(false);
|
||||||
|
when(vehicle.getId()).thenReturn("vehId");
|
||||||
|
|
||||||
|
VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, mock(Driver.class)).addPickup(shipment).addDelivery(shipment).build();
|
||||||
|
//start - pick(shipment) - del(shipment) - end
|
||||||
|
Shipment shipmentToInsert = mock(Shipment.class);
|
||||||
|
when(shipmentToInsert.getDeliveryLocation()).thenReturn("delLoc");
|
||||||
|
when(shipmentToInsert.getPickupLocation()).thenReturn("pickLoc");
|
||||||
|
InsertionData iData = mock(InsertionData.class);
|
||||||
|
when(iData.getPickupInsertionIndex()).thenReturn(2);
|
||||||
|
when(iData.getDeliveryInsertionIndex()).thenReturn(2);
|
||||||
|
when(iData.getSelectedVehicle()).thenReturn(vehicle);
|
||||||
|
|
||||||
|
Inserter inserter = new Inserter(mock(InsertionListeners.class));
|
||||||
|
inserter.insertJob(shipmentToInsert, iData, route);
|
||||||
|
|
||||||
|
assertEquals(4,route.getTourActivities().getActivities().size());
|
||||||
|
assertEquals(route.getTourActivities().getActivities().get(2).getLocationId(),shipmentToInsert.getPickupLocation());
|
||||||
|
assertEquals(route.getTourActivities().getActivities().get(3).getLocationId(),shipmentToInsert.getDeliveryLocation());
|
||||||
|
assertEquals(route.getEnd().getLocationId(),shipmentToInsert.getDeliveryLocation());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,113 @@
|
||||||
|
package jsprit.core.algorithm.recreate;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
import jsprit.core.algorithm.recreate.ActivityInsertionCostsCalculator.ActivityInsertionCosts;
|
||||||
|
import jsprit.core.problem.cost.VehicleRoutingActivityCosts;
|
||||||
|
import jsprit.core.problem.cost.VehicleRoutingTransportCosts;
|
||||||
|
import jsprit.core.problem.misc.JobInsertionContext;
|
||||||
|
import jsprit.core.problem.solution.route.VehicleRoute;
|
||||||
|
import jsprit.core.problem.solution.route.activity.End;
|
||||||
|
import jsprit.core.problem.solution.route.activity.TourActivity;
|
||||||
|
import jsprit.core.problem.vehicle.Vehicle;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class TestLocalActivityInsertionCostsCalculator {
|
||||||
|
|
||||||
|
VehicleRoutingTransportCosts tpCosts;
|
||||||
|
|
||||||
|
VehicleRoutingActivityCosts actCosts;
|
||||||
|
|
||||||
|
LocalActivityInsertionCostsCalculator calc;
|
||||||
|
|
||||||
|
Vehicle vehicle;
|
||||||
|
|
||||||
|
VehicleRoute route;
|
||||||
|
|
||||||
|
JobInsertionContext jic;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void doBefore(){
|
||||||
|
|
||||||
|
vehicle = mock(Vehicle.class);
|
||||||
|
route = mock(VehicleRoute.class);
|
||||||
|
when(route.isEmpty()).thenReturn(false);
|
||||||
|
when(route.getVehicle()).thenReturn(vehicle);
|
||||||
|
|
||||||
|
jic = mock(JobInsertionContext.class);
|
||||||
|
when(jic.getRoute()).thenReturn(route);
|
||||||
|
when(jic.getNewVehicle()).thenReturn(vehicle);
|
||||||
|
|
||||||
|
tpCosts = mock(VehicleRoutingTransportCosts.class);
|
||||||
|
when(tpCosts.getTransportCost("i", "j", 0.0, null, vehicle)).thenReturn(2.0);
|
||||||
|
when(tpCosts.getTransportTime("i", "j", 0.0, null, vehicle)).thenReturn(0.0);
|
||||||
|
when(tpCosts.getTransportCost("i", "k", 0.0, null, vehicle)).thenReturn(3.0);
|
||||||
|
when(tpCosts.getTransportTime("i", "k", 0.0, null, vehicle)).thenReturn(0.0);
|
||||||
|
when(tpCosts.getTransportCost("k", "j", 0.0, null, vehicle)).thenReturn(3.0);
|
||||||
|
when(tpCosts.getTransportTime("k", "j", 0.0, null, vehicle)).thenReturn(0.0);
|
||||||
|
|
||||||
|
actCosts = mock(VehicleRoutingActivityCosts.class);
|
||||||
|
calc = new LocalActivityInsertionCostsCalculator(tpCosts, actCosts);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenInsertingActBetweenTwoRouteActs_itCalcsMarginalTpCosts(){
|
||||||
|
TourActivity prevAct = mock(TourActivity.class);
|
||||||
|
when(prevAct.getLocationId()).thenReturn("i");
|
||||||
|
TourActivity nextAct = mock(TourActivity.class);
|
||||||
|
when(nextAct.getLocationId()).thenReturn("j");
|
||||||
|
TourActivity newAct = mock(TourActivity.class);
|
||||||
|
when(newAct.getLocationId()).thenReturn("k");
|
||||||
|
|
||||||
|
when(vehicle.isReturnToDepot()).thenReturn(true);
|
||||||
|
|
||||||
|
ActivityInsertionCosts costs = calc.getCosts(jic, prevAct, nextAct, newAct, 0.0);
|
||||||
|
assertEquals(4.0,costs.getAdditionalCosts(),0.01);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenInsertingActBetweenLastActAndEnd_itCalcsMarginalTpCosts(){
|
||||||
|
TourActivity prevAct = mock(TourActivity.class);
|
||||||
|
when(prevAct.getLocationId()).thenReturn("i");
|
||||||
|
End nextAct = End.newInstance("j", 0.0, 0.0);
|
||||||
|
TourActivity newAct = mock(TourActivity.class);
|
||||||
|
when(newAct.getLocationId()).thenReturn("k");
|
||||||
|
|
||||||
|
when(vehicle.isReturnToDepot()).thenReturn(true);
|
||||||
|
|
||||||
|
ActivityInsertionCosts costs = calc.getCosts(jic, prevAct, nextAct, newAct, 0.0);
|
||||||
|
assertEquals(4.0,costs.getAdditionalCosts(),0.01);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenInsertingActBetweenTwoRouteActsAndRouteIsOpen_itCalcsMarginalTpCosts(){
|
||||||
|
TourActivity prevAct = mock(TourActivity.class);
|
||||||
|
when(prevAct.getLocationId()).thenReturn("i");
|
||||||
|
TourActivity nextAct = mock(TourActivity.class);
|
||||||
|
when(nextAct.getLocationId()).thenReturn("j");
|
||||||
|
TourActivity newAct = mock(TourActivity.class);
|
||||||
|
when(newAct.getLocationId()).thenReturn("k");
|
||||||
|
|
||||||
|
when(vehicle.isReturnToDepot()).thenReturn(false);
|
||||||
|
|
||||||
|
ActivityInsertionCosts costs = calc.getCosts(jic, prevAct, nextAct, newAct, 0.0);
|
||||||
|
assertEquals(4.0,costs.getAdditionalCosts(),0.01);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenInsertingActBetweenLastActAndEndAndRouteIsOpen_itCalculatesTpCostsFromPrevToNewAct(){
|
||||||
|
TourActivity prevAct = mock(TourActivity.class);
|
||||||
|
when(prevAct.getLocationId()).thenReturn("i");
|
||||||
|
End nextAct = End.newInstance("j", 0.0, 0.0);
|
||||||
|
TourActivity newAct = mock(TourActivity.class);
|
||||||
|
when(newAct.getLocationId()).thenReturn("k");
|
||||||
|
|
||||||
|
when(vehicle.isReturnToDepot()).thenReturn(false);
|
||||||
|
|
||||||
|
ActivityInsertionCosts costs = calc.getCosts(jic, prevAct, nextAct, newAct, 0.0);
|
||||||
|
assertEquals(3.0,costs.getAdditionalCosts(),0.01);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -17,8 +17,9 @@
|
||||||
package jsprit.core.problem;
|
package jsprit.core.problem;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import jsprit.core.problem.VehicleRoutingProblem;
|
import static org.mockito.Mockito.mock;
|
||||||
import jsprit.core.problem.VehicleRoutingProblem.FleetSize;
|
import jsprit.core.problem.VehicleRoutingProblem.FleetSize;
|
||||||
|
import jsprit.core.problem.constraint.Constraint;
|
||||||
import jsprit.core.problem.job.Job;
|
import jsprit.core.problem.job.Job;
|
||||||
import jsprit.core.problem.job.Shipment;
|
import jsprit.core.problem.job.Shipment;
|
||||||
import jsprit.core.problem.vehicle.Vehicle;
|
import jsprit.core.problem.vehicle.Vehicle;
|
||||||
|
|
@ -82,5 +83,15 @@ public class VehicleRoutingProblemBuilderTest {
|
||||||
assertEquals(s2,vrp.getJobs().get("s2"));
|
assertEquals(s2,vrp.getJobs().get("s2"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenConstraintsAdded_theyShouldAppearInConstraintCollection(){
|
||||||
|
Constraint c1 = mock(Constraint.class);
|
||||||
|
Constraint c2 = mock(Constraint.class);
|
||||||
|
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
|
||||||
|
builder.addConstraint(c1).addConstraint(c2);
|
||||||
|
VehicleRoutingProblem problem = builder.build();
|
||||||
|
assertEquals(2,problem.getConstraints().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
package jsprit.core.problem.constraint;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import jsprit.core.problem.VehicleRoutingProblem;
|
||||||
|
import jsprit.core.problem.solution.route.state.RouteAndActivityStateGetter;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class TestConstraintManager {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenGettingConstraintsViaConstructor_theyShouldBeResolvedCorrectly(){
|
||||||
|
List<Constraint> constraints = new ArrayList<Constraint>();
|
||||||
|
constraints.add(new ServiceDeliveriesFirstConstraint());
|
||||||
|
constraints.add(mock(HardRouteStateLevelConstraint.class));
|
||||||
|
ConstraintManager cManager = new ConstraintManager(mock(VehicleRoutingProblem.class),mock(RouteAndActivityStateGetter.class),constraints);
|
||||||
|
assertEquals(2,cManager.getConstraints().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenGettingConstraintsViaConstructorAndAtLeastOneConstraintCannotBeResolved_itShouldOnlyAddTheKnownConstraints(){
|
||||||
|
List<Constraint> constraints = new ArrayList<Constraint>();
|
||||||
|
constraints.add(new ServiceDeliveriesFirstConstraint());
|
||||||
|
constraints.add(mock(Constraint.class));
|
||||||
|
ConstraintManager cManager = new ConstraintManager(mock(VehicleRoutingProblem.class),mock(RouteAndActivityStateGetter.class),constraints);
|
||||||
|
assertEquals(1,cManager.getConstraints().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
package jsprit.core.problem.solution.route;
|
package jsprit.core.problem.solution.route;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
import jsprit.core.problem.driver.Driver;
|
import jsprit.core.problem.driver.Driver;
|
||||||
import jsprit.core.problem.job.Shipment;
|
import jsprit.core.problem.job.Shipment;
|
||||||
import jsprit.core.problem.vehicle.Vehicle;
|
import jsprit.core.problem.vehicle.Vehicle;
|
||||||
|
|
@ -60,18 +60,73 @@ public class VehicleRouteBuilderTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenBuildingOpenRoute(){
|
public void whenBuildingClosedRoute_routeEndShouldHaveLocationOfVehicle(){
|
||||||
assertTrue(false);
|
Shipment s = mock(Shipment.class);
|
||||||
|
Shipment s2 = mock(Shipment.class);
|
||||||
|
Vehicle vehicle = mock(Vehicle.class);
|
||||||
|
when(vehicle.isReturnToDepot()).thenReturn(true);
|
||||||
|
when(vehicle.getLocationId()).thenReturn("vehLoc");
|
||||||
|
VehicleRoute.Builder builder = VehicleRoute.Builder.newInstance(vehicle, mock(Driver.class));
|
||||||
|
builder.addPickup(s);
|
||||||
|
builder.addPickup(s2);
|
||||||
|
builder.addDelivery(s);
|
||||||
|
builder.addDelivery(s2);
|
||||||
|
VehicleRoute route = builder.build();
|
||||||
|
assertEquals(route.getEnd().getLocationId(), vehicle.getLocationId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenBuildingOpenRoute_routeEndShouldHaveLocationOfLastActivity(){
|
||||||
|
Shipment s = mock(Shipment.class);
|
||||||
|
Shipment s2 = mock(Shipment.class);
|
||||||
|
when(s2.getDeliveryLocation()).thenReturn("delLoc");
|
||||||
|
Vehicle vehicle = mock(Vehicle.class);
|
||||||
|
when(vehicle.isReturnToDepot()).thenReturn(false);
|
||||||
|
when(vehicle.getLocationId()).thenReturn("vehLoc");
|
||||||
|
VehicleRoute.Builder builder = VehicleRoute.Builder.newInstance(vehicle, mock(Driver.class));
|
||||||
|
builder.addPickup(s);
|
||||||
|
builder.addPickup(s2);
|
||||||
|
builder.addDelivery(s);
|
||||||
|
builder.addDelivery(s2);
|
||||||
|
VehicleRoute route = builder.build();
|
||||||
|
assertEquals(route.getEnd().getLocationId(), s2.getDeliveryLocation());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenSettingDepartureTime(){
|
public void whenSettingDepartureTime(){
|
||||||
assertTrue(false);
|
Shipment s = mock(Shipment.class);
|
||||||
|
Shipment s2 = mock(Shipment.class);
|
||||||
|
when(s2.getDeliveryLocation()).thenReturn("delLoc");
|
||||||
|
Vehicle vehicle = mock(Vehicle.class);
|
||||||
|
when(vehicle.isReturnToDepot()).thenReturn(false);
|
||||||
|
when(vehicle.getLocationId()).thenReturn("vehLoc");
|
||||||
|
VehicleRoute.Builder builder = VehicleRoute.Builder.newInstance(vehicle, mock(Driver.class));
|
||||||
|
builder.addPickup(s);
|
||||||
|
builder.addPickup(s2);
|
||||||
|
builder.addDelivery(s);
|
||||||
|
builder.addDelivery(s2);
|
||||||
|
builder.setDepartureTime(100);
|
||||||
|
VehicleRoute route = builder.build();
|
||||||
|
assertEquals(100.0,route.getDepartureTime(),0.01);
|
||||||
|
assertEquals(100.0,route.getStart().getEndTime(),0.01);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenSettingEndTime(){
|
public void whenSettingEndTime(){
|
||||||
assertTrue(false);
|
Shipment s = mock(Shipment.class);
|
||||||
|
Shipment s2 = mock(Shipment.class);
|
||||||
|
when(s2.getDeliveryLocation()).thenReturn("delLoc");
|
||||||
|
Vehicle vehicle = mock(Vehicle.class);
|
||||||
|
when(vehicle.isReturnToDepot()).thenReturn(false);
|
||||||
|
when(vehicle.getLocationId()).thenReturn("vehLoc");
|
||||||
|
VehicleRoute.Builder builder = VehicleRoute.Builder.newInstance(vehicle, mock(Driver.class));
|
||||||
|
builder.addPickup(s);
|
||||||
|
builder.addPickup(s2);
|
||||||
|
builder.addDelivery(s);
|
||||||
|
builder.addDelivery(s2);
|
||||||
|
builder.setRouteEndArrivalTime(100.0);
|
||||||
|
VehicleRoute route = builder.build();
|
||||||
|
assertEquals(100.0,route.getEnd().getArrTime(),0.01);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
item id pickup_x pickup_y deliver_x deliver_y
|
|
||||||
envelope 1 13745 55419 13883 55756
|
|
||||||
envelope 2 8406 53246 13937 55854
|
|
||||||
envelope 3 15738 57396 35996 79499
|
|
||||||
envelope 4 12045 60418 19349 57118
|
|
||||||
envelope 5 13750 56416 35733 78403
|
|
||||||
envelope 6 13190 57068 11860 59749
|
|
||||||
envelope 7 15021 55768 14098 57379
|
|
||||||
envelope 8 11513 58543 11501 59683
|
|
||||||
envelope 9 12013 64155 14120 59301
|
|
||||||
envelope 10 15006 57578 35511 78426
|
|
||||||
envelope 11 11450 58819 11916 58338
|
|
||||||
envelope 12 13728 56304 35524 79013
|
|
||||||
envelope 13 15104 60923 17937 57066
|
|
||||||
envelope 14 11373 58388 13983 53804
|
|
||||||
envelope 15 18575 55186 18718 54381
|
|
||||||
envelope 16 11639 50071 17363 58375
|
|
||||||
envelope 17 11273 53410 10860 60441
|
|
||||||
envelope 18 13766 59041 13963 57769
|
|
||||||
envelope 19 16138 55801 16183 56024
|
|
||||||
envelope 20 13728 56146 14301 61694
|
|
||||||
envelope 21 12848 57059 13586 59734
|
|
||||||
envelope 22 13645 56488 13955 55859
|
|
||||||
envelope 23 12896 56838 13937 55908
|
|
||||||
envelope 24 13341 58150 35709 78924
|
|
||||||
envelope 25 13483 57303 13614 57820
|
|
||||||
envelope 26 12741 63478 15230 59838
|
|
||||||
envelope 27 14676 51691 16501 48361
|
|
||||||
envelope 28 13748 54933 14120 56110
|
|
||||||
envelope 29 17875 59565 20453 61903
|
|
||||||
envelope 30 9772 56424 6404 55601
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
type id x y
|
|
||||||
messenger A 13750 57578
|
|
||||||
messenger B 15104 53410
|
|
||||||
messenger C 13728 55801
|
|
||||||
messenger D 12741 63478
|
|
||||||
messenger E 14676 18575
|
|
||||||
1236
jsprit-examples/input/pickups_and_deliveries_solomon_r101_open.xml
Normal file
1236
jsprit-examples/input/pickups_and_deliveries_solomon_r101_open.xml
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -4,9 +4,7 @@ import java.io.BufferedReader;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileReader;
|
import java.io.FileReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
@ -19,8 +17,10 @@ import jsprit.core.problem.VehicleRoutingProblem;
|
||||||
import jsprit.core.problem.VehicleRoutingProblem.Builder;
|
import jsprit.core.problem.VehicleRoutingProblem.Builder;
|
||||||
import jsprit.core.problem.VehicleRoutingProblem.FleetSize;
|
import jsprit.core.problem.VehicleRoutingProblem.FleetSize;
|
||||||
import jsprit.core.problem.constraint.HardActivityStateLevelConstraint;
|
import jsprit.core.problem.constraint.HardActivityStateLevelConstraint;
|
||||||
|
import jsprit.core.problem.constraint.HardRouteStateLevelConstraint;
|
||||||
import jsprit.core.problem.cost.VehicleRoutingTransportCosts;
|
import jsprit.core.problem.cost.VehicleRoutingTransportCosts;
|
||||||
import jsprit.core.problem.driver.DriverImpl;
|
import jsprit.core.problem.driver.DriverImpl;
|
||||||
|
import jsprit.core.problem.io.VrpXMLWriter;
|
||||||
import jsprit.core.problem.job.Job;
|
import jsprit.core.problem.job.Job;
|
||||||
import jsprit.core.problem.job.Shipment;
|
import jsprit.core.problem.job.Shipment;
|
||||||
import jsprit.core.problem.misc.JobInsertionContext;
|
import jsprit.core.problem.misc.JobInsertionContext;
|
||||||
|
|
@ -39,42 +39,22 @@ public class BicycleMessenger {
|
||||||
|
|
||||||
static class ThreeTimesLessThanDirectRouteConstraint implements HardActivityStateLevelConstraint {
|
static class ThreeTimesLessThanDirectRouteConstraint implements HardActivityStateLevelConstraint {
|
||||||
|
|
||||||
private VehicleRoutingTransportCosts vrpCosts;
|
private VehicleRoutingTransportCosts routingCosts;
|
||||||
|
|
||||||
//jobId map direct-distance by nearestMessenger
|
//jobId map direct-distance by nearestMessenger
|
||||||
private Map<String,Double> bestMessengers = new HashMap<String, Double>();
|
private Map<String,Double> bestMessengers = new HashMap<String, Double>();
|
||||||
|
|
||||||
public ThreeTimesLessThanDirectRouteConstraint(VehicleRoutingTransportCosts vrpCosts, Collection<Job> envelopes, Collection<Vehicle> messengers) {
|
public ThreeTimesLessThanDirectRouteConstraint(Map<String, Double> nearestMessengers, VehicleRoutingTransportCosts routingCosts) {
|
||||||
super();
|
this.bestMessengers = nearestMessengers;
|
||||||
this.vrpCosts = vrpCosts;
|
this.routingCosts = routingCosts;
|
||||||
determineNearestMessenger(envelopes,messengers);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void determineNearestMessenger(Collection<Job> envelopes,Collection<Vehicle> messengers) {
|
|
||||||
for(Job envelope : envelopes){
|
|
||||||
double minDirect = Double.MAX_VALUE;
|
|
||||||
for(Vehicle m : messengers){
|
|
||||||
double direct = getDirectRouteDistance(envelope,m);
|
|
||||||
if(direct < minDirect){
|
|
||||||
minDirect = direct;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bestMessengers.put(envelope.getId(), minDirect);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private double getDirectRouteDistance(Job job, Vehicle v) {
|
|
||||||
Shipment envelope = (Shipment) job;
|
|
||||||
double direct = vrpCosts.getTransportTime(v.getLocationId(), envelope.getPickupLocation(), 0.0, DriverImpl.noDriver(), v) +
|
|
||||||
vrpCosts.getTransportTime(envelope.getPickupLocation(), envelope.getDeliveryLocation(), 0.0, DriverImpl.noDriver(), v);
|
|
||||||
return direct;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ConstraintsStatus fulfilled(JobInsertionContext iFacts,TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
|
public ConstraintsStatus fulfilled(JobInsertionContext iFacts,TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
|
||||||
if(newAct instanceof DeliverShipment){
|
if(newAct instanceof DeliverShipment){
|
||||||
double deliveryTime = prevActDepTime + vrpCosts.getTransportTime(prevAct.getLocationId(), newAct.getLocationId(), prevActDepTime, iFacts.getNewDriver(), iFacts.getNewVehicle());
|
double deliveryTime = prevActDepTime + routingCosts.getTransportTime(prevAct.getLocationId(), newAct.getLocationId(), prevActDepTime, iFacts.getNewDriver(), iFacts.getNewVehicle());
|
||||||
if(deliveryTime > 3 * bestMessengers.get(((DeliverShipment) newAct).getJob().getId())){
|
double directTimeOfNearestMessenger = bestMessengers.get(((DeliverShipment) newAct).getJob().getId());
|
||||||
|
if(deliveryTime > 3 * directTimeOfNearestMessenger){
|
||||||
return ConstraintsStatus.NOT_FULFILLED_BREAK;
|
return ConstraintsStatus.NOT_FULFILLED_BREAK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -83,21 +63,52 @@ public class BicycleMessenger {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class IgnoreMessengerThatCanNeverMeetTimeRequirements implements HardRouteStateLevelConstraint {
|
||||||
|
|
||||||
|
private Map<String,Double> bestMessengers = new HashMap<String, Double>();
|
||||||
|
|
||||||
|
private VehicleRoutingTransportCosts routingCosts;
|
||||||
|
|
||||||
|
public IgnoreMessengerThatCanNeverMeetTimeRequirements(Map<String, Double> bestMessengers,VehicleRoutingTransportCosts routingCosts) {
|
||||||
|
super();
|
||||||
|
this.bestMessengers = bestMessengers;
|
||||||
|
this.routingCosts = routingCosts;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean fulfilled(JobInsertionContext insertionContext) {
|
||||||
|
double timeOfDirectRoute = getTimeOfDirectRoute(insertionContext.getJob(), insertionContext.getNewVehicle(), routingCosts);
|
||||||
|
double timeOfNearestMessenger = bestMessengers.get(insertionContext.getJob().getId());
|
||||||
|
if(timeOfDirectRoute > 3 * timeOfNearestMessenger){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param args
|
* @param args
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public static void main(String[] args) throws IOException {
|
public static void main(String[] args) throws IOException {
|
||||||
|
|
||||||
|
|
||||||
VehicleRoutingProblem.Builder problemBuilder = VehicleRoutingProblem.Builder.newInstance();
|
VehicleRoutingProblem.Builder problemBuilder = VehicleRoutingProblem.Builder.newInstance();
|
||||||
readEnvelopes(problemBuilder);
|
readEnvelopes(problemBuilder);
|
||||||
readMessengers(problemBuilder);
|
readMessengers(problemBuilder);
|
||||||
|
|
||||||
|
VehicleRoutingTransportCosts routingCosts = new CrowFlyCosts(problemBuilder.getLocations());
|
||||||
|
Map<String,Double> nearestMessengers = getNearestMessengers(routingCosts, problemBuilder.getAddedJobs(), problemBuilder.getAddedVehicles());
|
||||||
|
|
||||||
problemBuilder.setFleetSize(FleetSize.FINITE);
|
problemBuilder.setFleetSize(FleetSize.FINITE);
|
||||||
// problemBuilder.addConstraint(new ThreeTimesLessThanDirectRouteConstraint(new CrowFlyCosts(problemBuilder.getLocations()),problemBuilder.getAddedJobs(),problemBuilder.getAddedVehicles()));
|
problemBuilder.addConstraint(new ThreeTimesLessThanDirectRouteConstraint(nearestMessengers, routingCosts));
|
||||||
|
problemBuilder.addConstraint(new IgnoreMessengerThatCanNeverMeetTimeRequirements(nearestMessengers, routingCosts));
|
||||||
|
|
||||||
VehicleRoutingProblem bicycleMessengerProblem = problemBuilder.build();
|
VehicleRoutingProblem bicycleMessengerProblem = problemBuilder.build();
|
||||||
|
|
||||||
VehicleRoutingAlgorithm algorithm = VehicleRoutingAlgorithms.readAndCreateAlgorithm(bicycleMessengerProblem, 5,"input/algorithmConfig_open.xml");
|
VehicleRoutingAlgorithm algorithm = VehicleRoutingAlgorithms.readAndCreateAlgorithm(bicycleMessengerProblem,"input/algorithmConfig_open.xml");
|
||||||
// algorithm.setPrematureAlgorithmTermination(new IterationWithoutImprovementTermination(200));
|
algorithm.setPrematureAlgorithmTermination(new IterationWithoutImprovementTermination(200));
|
||||||
Collection<VehicleRoutingProblemSolution> solutions = algorithm.searchSolutions();
|
Collection<VehicleRoutingProblemSolution> solutions = algorithm.searchSolutions();
|
||||||
|
|
||||||
SolutionPrinter.print(Solutions.bestOf(solutions));
|
SolutionPrinter.print(Solutions.bestOf(solutions));
|
||||||
|
|
@ -113,9 +124,33 @@ public class BicycleMessenger {
|
||||||
// plotter1.setBoundingBox(10000, 47500, 20000, 67500);
|
// plotter1.setBoundingBox(10000, 47500, 20000, 67500);
|
||||||
plotter1.plot("output/bicycleMessengerSolution.png", "bicycleMessenger");
|
plotter1.plot("output/bicycleMessengerSolution.png", "bicycleMessenger");
|
||||||
|
|
||||||
|
new VrpXMLWriter(bicycleMessengerProblem, solutions).write("output/bicycleMessenger.xml");
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Map<String,Double> getNearestMessengers(VehicleRoutingTransportCosts routingCosts, Collection<Job> envelopes, Collection<Vehicle> messengers) {
|
||||||
|
Map<String,Double> nearestMessengers = new HashMap<String, Double>();
|
||||||
|
for(Job envelope : envelopes){
|
||||||
|
double minDirect = Double.MAX_VALUE;
|
||||||
|
for(Vehicle m : messengers){
|
||||||
|
double direct = getTimeOfDirectRoute(envelope, m, routingCosts);
|
||||||
|
if(direct < minDirect){
|
||||||
|
minDirect = direct;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nearestMessengers.put(envelope.getId(), minDirect);
|
||||||
|
}
|
||||||
|
return nearestMessengers;
|
||||||
|
}
|
||||||
|
|
||||||
|
static double getTimeOfDirectRoute(Job job, Vehicle v, VehicleRoutingTransportCosts routingCosts) {
|
||||||
|
Shipment envelope = (Shipment) job;
|
||||||
|
double direct = routingCosts.getTransportTime(v.getLocationId(), envelope.getPickupLocation(), 0.0, DriverImpl.noDriver(), v) +
|
||||||
|
routingCosts.getTransportTime(envelope.getPickupLocation(), envelope.getDeliveryLocation(), 0.0, DriverImpl.noDriver(), v);
|
||||||
|
return direct;
|
||||||
|
}
|
||||||
|
|
||||||
private static void readEnvelopes(Builder problemBuilder) throws IOException {
|
private static void readEnvelopes(Builder problemBuilder) throws IOException {
|
||||||
BufferedReader reader = new BufferedReader(new FileReader(new File("input/bicycle_messenger_demand.txt")));
|
BufferedReader reader = new BufferedReader(new FileReader(new File("input/bicycle_messenger_demand.txt")));
|
||||||
String line = null;
|
String line = null;
|
||||||
|
|
@ -134,7 +169,7 @@ public class BicycleMessenger {
|
||||||
BufferedReader reader = new BufferedReader(new FileReader(new File("input/bicycle_messenger_supply.txt")));
|
BufferedReader reader = new BufferedReader(new FileReader(new File("input/bicycle_messenger_supply.txt")));
|
||||||
String line = null;
|
String line = null;
|
||||||
boolean firstLine = true;
|
boolean firstLine = true;
|
||||||
VehicleType messengerType = VehicleTypeImpl.Builder.newInstance("messengerType", Integer.MAX_VALUE).setCostPerDistance(1).build();
|
VehicleType messengerType = VehicleTypeImpl.Builder.newInstance("messengerType", 15).setCostPerDistance(1).build();
|
||||||
while((line = reader.readLine()) != null){
|
while((line = reader.readLine()) != null){
|
||||||
if(firstLine) { firstLine = false; continue; }
|
if(firstLine) { firstLine = false; continue; }
|
||||||
String[] tokens = line.split("\\s+");
|
String[] tokens = line.split("\\s+");
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,6 @@ import jsprit.core.algorithm.selector.SelectBest;
|
||||||
import jsprit.core.problem.VehicleRoutingProblem;
|
import jsprit.core.problem.VehicleRoutingProblem;
|
||||||
import jsprit.core.problem.io.VrpXMLReader;
|
import jsprit.core.problem.io.VrpXMLReader;
|
||||||
import jsprit.core.problem.solution.VehicleRoutingProblemSolution;
|
import jsprit.core.problem.solution.VehicleRoutingProblemSolution;
|
||||||
import jsprit.instance.reader.SolomonReader;
|
|
||||||
|
|
||||||
|
|
||||||
public class SolomonOpenExample {
|
public class SolomonOpenExample {
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ import jsprit.core.algorithm.io.VehicleRoutingAlgorithms;
|
||||||
import jsprit.core.algorithm.selector.SelectBest;
|
import jsprit.core.algorithm.selector.SelectBest;
|
||||||
import jsprit.core.problem.VehicleRoutingProblem;
|
import jsprit.core.problem.VehicleRoutingProblem;
|
||||||
import jsprit.core.problem.VehicleRoutingProblem.Constraint;
|
import jsprit.core.problem.VehicleRoutingProblem.Constraint;
|
||||||
|
import jsprit.core.problem.constraint.ServiceDeliveriesFirstConstraint;
|
||||||
import jsprit.core.problem.io.VrpXMLReader;
|
import jsprit.core.problem.io.VrpXMLReader;
|
||||||
import jsprit.core.problem.solution.VehicleRoutingProblemSolution;
|
import jsprit.core.problem.solution.VehicleRoutingProblemSolution;
|
||||||
|
|
||||||
|
|
@ -62,7 +63,8 @@ public class VRPWithBackhaulsExample {
|
||||||
/*
|
/*
|
||||||
* Finally, the problem can be built. By default, transportCosts are crowFlyDistances (as usually used for vrp-instances).
|
* Finally, the problem can be built. By default, transportCosts are crowFlyDistances (as usually used for vrp-instances).
|
||||||
*/
|
*/
|
||||||
vrpBuilder.addProblemConstraint(Constraint.DELIVERIES_FIRST);
|
// vrpBuilder.addProblemConstraint(Constraint.DELIVERIES_FIRST);
|
||||||
|
vrpBuilder.addConstraint(new ServiceDeliveriesFirstConstraint());
|
||||||
|
|
||||||
VehicleRoutingProblem vrp = vrpBuilder.build();
|
VehicleRoutingProblem vrp = vrpBuilder.build();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ import jsprit.core.algorithm.io.VehicleRoutingAlgorithms;
|
||||||
import jsprit.core.algorithm.selector.SelectBest;
|
import jsprit.core.algorithm.selector.SelectBest;
|
||||||
import jsprit.core.problem.VehicleRoutingProblem;
|
import jsprit.core.problem.VehicleRoutingProblem;
|
||||||
import jsprit.core.problem.VehicleRoutingProblem.Constraint;
|
import jsprit.core.problem.VehicleRoutingProblem.Constraint;
|
||||||
|
import jsprit.core.problem.constraint.ServiceDeliveriesFirstConstraint;
|
||||||
import jsprit.core.problem.io.VrpXMLReader;
|
import jsprit.core.problem.io.VrpXMLReader;
|
||||||
import jsprit.core.problem.solution.VehicleRoutingProblemSolution;
|
import jsprit.core.problem.solution.VehicleRoutingProblemSolution;
|
||||||
|
|
||||||
|
|
@ -62,7 +63,7 @@ public class VRPWithBackhaulsExample2 {
|
||||||
/*
|
/*
|
||||||
* add the backhaul constraint to the problem
|
* add the backhaul constraint to the problem
|
||||||
*/
|
*/
|
||||||
vrpBuilder.addProblemConstraint(Constraint.DELIVERIES_FIRST);
|
vrpBuilder.addConstraint(new ServiceDeliveriesFirstConstraint());
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Finally, the problem can be built. By default, transportCosts are crowFlyDistances (as usually used for vrp-instances).
|
* Finally, the problem can be built. By default, transportCosts are crowFlyDistances (as usually used for vrp-instances).
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue