mirror of
https://github.com/graphhopper/jsprit.git
synced 2020-01-24 07:45:05 +01:00
variable departure times and waiting time opt
This commit is contained in:
parent
1604a637a5
commit
552729d7ee
10 changed files with 403 additions and 14 deletions
|
|
@ -0,0 +1,40 @@
|
||||||
|
package jsprit.core.algorithm.recreate;
|
||||||
|
|
||||||
|
import jsprit.core.algorithm.recreate.listener.InsertionStartsListener;
|
||||||
|
import jsprit.core.algorithm.recreate.listener.JobInsertedListener;
|
||||||
|
import jsprit.core.problem.VehicleRoutingProblem;
|
||||||
|
import jsprit.core.problem.job.Job;
|
||||||
|
import jsprit.core.problem.solution.route.VehicleRoute;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by schroeder on 22/07/15.
|
||||||
|
*/
|
||||||
|
public class ConfigureLocalActivityInsertionCalculator implements InsertionStartsListener, JobInsertedListener {
|
||||||
|
|
||||||
|
private VehicleRoutingProblem vrp;
|
||||||
|
|
||||||
|
private LocalActivityInsertionCostsCalculator localActivityInsertionCostsCalculator;
|
||||||
|
|
||||||
|
private int nuOfJobsToRecreate;
|
||||||
|
|
||||||
|
public ConfigureLocalActivityInsertionCalculator(VehicleRoutingProblem vrp, LocalActivityInsertionCostsCalculator localActivityInsertionCostsCalculator) {
|
||||||
|
this.vrp = vrp;
|
||||||
|
this.localActivityInsertionCostsCalculator = localActivityInsertionCostsCalculator;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void informInsertionStarts(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs) {
|
||||||
|
this.nuOfJobsToRecreate = unassignedJobs.size();
|
||||||
|
double completenessRatio = (1-((double)nuOfJobsToRecreate/(double)vrp.getJobs().values().size()));
|
||||||
|
localActivityInsertionCostsCalculator.setSolutionCompletenessRatio(completenessRatio);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) {
|
||||||
|
nuOfJobsToRecreate--;
|
||||||
|
double completenessRatio = (1-((double)nuOfJobsToRecreate/(double)vrp.getJobs().values().size()));
|
||||||
|
localActivityInsertionCostsCalculator.setSolutionCompletenessRatio(completenessRatio);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -259,8 +259,10 @@ public class JobInsertionCostsCalculatorBuilder {
|
||||||
if(constraintManager == null) throw new IllegalStateException("constraint-manager is null");
|
if(constraintManager == null) throw new IllegalStateException("constraint-manager is null");
|
||||||
|
|
||||||
ActivityInsertionCostsCalculator actInsertionCalc;
|
ActivityInsertionCostsCalculator actInsertionCalc;
|
||||||
|
ConfigureLocalActivityInsertionCalculator configLocal = null;
|
||||||
if(activityInsertionCostCalculator == null && addDefaultCostCalc){
|
if(activityInsertionCostCalculator == null && addDefaultCostCalc){
|
||||||
actInsertionCalc = new LocalActivityInsertionCostsCalculator(vrp.getTransportCosts(), vrp.getActivityCosts());
|
actInsertionCalc = new LocalActivityInsertionCostsCalculator(vrp.getTransportCosts(), vrp.getActivityCosts());
|
||||||
|
configLocal = new ConfigureLocalActivityInsertionCalculator(vrp, (LocalActivityInsertionCostsCalculator) actInsertionCalc);
|
||||||
}
|
}
|
||||||
else if(activityInsertionCostCalculator == null && !addDefaultCostCalc){
|
else if(activityInsertionCostCalculator == null && !addDefaultCostCalc){
|
||||||
actInsertionCalc = new ActivityInsertionCostsCalculator(){
|
actInsertionCalc = new ActivityInsertionCostsCalculator(){
|
||||||
|
|
@ -296,7 +298,11 @@ public class JobInsertionCostsCalculatorBuilder {
|
||||||
switcher.put(Pickup.class, serviceInsertion);
|
switcher.put(Pickup.class, serviceInsertion);
|
||||||
switcher.put(Delivery.class, serviceInsertion);
|
switcher.put(Delivery.class, serviceInsertion);
|
||||||
|
|
||||||
return new CalculatorPlusListeners(switcher);
|
CalculatorPlusListeners calculatorPlusListeners = new CalculatorPlusListeners(switcher);
|
||||||
|
if(configLocal != null){
|
||||||
|
calculatorPlusListeners.insertionListener.add(configLocal);
|
||||||
|
}
|
||||||
|
return calculatorPlusListeners;
|
||||||
}
|
}
|
||||||
|
|
||||||
private CalculatorPlusListeners createCalculatorConsideringFixedCosts(VehicleRoutingProblem vrp, JobInsertionCostsCalculator baseCalculator, RouteAndActivityStateGetter activityStates2, double weightOfFixedCosts){
|
private CalculatorPlusListeners createCalculatorConsideringFixedCosts(VehicleRoutingProblem vrp, JobInsertionCostsCalculator baseCalculator, RouteAndActivityStateGetter activityStates2, double weightOfFixedCosts){
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ import jsprit.core.problem.cost.VehicleRoutingActivityCosts;
|
||||||
import jsprit.core.problem.cost.VehicleRoutingTransportCosts;
|
import jsprit.core.problem.cost.VehicleRoutingTransportCosts;
|
||||||
import jsprit.core.problem.misc.JobInsertionContext;
|
import jsprit.core.problem.misc.JobInsertionContext;
|
||||||
import jsprit.core.problem.solution.route.activity.End;
|
import jsprit.core.problem.solution.route.activity.End;
|
||||||
|
import jsprit.core.problem.solution.route.activity.Start;
|
||||||
import jsprit.core.problem.solution.route.activity.TourActivity;
|
import jsprit.core.problem.solution.route.activity.TourActivity;
|
||||||
import jsprit.core.util.CalculationUtils;
|
import jsprit.core.util.CalculationUtils;
|
||||||
|
|
||||||
|
|
@ -41,6 +42,9 @@ class LocalActivityInsertionCostsCalculator implements ActivityInsertionCostsCal
|
||||||
|
|
||||||
private VehicleRoutingActivityCosts activityCosts;
|
private VehicleRoutingActivityCosts activityCosts;
|
||||||
|
|
||||||
|
private double activityCostsWeight = 1.;
|
||||||
|
|
||||||
|
private double solutionCompletenessRatio = 1.;
|
||||||
|
|
||||||
public LocalActivityInsertionCostsCalculator(VehicleRoutingTransportCosts routingCosts, VehicleRoutingActivityCosts actCosts) {
|
public LocalActivityInsertionCostsCalculator(VehicleRoutingTransportCosts routingCosts, VehicleRoutingActivityCosts actCosts) {
|
||||||
super();
|
super();
|
||||||
|
|
@ -56,6 +60,11 @@ class LocalActivityInsertionCostsCalculator implements ActivityInsertionCostsCal
|
||||||
double newAct_arrTime = depTimeAtPrevAct + tp_time_prevAct_newAct;
|
double newAct_arrTime = depTimeAtPrevAct + tp_time_prevAct_newAct;
|
||||||
double newAct_endTime = CalculationUtils.getActivityEndTime(newAct_arrTime, newAct);
|
double newAct_endTime = CalculationUtils.getActivityEndTime(newAct_arrTime, newAct);
|
||||||
double act_costs_newAct = activityCosts.getActivityCost(newAct, newAct_arrTime, iFacts.getNewDriver(), iFacts.getNewVehicle());
|
double act_costs_newAct = activityCosts.getActivityCost(newAct, newAct_arrTime, iFacts.getNewDriver(), iFacts.getNewVehicle());
|
||||||
|
if(prevAct instanceof Start) {
|
||||||
|
if(iFacts.getNewVehicle().hasVariableDepartureTime()){
|
||||||
|
act_costs_newAct = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//open routes
|
//open routes
|
||||||
if(nextAct instanceof End){
|
if(nextAct instanceof End){
|
||||||
|
|
@ -68,22 +77,30 @@ class LocalActivityInsertionCostsCalculator implements ActivityInsertionCostsCal
|
||||||
double tp_time_newAct_nextAct = routingCosts.getTransportTime(newAct.getLocation(), nextAct.getLocation(), newAct_endTime, iFacts.getNewDriver(), iFacts.getNewVehicle());
|
double tp_time_newAct_nextAct = routingCosts.getTransportTime(newAct.getLocation(), nextAct.getLocation(), newAct_endTime, iFacts.getNewDriver(), iFacts.getNewVehicle());
|
||||||
double nextAct_arrTime = newAct_endTime + tp_time_newAct_nextAct;
|
double nextAct_arrTime = newAct_endTime + tp_time_newAct_nextAct;
|
||||||
double act_costs_nextAct = activityCosts.getActivityCost(nextAct, nextAct_arrTime, iFacts.getNewDriver(), iFacts.getNewVehicle());
|
double act_costs_nextAct = activityCosts.getActivityCost(nextAct, nextAct_arrTime, iFacts.getNewDriver(), iFacts.getNewVehicle());
|
||||||
double totalCosts = tp_costs_prevAct_newAct + tp_costs_newAct_nextAct + act_costs_newAct + act_costs_nextAct;
|
|
||||||
|
double totalCosts = tp_costs_prevAct_newAct + tp_costs_newAct_nextAct + solutionCompletenessRatio * activityCostsWeight * (act_costs_newAct + act_costs_nextAct);
|
||||||
|
|
||||||
double oldCosts;
|
double oldCosts;
|
||||||
if(iFacts.getRoute().isEmpty()){
|
if(iFacts.getRoute().isEmpty()){
|
||||||
double tp_costs_prevAct_nextAct = routingCosts.getTransportCost(prevAct.getLocation(), nextAct.getLocation(), depTimeAtPrevAct, iFacts.getNewDriver(), iFacts.getNewVehicle());
|
double tp_costs_prevAct_nextAct = routingCosts.getTransportCost(prevAct.getLocation(), nextAct.getLocation(), depTimeAtPrevAct, iFacts.getNewDriver(), iFacts.getNewVehicle());
|
||||||
double arrTime_nextAct = routingCosts.getTransportTime(prevAct.getLocation(), nextAct.getLocation(), depTimeAtPrevAct, iFacts.getNewDriver(), iFacts.getNewVehicle());
|
double arrTime_nextAct = routingCosts.getTransportTime(prevAct.getLocation(), nextAct.getLocation(), depTimeAtPrevAct, iFacts.getNewDriver(), iFacts.getNewVehicle());
|
||||||
double actCost_nextAct = activityCosts.getActivityCost(nextAct, arrTime_nextAct, iFacts.getNewDriver(), iFacts.getNewVehicle());
|
double actCost_nextAct = activityCosts.getActivityCost(nextAct, arrTime_nextAct, iFacts.getNewDriver(), iFacts.getNewVehicle());
|
||||||
oldCosts = tp_costs_prevAct_nextAct + actCost_nextAct;
|
oldCosts = tp_costs_prevAct_nextAct + solutionCompletenessRatio * activityCostsWeight * actCost_nextAct;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
double tp_costs_prevAct_nextAct = routingCosts.getTransportCost(prevAct.getLocation(), nextAct.getLocation(), prevAct.getEndTime(), iFacts.getRoute().getDriver(), iFacts.getRoute().getVehicle());
|
double tp_costs_prevAct_nextAct = routingCosts.getTransportCost(prevAct.getLocation(), nextAct.getLocation(), prevAct.getEndTime(), iFacts.getRoute().getDriver(), iFacts.getRoute().getVehicle());
|
||||||
double arrTime_nextAct = routingCosts.getTransportTime(prevAct.getLocation(), nextAct.getLocation(), prevAct.getEndTime(), iFacts.getRoute().getDriver(), iFacts.getRoute().getVehicle());
|
double arrTime_nextAct = routingCosts.getTransportTime(prevAct.getLocation(), nextAct.getLocation(), prevAct.getEndTime(), iFacts.getRoute().getDriver(), iFacts.getRoute().getVehicle());
|
||||||
double actCost_nextAct = activityCosts.getActivityCost(nextAct, arrTime_nextAct, iFacts.getRoute().getDriver(), iFacts.getRoute().getVehicle());
|
double actCost_nextAct = activityCosts.getActivityCost(nextAct, arrTime_nextAct, iFacts.getRoute().getDriver(), iFacts.getRoute().getVehicle());
|
||||||
oldCosts = tp_costs_prevAct_nextAct + actCost_nextAct;
|
oldCosts = tp_costs_prevAct_nextAct + solutionCompletenessRatio * activityCostsWeight * actCost_nextAct;
|
||||||
}
|
}
|
||||||
return totalCosts - oldCosts;
|
return totalCosts - oldCosts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setActivityCostWeight(double weight){
|
||||||
|
this.activityCostsWeight = weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSolutionCompletenessRatio(double solutionCompletenessRatio) {
|
||||||
|
this.solutionCompletenessRatio = solutionCompletenessRatio;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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 jsprit.core.algorithm.state;
|
||||||
|
|
||||||
|
import jsprit.core.problem.cost.VehicleRoutingTransportCosts;
|
||||||
|
import jsprit.core.problem.solution.route.RouteVisitor;
|
||||||
|
import jsprit.core.problem.solution.route.VehicleRoute;
|
||||||
|
import jsprit.core.problem.solution.route.activity.TourActivity;
|
||||||
|
|
||||||
|
public class UpdateDepartureTime implements StateUpdater, RouteVisitor{
|
||||||
|
|
||||||
|
private VehicleRoutingTransportCosts routingCosts;
|
||||||
|
|
||||||
|
public UpdateDepartureTime(VehicleRoutingTransportCosts routingCosts) {
|
||||||
|
this.routingCosts = routingCosts;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(VehicleRoute route) {
|
||||||
|
if(route.getVehicle() != null){
|
||||||
|
if(route.getVehicle().hasVariableDepartureTime()) {
|
||||||
|
if (!route.isEmpty()) {
|
||||||
|
TourActivity first = route.getActivities().get(0);
|
||||||
|
double earliestStart = first.getTheoreticalEarliestOperationStartTime();
|
||||||
|
double backwardTravelTime = routingCosts.getBackwardTransportTime(first.getLocation(), route.getStart().getLocation(),
|
||||||
|
earliestStart, route.getDriver(), route.getVehicle());
|
||||||
|
double newDepartureTime = Math.max(route.getStart().getEndTime(), earliestStart - backwardTravelTime);
|
||||||
|
route.setVehicleAndDepartureTime(route.getVehicle(), newDepartureTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -72,4 +72,6 @@ public interface Vehicle extends HasId, HasIndex {
|
||||||
public abstract VehicleTypeKey getVehicleTypeIdentifier();
|
public abstract VehicleTypeKey getVehicleTypeIdentifier();
|
||||||
|
|
||||||
public abstract Skills getSkills();
|
public abstract Skills getSkills();
|
||||||
|
|
||||||
|
public boolean hasVariableDepartureTime();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -91,6 +91,11 @@ public class VehicleImpl extends AbstractVehicle{
|
||||||
public Skills getSkills() {
|
public Skills getSkills() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasVariableDepartureTime() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -125,6 +130,8 @@ public class VehicleImpl extends AbstractVehicle{
|
||||||
|
|
||||||
private Location endLocation;
|
private Location endLocation;
|
||||||
|
|
||||||
|
private boolean hasVariableDepartureTime = false;
|
||||||
|
|
||||||
private Builder(String id) {
|
private Builder(String id) {
|
||||||
super();
|
super();
|
||||||
this.id = id;
|
this.id = id;
|
||||||
|
|
@ -143,6 +150,11 @@ public class VehicleImpl extends AbstractVehicle{
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Builder setHasVariableDepartureTime(boolean hasVariableDepartureTime){
|
||||||
|
this.hasVariableDepartureTime = hasVariableDepartureTime;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the flag whether the vehicle must return to depot or not.
|
* Sets the flag whether the vehicle must return to depot or not.
|
||||||
*
|
*
|
||||||
|
|
@ -274,6 +286,8 @@ public class VehicleImpl extends AbstractVehicle{
|
||||||
|
|
||||||
private final Location startLocation;
|
private final Location startLocation;
|
||||||
|
|
||||||
|
private final boolean hasVariableDepartureTime;
|
||||||
|
|
||||||
private VehicleImpl(Builder builder){
|
private VehicleImpl(Builder builder){
|
||||||
id = builder.id;
|
id = builder.id;
|
||||||
type = builder.type;
|
type = builder.type;
|
||||||
|
|
@ -283,6 +297,7 @@ public class VehicleImpl extends AbstractVehicle{
|
||||||
skills = builder.skills;
|
skills = builder.skills;
|
||||||
endLocation = builder.endLocation;
|
endLocation = builder.endLocation;
|
||||||
startLocation = builder.startLocation;
|
startLocation = builder.startLocation;
|
||||||
|
hasVariableDepartureTime = builder.hasVariableDepartureTime;
|
||||||
setVehicleIdentifier(new VehicleTypeKey(type.getTypeId(),startLocation.getId(),endLocation.getId(),earliestDeparture,latestArrival,skills));
|
setVehicleIdentifier(new VehicleTypeKey(type.getTypeId(),startLocation.getId(),endLocation.getId(),earliestDeparture,latestArrival,skills));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -341,6 +356,11 @@ public class VehicleImpl extends AbstractVehicle{
|
||||||
return skills;
|
return skills;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasVariableDepartureTime() {
|
||||||
|
return hasVariableDepartureTime;
|
||||||
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see java.lang.Object#hashCode()
|
* @see java.lang.Object#hashCode()
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,143 @@
|
||||||
|
package jsprit.core.algorithm;
|
||||||
|
|
||||||
|
import jsprit.core.algorithm.box.Jsprit;
|
||||||
|
import jsprit.core.algorithm.state.StateManager;
|
||||||
|
import jsprit.core.algorithm.state.UpdateDepartureTime;
|
||||||
|
import jsprit.core.analysis.SolutionAnalyser;
|
||||||
|
import jsprit.core.problem.Location;
|
||||||
|
import jsprit.core.problem.VehicleRoutingProblem;
|
||||||
|
import jsprit.core.problem.constraint.ConstraintManager;
|
||||||
|
import jsprit.core.problem.cost.TransportDistance;
|
||||||
|
import jsprit.core.problem.cost.VehicleRoutingActivityCosts;
|
||||||
|
import jsprit.core.problem.driver.Driver;
|
||||||
|
import jsprit.core.problem.job.Service;
|
||||||
|
import jsprit.core.problem.solution.SolutionCostCalculator;
|
||||||
|
import jsprit.core.problem.solution.VehicleRoutingProblemSolution;
|
||||||
|
import jsprit.core.problem.solution.route.activity.TimeWindow;
|
||||||
|
import jsprit.core.problem.solution.route.activity.TourActivity;
|
||||||
|
import jsprit.core.problem.vehicle.Vehicle;
|
||||||
|
import jsprit.core.problem.vehicle.VehicleImpl;
|
||||||
|
import jsprit.core.util.CostFactory;
|
||||||
|
import jsprit.core.util.Solutions;
|
||||||
|
import junit.framework.Assert;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by schroeder on 22/07/15.
|
||||||
|
*/
|
||||||
|
public class VariableDepartureAndWaitingTime_IT {
|
||||||
|
|
||||||
|
static interface AlgorithmFactory {
|
||||||
|
VehicleRoutingAlgorithm createAlgorithm(VehicleRoutingProblem vrp);
|
||||||
|
}
|
||||||
|
|
||||||
|
VehicleRoutingActivityCosts activityCosts;
|
||||||
|
|
||||||
|
AlgorithmFactory algorithmFactory;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void doBefore(){
|
||||||
|
activityCosts = new VehicleRoutingActivityCosts() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getActivityCost(TourActivity tourAct, double arrivalTime, Driver driver, Vehicle vehicle) {
|
||||||
|
return Math.max(0,tourAct.getTheoreticalEarliestOperationStartTime() - arrivalTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
algorithmFactory = new AlgorithmFactory() {
|
||||||
|
@Override
|
||||||
|
public VehicleRoutingAlgorithm createAlgorithm(final VehicleRoutingProblem vrp) {
|
||||||
|
StateManager stateManager = new StateManager(vrp);
|
||||||
|
stateManager.addStateUpdater(new UpdateDepartureTime(vrp.getTransportCosts()));
|
||||||
|
ConstraintManager constraintManager = new ConstraintManager(vrp,stateManager);
|
||||||
|
|
||||||
|
return Jsprit.Builder.newInstance(vrp)
|
||||||
|
.addCoreStateAndConstraintStuff(true)
|
||||||
|
.setStateAndConstraintManager(stateManager,constraintManager)
|
||||||
|
.setObjectiveFunction(new SolutionCostCalculator() {
|
||||||
|
@Override
|
||||||
|
public double getCosts(VehicleRoutingProblemSolution solution) {
|
||||||
|
SolutionAnalyser sa = new SolutionAnalyser(vrp, solution, new TransportDistance() {
|
||||||
|
@Override
|
||||||
|
public double getDistance(Location from, Location to) {
|
||||||
|
return vrp.getTransportCosts().getTransportCost(from, to, 0., null, null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return sa.getWaitingTime() + sa.getDistance();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.buildAlgorithm();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void plainSetupShouldWork(){
|
||||||
|
VehicleImpl v = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance(0,0)).build();
|
||||||
|
Service s1 = Service.Builder.newInstance("s1").setLocation(Location.newInstance(10,0)).build();
|
||||||
|
Service s2 = Service.Builder.newInstance("s2").setLocation(Location.newInstance(20,0)).build();
|
||||||
|
VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance()
|
||||||
|
.addJob(s1).addJob(s2).addVehicle(v)
|
||||||
|
.setFleetSize(VehicleRoutingProblem.FleetSize.FINITE)
|
||||||
|
.setRoutingCost(CostFactory.createManhattanCosts())
|
||||||
|
.setActivityCosts(activityCosts)
|
||||||
|
.build();
|
||||||
|
VehicleRoutingAlgorithm vra = algorithmFactory.createAlgorithm(vrp);
|
||||||
|
VehicleRoutingProblemSolution solution = Solutions.bestOf(vra.searchSolutions());
|
||||||
|
Assert.assertEquals(40.,solution.getCost());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void withTimeWindowsShouldWork(){
|
||||||
|
VehicleImpl v = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance(0,0)).build();
|
||||||
|
Service s1 = Service.Builder.newInstance("s1").setTimeWindow(TimeWindow.newInstance(1010,1100)).setLocation(Location.newInstance(10,0)).build();
|
||||||
|
Service s2 = Service.Builder.newInstance("s2").setTimeWindow(TimeWindow.newInstance(1020,1100)).setLocation(Location.newInstance(20,0)).build();
|
||||||
|
final VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance()
|
||||||
|
.addJob(s1).addJob(s2).addVehicle(v)
|
||||||
|
.setFleetSize(VehicleRoutingProblem.FleetSize.FINITE)
|
||||||
|
.setRoutingCost(CostFactory.createManhattanCosts())
|
||||||
|
.setActivityCosts(activityCosts)
|
||||||
|
.build();
|
||||||
|
VehicleRoutingAlgorithm vra = algorithmFactory.createAlgorithm(vrp);
|
||||||
|
VehicleRoutingProblemSolution solution = Solutions.bestOf(vra.searchSolutions());
|
||||||
|
Assert.assertEquals(40.+1000.,solution.getCost());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void variableDepartureShouldWork(){
|
||||||
|
VehicleImpl v = VehicleImpl.Builder.newInstance("v").setHasVariableDepartureTime(true).setStartLocation(Location.newInstance(0, 0)).build();
|
||||||
|
Service s1 = Service.Builder.newInstance("s1").setTimeWindow(TimeWindow.newInstance(1010,1100)).setLocation(Location.newInstance(10,0)).build();
|
||||||
|
Service s2 = Service.Builder.newInstance("s2").setTimeWindow(TimeWindow.newInstance(1020,1100)).setLocation(Location.newInstance(20,0)).build();
|
||||||
|
final VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance()
|
||||||
|
.addJob(s1).addJob(s2).addVehicle(v)
|
||||||
|
.setFleetSize(VehicleRoutingProblem.FleetSize.FINITE)
|
||||||
|
.setRoutingCost(CostFactory.createManhattanCosts())
|
||||||
|
.setActivityCosts(activityCosts)
|
||||||
|
.build();
|
||||||
|
VehicleRoutingAlgorithm vra = algorithmFactory.createAlgorithm(vrp);
|
||||||
|
VehicleRoutingProblemSolution solution = Solutions.bestOf(vra.searchSolutions());
|
||||||
|
Assert.assertEquals(40.,solution.getCost());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void variableDepartureShouldWork2(){
|
||||||
|
VehicleImpl v = VehicleImpl.Builder.newInstance("v").setHasVariableDepartureTime(true).setStartLocation(Location.newInstance(0, 0)).build();
|
||||||
|
Service s1 = Service.Builder.newInstance("s1").setTimeWindow(TimeWindow.newInstance(1010,1100)).setLocation(Location.newInstance(10,0)).build();
|
||||||
|
Service s2 = Service.Builder.newInstance("s2").setTimeWindow(TimeWindow.newInstance(1020,1100)).setLocation(Location.newInstance(20,0)).build();
|
||||||
|
Service s3 = Service.Builder.newInstance("s3").setTimeWindow(TimeWindow.newInstance(1020,1100)).setLocation(Location.newInstance(15,0)).build();
|
||||||
|
final VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance()
|
||||||
|
.addJob(s1).addJob(s2).addVehicle(v)
|
||||||
|
.setFleetSize(VehicleRoutingProblem.FleetSize.FINITE)
|
||||||
|
.setRoutingCost(CostFactory.createManhattanCosts())
|
||||||
|
.setActivityCosts(activityCosts)
|
||||||
|
.build();
|
||||||
|
VehicleRoutingAlgorithm vra = algorithmFactory.createAlgorithm(vrp);
|
||||||
|
VehicleRoutingProblemSolution solution = Solutions.bestOf(vra.searchSolutions());
|
||||||
|
Assert.assertEquals(40.,solution.getCost());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,97 @@
|
||||||
|
package jsprit.core.algorithm.state;
|
||||||
|
|
||||||
|
import jsprit.core.problem.Location;
|
||||||
|
import jsprit.core.problem.cost.VehicleRoutingTransportCosts;
|
||||||
|
import jsprit.core.problem.job.Service;
|
||||||
|
import jsprit.core.problem.solution.route.VehicleRoute;
|
||||||
|
import jsprit.core.problem.solution.route.activity.TimeWindow;
|
||||||
|
import jsprit.core.problem.vehicle.VehicleImpl;
|
||||||
|
import jsprit.core.util.CostFactory;
|
||||||
|
import junit.framework.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by schroeder on 22/07/15.
|
||||||
|
*/
|
||||||
|
public class UpdateDepartureTimeTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenNoTimeWindow_departureTimeShouldBeEarliestStartTime(){
|
||||||
|
VehicleRoutingTransportCosts routingCosts = CostFactory.createManhattanCosts();
|
||||||
|
VehicleImpl v = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance(0,0)).build();
|
||||||
|
Service s = Service.Builder.newInstance("s").setLocation(Location.newInstance(10,0)).build();
|
||||||
|
VehicleRoute route = VehicleRoute.Builder.newInstance(v).addService(s).build();
|
||||||
|
|
||||||
|
UpdateDepartureTime udt = new UpdateDepartureTime(routingCosts);
|
||||||
|
udt.visit(route);
|
||||||
|
|
||||||
|
Assert.assertEquals(0.,route.getDepartureTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenNoTimeWindow_departureTimeShouldBeEarliestStartTime2(){
|
||||||
|
VehicleRoutingTransportCosts routingCosts = CostFactory.createManhattanCosts();
|
||||||
|
VehicleImpl v = VehicleImpl.Builder.newInstance("v").setEarliestStart(10).setStartLocation(Location.newInstance(0, 0)).build();
|
||||||
|
Service s = Service.Builder.newInstance("s").setLocation(Location.newInstance(10,0)).build();
|
||||||
|
VehicleRoute route = VehicleRoute.Builder.newInstance(v).addService(s).build();
|
||||||
|
|
||||||
|
UpdateDepartureTime udt = new UpdateDepartureTime(routingCosts);
|
||||||
|
udt.visit(route);
|
||||||
|
|
||||||
|
Assert.assertEquals(10.,route.getDepartureTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenTimeWindowAndNoWaitingTime_departureTimeShouldBeEarliestStartTime1(){
|
||||||
|
VehicleRoutingTransportCosts routingCosts = CostFactory.createManhattanCosts();
|
||||||
|
VehicleImpl v = VehicleImpl.Builder.newInstance("v").setEarliestStart(0).setStartLocation(Location.newInstance(0,0)).build();
|
||||||
|
Service s = Service.Builder.newInstance("s").setTimeWindow(TimeWindow.newInstance(5,20)).setLocation(Location.newInstance(10, 0)).build();
|
||||||
|
VehicleRoute route = VehicleRoute.Builder.newInstance(v).addService(s).build();
|
||||||
|
|
||||||
|
UpdateDepartureTime udt = new UpdateDepartureTime(routingCosts);
|
||||||
|
udt.visit(route);
|
||||||
|
|
||||||
|
Assert.assertEquals(0.,route.getDepartureTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenTimeWindowAndNoWaitingTime_departureTimeShouldBeEarliestStartTime2(){
|
||||||
|
VehicleRoutingTransportCosts routingCosts = CostFactory.createManhattanCosts();
|
||||||
|
VehicleImpl v = VehicleImpl.Builder.newInstance("v").setEarliestStart(10).setStartLocation(Location.newInstance(0,0)).build();
|
||||||
|
Service s = Service.Builder.newInstance("s").setTimeWindow(TimeWindow.newInstance(5,20)).setLocation(Location.newInstance(10, 0)).build();
|
||||||
|
VehicleRoute route = VehicleRoute.Builder.newInstance(v).addService(s).build();
|
||||||
|
|
||||||
|
UpdateDepartureTime udt = new UpdateDepartureTime(routingCosts);
|
||||||
|
udt.visit(route);
|
||||||
|
|
||||||
|
Assert.assertEquals(10.,route.getDepartureTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenTimeWindowAndWaitingTime_departureTimeShouldChange(){
|
||||||
|
VehicleRoutingTransportCosts routingCosts = CostFactory.createManhattanCosts();
|
||||||
|
VehicleImpl v = VehicleImpl.Builder.newInstance("v").setEarliestStart(0)
|
||||||
|
.setHasVariableDepartureTime(true)
|
||||||
|
.setStartLocation(Location.newInstance(0,0)).build();
|
||||||
|
Service s = Service.Builder.newInstance("s").setTimeWindow(TimeWindow.newInstance(15,20)).setLocation(Location.newInstance(10, 0)).build();
|
||||||
|
VehicleRoute route = VehicleRoute.Builder.newInstance(v).addService(s).build();
|
||||||
|
|
||||||
|
UpdateDepartureTime udt = new UpdateDepartureTime(routingCosts);
|
||||||
|
udt.visit(route);
|
||||||
|
|
||||||
|
Assert.assertEquals(5.,route.getDepartureTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenTimeWindowAndWaitingTime_departureTimeShouldChange2(){
|
||||||
|
VehicleRoutingTransportCosts routingCosts = CostFactory.createManhattanCosts();
|
||||||
|
VehicleImpl v = VehicleImpl.Builder.newInstance("v").setHasVariableDepartureTime(true).setEarliestStart(5).setStartLocation(Location.newInstance(0,0)).build();
|
||||||
|
Service s = Service.Builder.newInstance("s").setTimeWindow(TimeWindow.newInstance(18,20)).setLocation(Location.newInstance(10, 0)).build();
|
||||||
|
VehicleRoute route = VehicleRoute.Builder.newInstance(v).addService(s).build();
|
||||||
|
|
||||||
|
UpdateDepartureTime udt = new UpdateDepartureTime(routingCosts);
|
||||||
|
udt.visit(route);
|
||||||
|
|
||||||
|
Assert.assertEquals(8.,route.getDepartureTime());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -221,5 +221,15 @@ public class VehicleImplTest {
|
||||||
assertFalse(v.getSkills().containsSkill("ScrewDriver"));
|
assertFalse(v.getSkills().containsSkill("ScrewDriver"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenSettingVariableDeparture_itShouldBeSet(){
|
||||||
|
VehicleImpl v = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance("loc")).setHasVariableDepartureTime(true).build();
|
||||||
|
assertTrue(v.hasVariableDepartureTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void defaultOfHasVariableDepartureShouldBeFalse(){
|
||||||
|
VehicleImpl v = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance("loc")).build();
|
||||||
|
assertFalse(v.hasVariableDepartureTime());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ package jsprit.examples;
|
||||||
|
|
||||||
import jsprit.analysis.toolbox.Plotter;
|
import jsprit.analysis.toolbox.Plotter;
|
||||||
import jsprit.core.algorithm.VehicleRoutingAlgorithm;
|
import jsprit.core.algorithm.VehicleRoutingAlgorithm;
|
||||||
import jsprit.core.algorithm.io.VehicleRoutingAlgorithms;
|
import jsprit.core.algorithm.box.Jsprit;
|
||||||
import jsprit.core.problem.Location;
|
import jsprit.core.problem.Location;
|
||||||
import jsprit.core.problem.VehicleRoutingProblem;
|
import jsprit.core.problem.VehicleRoutingProblem;
|
||||||
import jsprit.core.problem.VehicleRoutingProblem.FleetSize;
|
import jsprit.core.problem.VehicleRoutingProblem.FleetSize;
|
||||||
|
|
@ -98,7 +98,7 @@ public class CostMatrixExample {
|
||||||
VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance().setFleetSize(FleetSize.INFINITE).setRoutingCost(costMatrix)
|
VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance().setFleetSize(FleetSize.INFINITE).setRoutingCost(costMatrix)
|
||||||
.addVehicle(vehicle).addJob(s1).addJob(s2).addJob(s3).build();
|
.addVehicle(vehicle).addJob(s1).addJob(s2).addJob(s3).build();
|
||||||
|
|
||||||
VehicleRoutingAlgorithm vra = VehicleRoutingAlgorithms.readAndCreateAlgorithm(vrp, "input/fastAlgo.xml");
|
VehicleRoutingAlgorithm vra = Jsprit.createAlgorithm(vrp);
|
||||||
|
|
||||||
Collection<VehicleRoutingProblemSolution> solutions = vra.searchSolutions();
|
Collection<VehicleRoutingProblemSolution> solutions = vra.searchSolutions();
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue