From 8aa27517af4b48577c4692b56505cc51e14393a7 Mon Sep 17 00:00:00 2001 From: oblonski <4sschroeder@gmail.com> Date: Tue, 26 Aug 2014 10:10:52 +0200 Subject: [PATCH] add example.AdditionalDistanceConstraintExample --- .../input/algorithmConfig_solomon.xml | 4 +- .../AdditionalDistanceConstraintExample.java | 168 ++++++++++++++++++ 2 files changed, 170 insertions(+), 2 deletions(-) create mode 100644 jsprit-examples/src/main/java/jsprit/examples/AdditionalDistanceConstraintExample.java diff --git a/jsprit-examples/input/algorithmConfig_solomon.xml b/jsprit-examples/input/algorithmConfig_solomon.xml index 12b98942..b34e133a 100755 --- a/jsprit-examples/input/algorithmConfig_solomon.xml +++ b/jsprit-examples/input/algorithmConfig_solomon.xml @@ -17,7 +17,7 @@ - + @@ -31,7 +31,7 @@ - + diff --git a/jsprit-examples/src/main/java/jsprit/examples/AdditionalDistanceConstraintExample.java b/jsprit-examples/src/main/java/jsprit/examples/AdditionalDistanceConstraintExample.java new file mode 100644 index 00000000..c5d803ad --- /dev/null +++ b/jsprit-examples/src/main/java/jsprit/examples/AdditionalDistanceConstraintExample.java @@ -0,0 +1,168 @@ +package jsprit.examples; + + +import jsprit.analysis.toolbox.Plotter; +import jsprit.core.algorithm.VehicleRoutingAlgorithm; +import jsprit.core.algorithm.VehicleRoutingAlgorithmBuilder; +import jsprit.core.algorithm.state.StateId; +import jsprit.core.algorithm.state.StateManager; +import jsprit.core.algorithm.state.StateUpdater; +import jsprit.core.problem.VehicleRoutingProblem; +import jsprit.core.problem.constraint.ConstraintManager; +import jsprit.core.problem.constraint.HardActivityStateLevelConstraint; +import jsprit.core.problem.io.VrpXMLReader; +import jsprit.core.problem.misc.JobInsertionContext; +import jsprit.core.problem.solution.VehicleRoutingProblemSolution; +import jsprit.core.problem.solution.route.VehicleRoute; +import jsprit.core.problem.solution.route.activity.ActivityVisitor; +import jsprit.core.problem.solution.route.activity.TourActivity; +import jsprit.core.reporting.SolutionPrinter; +import jsprit.core.util.Coordinate; +import jsprit.core.util.EuclideanDistanceCalculator; +import jsprit.core.util.Solutions; +import jsprit.core.util.VehicleRoutingTransportCostsMatrix; + +import java.util.Collection; + +//import jsprit.core.problem.solution.route.state.StateFactory; //v1.3.1 + +public class AdditionalDistanceConstraintExample { + + static class DistanceUpdater implements StateUpdater, ActivityVisitor { + + private final StateManager stateManager; + + private final VehicleRoutingTransportCostsMatrix costMatrix; + +// private final StateFactory.StateId distanceStateId; //v1.3.1 + private final StateId distanceStateId; //head of development - upcoming release + + private VehicleRoute vehicleRoute; + + private double distance = 0.; + + private TourActivity prevAct; + +// public DistanceUpdater(StateFactory.StateId distanceStateId, StateManager stateManager, VehicleRoutingTransportCostsMatrix costMatrix) { //v1.3.1 + public DistanceUpdater(StateId distanceStateId, StateManager stateManager, VehicleRoutingTransportCostsMatrix transportCosts) { //head of development - upcoming release (v1.4) + this.costMatrix = transportCosts; + this.stateManager = stateManager; + this.distanceStateId = distanceStateId; + } + + @Override + public void begin(VehicleRoute vehicleRoute) { + distance = 0.; + prevAct = vehicleRoute.getStart(); + this.vehicleRoute = vehicleRoute; + } + + @Override + public void visit(TourActivity tourActivity) { + distance += getDistance(prevAct,tourActivity); + prevAct = tourActivity; + } + + @Override + public void finish() { + distance += getDistance(prevAct,vehicleRoute.getEnd()); +// stateManager.putTypedRouteState(vehicleRoute,distanceStateId,Double.class,distance); //v1.3.1 + stateManager.putRouteState(vehicleRoute, distanceStateId, distance); //head of development - upcoming release (v1.4) + } + + double getDistance(TourActivity from, TourActivity to){ + return costMatrix.getDistance(from.getLocationId(), to.getLocationId()); + } + } + + static class DistanceConstraint implements HardActivityStateLevelConstraint { + + private final StateManager stateManager; + + private final VehicleRoutingTransportCostsMatrix costsMatrix; + + private final double maxDistance; + +// private final StateFactory.StateId distanceStateId; //v1.3.1 + private final StateId distanceStateId; //head of development - upcoming release (v1.4) + +// DistanceConstraint(double maxDistance, StateFactory.StateId distanceStateId, StateManager stateManager, VehicleRoutingTransportCostsMatrix costsMatrix) { //v1.3.1 + DistanceConstraint(double maxDistance, StateId distanceStateId, StateManager stateManager, VehicleRoutingTransportCostsMatrix transportCosts) { //head of development - upcoming release (v1.4) + this.costsMatrix = transportCosts; + this.maxDistance = maxDistance; + this.stateManager = stateManager; + this.distanceStateId = distanceStateId; + } + + @Override + public ConstraintsStatus fulfilled(JobInsertionContext context, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double v) { + double additionalDistance = getDistance(prevAct,newAct) + getDistance(newAct,nextAct) - getDistance(prevAct,nextAct); + Double routeDistance = stateManager.getRouteState(context.getRoute(), distanceStateId, Double.class); + if(routeDistance == null) routeDistance = 0.; + double newRouteDistance = routeDistance + additionalDistance; + if(newRouteDistance > maxDistance) { + return ConstraintsStatus.NOT_FULFILLED; + } + else return ConstraintsStatus.FULFILLED; + } + + double getDistance(TourActivity from, TourActivity to){ + return costsMatrix.getDistance(from.getLocationId(), to.getLocationId()); + } + + } + public static void main(String[] args) { + + //route length 618 + VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); + new VrpXMLReader(vrpBuilder).read("input/pickups_and_deliveries_solomon_r101_withoutTWs.xml"); + //builds a matrix based on euclidean distances; t_ij = euclidean(i,j) / 2; d_ij = euclidean(i,j); + VehicleRoutingTransportCostsMatrix costMatrix = createMatrix(vrpBuilder); + vrpBuilder.setRoutingCost(costMatrix); + VehicleRoutingProblem vrp = vrpBuilder.build(); + + VehicleRoutingAlgorithmBuilder vraBuilder = new VehicleRoutingAlgorithmBuilder(vrp,"input/algorithmConfig_solomon.xml"); + +// StateManager stateManager = new StateManager(vrp.getTransportCosts()); //v1.3.1 + StateManager stateManager = new StateManager(vrp); //head of development - upcoming release (v1.4) + +// StateFactory.StateId distanceStateId = StateFactory.createId("distance"); //v1.3.1 + StateId distanceStateId = stateManager.createStateId("distance"); //head of development - upcoming release (v1.4) + stateManager.addStateUpdater(new DistanceUpdater(distanceStateId, stateManager, costMatrix)); +// stateManager.updateLoadStates(); + + ConstraintManager constraintManager = new ConstraintManager(vrp,stateManager); + constraintManager.addConstraint(new DistanceConstraint(120.,distanceStateId,stateManager,costMatrix), ConstraintManager.Priority.CRITICAL); +// constraintManager.addLoadConstraint(); + +// vraBuilder.addCoreConstraints(); + vraBuilder.addDefaultCostCalculators(); + vraBuilder.setStateAndConstraintManager(stateManager,constraintManager); + + VehicleRoutingAlgorithm vra = vraBuilder.build(); +// vra.setNuOfIterations(250); //v1.3.1 + vra.setMaxIterations(250); //head of development - upcoming release (v1.4) + + Collection solutions = vra.searchSolutions(); + + SolutionPrinter.print(vrp, Solutions.bestOf(solutions), SolutionPrinter.Print.VERBOSE); + + new Plotter(vrp, Solutions.bestOf(solutions)).plot("output/plot","plot"); + } + + private static VehicleRoutingTransportCostsMatrix createMatrix(VehicleRoutingProblem.Builder vrpBuilder) { + VehicleRoutingTransportCostsMatrix.Builder matrixBuilder = VehicleRoutingTransportCostsMatrix.Builder.newInstance(true); + for(String from : vrpBuilder.getLocationMap().keySet()){ + for(String to : vrpBuilder.getLocationMap().keySet()){ + Coordinate fromCoord = vrpBuilder.getLocationMap().get(from); + Coordinate toCoord = vrpBuilder.getLocationMap().get(to); + double distance = EuclideanDistanceCalculator.calculateDistance(fromCoord, toCoord); + matrixBuilder.addTransportDistance(from,to,distance); + matrixBuilder.addTransportTime(from,to,(distance / 2.)); + } + } + return matrixBuilder.build(); + } + + +}