From 5399749cefa3697678b62d6f3ec849ea8c2350ae Mon Sep 17 00:00:00 2001 From: oblonski <4sschroeder@gmail.com> Date: Sun, 23 Mar 2014 19:53:43 +0100 Subject: [PATCH] add problem modeling capabilities --- .../VehicleRoutingAlgorithmBuilder.java | 12 +++++ .../recreate/DellAmicoFixCostCalculator.java | 46 +++++++++++++++++ ...nsertionConsideringFixCostsCalculator.java | 26 +++++++--- .../VariableTransportCostCalculator.java | 49 +++++++++++++++++++ .../examples/TransportOfDisabledPeople.java | 27 ++++++++++ 5 files changed, 152 insertions(+), 8 deletions(-) create mode 100644 jsprit-core/src/main/java/jsprit/core/algorithm/VehicleRoutingAlgorithmBuilder.java create mode 100644 jsprit-core/src/main/java/jsprit/core/algorithm/recreate/DellAmicoFixCostCalculator.java create mode 100644 jsprit-core/src/main/java/jsprit/core/algorithm/recreate/VariableTransportCostCalculator.java diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/VehicleRoutingAlgorithmBuilder.java b/jsprit-core/src/main/java/jsprit/core/algorithm/VehicleRoutingAlgorithmBuilder.java new file mode 100644 index 00000000..834049f9 --- /dev/null +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/VehicleRoutingAlgorithmBuilder.java @@ -0,0 +1,12 @@ +package jsprit.core.algorithm; + +import jsprit.core.problem.VehicleRoutingProblem; + +public class VehicleRoutingAlgorithmBuilder { + + public VehicleRoutingAlgorithmBuilder(VehicleRoutingProblem problem, String algorithmConfig) { + + } + + +} diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/DellAmicoFixCostCalculator.java b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/DellAmicoFixCostCalculator.java new file mode 100644 index 00000000..de3fe4cd --- /dev/null +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/DellAmicoFixCostCalculator.java @@ -0,0 +1,46 @@ +package jsprit.core.algorithm.recreate; + +import java.util.Collection; + +import jsprit.core.algorithm.recreate.listener.InsertionStartsListener; +import jsprit.core.algorithm.recreate.listener.JobInsertedListener; +import jsprit.core.problem.constraint.SoftRouteConstraint; +import jsprit.core.problem.job.Job; +import jsprit.core.problem.misc.JobInsertionContext; +import jsprit.core.problem.solution.route.VehicleRoute; +import jsprit.core.problem.solution.route.state.RouteAndActivityStateGetter; + +public class DellAmicoFixCostCalculator implements SoftRouteConstraint, InsertionStartsListener, JobInsertedListener{ + + private int nuOfJobsToRecreate; + + private final JobInsertionConsideringFixCostsCalculator calculator; + + private final int nuOfJobs; + + public DellAmicoFixCostCalculator(final int nuOfJobs, final RouteAndActivityStateGetter stateGetter) { + super(); + this.nuOfJobs=nuOfJobs; + calculator = new JobInsertionConsideringFixCostsCalculator(null, stateGetter); + } + + @Override + public double getCosts(JobInsertionContext insertionContext) {// TODO Auto-generated method stub + return calculator.getCosts(insertionContext); + } + + @Override + public void informInsertionStarts(Collection routes, Collection unassignedJobs) { + this.nuOfJobsToRecreate = unassignedJobs.size(); + double completenessRatio = (1-((double)nuOfJobsToRecreate/(double)nuOfJobs)); + calculator.setSolutionCompletenessRatio(completenessRatio); + } + + @Override + public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) { + nuOfJobsToRecreate--; + double completenessRatio = (1-((double)nuOfJobsToRecreate/(double)nuOfJobs)); + calculator.setSolutionCompletenessRatio(completenessRatio); + } + +} diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/JobInsertionConsideringFixCostsCalculator.java b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/JobInsertionConsideringFixCostsCalculator.java index b01bd7a5..3fb54f1d 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/JobInsertionConsideringFixCostsCalculator.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/JobInsertionConsideringFixCostsCalculator.java @@ -18,8 +18,10 @@ package jsprit.core.algorithm.recreate; import jsprit.core.algorithm.recreate.InsertionData.NoInsertionFound; import jsprit.core.problem.Capacity; +import jsprit.core.problem.constraint.SoftRouteConstraint; import jsprit.core.problem.driver.Driver; import jsprit.core.problem.job.Job; +import jsprit.core.problem.misc.JobInsertionContext; import jsprit.core.problem.solution.route.VehicleRoute; import jsprit.core.problem.solution.route.state.RouteAndActivityStateGetter; import jsprit.core.problem.solution.route.state.StateFactory; @@ -28,10 +30,7 @@ import jsprit.core.problem.vehicle.VehicleImpl.NoVehicle; import org.apache.log4j.Logger; - - - -final class JobInsertionConsideringFixCostsCalculator implements JobInsertionCostsCalculator{ +final class JobInsertionConsideringFixCostsCalculator implements JobInsertionCostsCalculator, SoftRouteConstraint{ private static final Logger logger = Logger.getLogger(JobInsertionConsideringFixCostsCalculator.class); @@ -52,10 +51,7 @@ final class JobInsertionConsideringFixCostsCalculator implements JobInsertionCos @Override public InsertionData getInsertionData(final VehicleRoute currentRoute, final Job jobToInsert, final Vehicle newVehicle, double newVehicleDepartureTime, final Driver newDriver, final double bestKnownPrice) { - double relFixCost = getDeltaRelativeFixCost(currentRoute, newVehicle, jobToInsert); - double absFixCost = getDeltaAbsoluteFixCost(currentRoute, newVehicle, jobToInsert); - double deltaFixCost = (1-solution_completeness_ratio)*relFixCost + solution_completeness_ratio*absFixCost; - double fixcost_contribution = weight_deltaFixCost*solution_completeness_ratio*deltaFixCost; + double fixcost_contribution = getFixCostContribution(currentRoute,jobToInsert, newVehicle); if(fixcost_contribution > bestKnownPrice){ return InsertionData.createEmptyInsertionData(); } @@ -68,6 +64,15 @@ final class JobInsertionConsideringFixCostsCalculator implements JobInsertionCos insertionData.setVehicleDepartureTime(newVehicleDepartureTime); return insertionData; } + + private double getFixCostContribution(final VehicleRoute currentRoute, + final Job jobToInsert, final Vehicle newVehicle) { + double relFixCost = getDeltaRelativeFixCost(currentRoute, newVehicle, jobToInsert); + double absFixCost = getDeltaAbsoluteFixCost(currentRoute, newVehicle, jobToInsert); + double deltaFixCost = (1-solution_completeness_ratio)*relFixCost + solution_completeness_ratio*absFixCost; + double fixcost_contribution = weight_deltaFixCost*solution_completeness_ratio*deltaFixCost; + return fixcost_contribution; + } public void setWeightOfFixCost(double weight){ weight_deltaFixCost = weight; @@ -120,4 +125,9 @@ final class JobInsertionConsideringFixCostsCalculator implements JobInsertionCos return stateGetter.getRouteState(route, StateFactory.MAXLOAD, Capacity.class); } + @Override + public double getCosts(JobInsertionContext insertionContext) { + return getFixCostContribution(insertionContext.getRoute(), insertionContext.getJob(), insertionContext.getNewVehicle()); + } + } diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/VariableTransportCostCalculator.java b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/VariableTransportCostCalculator.java new file mode 100644 index 00000000..748ec22e --- /dev/null +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/VariableTransportCostCalculator.java @@ -0,0 +1,49 @@ +package jsprit.core.algorithm.recreate; + +import jsprit.core.problem.constraint.SoftActivityConstraint; +import jsprit.core.problem.cost.VehicleRoutingTransportCosts; +import jsprit.core.problem.misc.JobInsertionContext; +import jsprit.core.problem.solution.route.activity.End; +import jsprit.core.problem.solution.route.activity.TourActivity; +import jsprit.core.util.CalculationUtils; + +public class VariableTransportCostCalculator implements SoftActivityConstraint{ + + private VehicleRoutingTransportCosts routingCosts; + + public VariableTransportCostCalculator(VehicleRoutingTransportCosts routingCosts) { + super(); + this.routingCosts = routingCosts; + } + + @Override + public double getCosts(JobInsertionContext iFacts, TourActivity prevAct,TourActivity newAct, TourActivity nextAct, double depTimeAtPrevAct) { + double tp_costs_prevAct_newAct = routingCosts.getTransportCost(prevAct.getLocationId(), newAct.getLocationId(), depTimeAtPrevAct, iFacts.getNewDriver(), iFacts.getNewVehicle()); + double tp_time_prevAct_newAct = routingCosts.getTransportTime(prevAct.getLocationId(), newAct.getLocationId(), depTimeAtPrevAct, iFacts.getNewDriver(), iFacts.getNewVehicle()); + + double newAct_arrTime = depTimeAtPrevAct + tp_time_prevAct_newAct; + double newAct_endTime = CalculationUtils.getActivityEndTime(newAct_arrTime, newAct); + + //open routes + if(nextAct instanceof End){ + if(!iFacts.getNewVehicle().isReturnToDepot()){ + return tp_costs_prevAct_newAct; + } + } + + double tp_costs_newAct_nextAct = routingCosts.getTransportCost(newAct.getLocationId(), nextAct.getLocationId(), newAct_endTime, iFacts.getNewDriver(), iFacts.getNewVehicle()); + double totalCosts = tp_costs_prevAct_newAct + tp_costs_newAct_nextAct; + + double oldCosts; + if(iFacts.getRoute().isEmpty()){ + double tp_costs_prevAct_nextAct = routingCosts.getTransportCost(prevAct.getLocationId(), nextAct.getLocationId(), depTimeAtPrevAct, iFacts.getNewDriver(), iFacts.getNewVehicle()); + oldCosts = tp_costs_prevAct_nextAct; + } + else{ + double tp_costs_prevAct_nextAct = routingCosts.getTransportCost(prevAct.getLocationId(), nextAct.getLocationId(), prevAct.getEndTime(), iFacts.getRoute().getDriver(), iFacts.getRoute().getVehicle()); + oldCosts = tp_costs_prevAct_nextAct; + } + return totalCosts - oldCosts; + } + +} diff --git a/jsprit-examples/src/main/java/jsprit/examples/TransportOfDisabledPeople.java b/jsprit-examples/src/main/java/jsprit/examples/TransportOfDisabledPeople.java index da26e387..49bc1ae7 100644 --- a/jsprit-examples/src/main/java/jsprit/examples/TransportOfDisabledPeople.java +++ b/jsprit-examples/src/main/java/jsprit/examples/TransportOfDisabledPeople.java @@ -7,13 +7,18 @@ import jsprit.analysis.toolbox.GraphStreamViewer.Label; import jsprit.analysis.toolbox.Plotter; import jsprit.analysis.toolbox.SolutionPrinter; import jsprit.core.algorithm.VehicleRoutingAlgorithm; +import jsprit.core.algorithm.VehicleRoutingAlgorithmBuilder; import jsprit.core.algorithm.io.VehicleRoutingAlgorithms; +import jsprit.core.algorithm.recreate.DellAmicoFixCostCalculator; +import jsprit.core.algorithm.recreate.VariableTransportCostCalculator; +import jsprit.core.algorithm.state.StateManager; import jsprit.core.algorithm.termination.IterationWithoutImprovementTermination; import jsprit.core.problem.VehicleRoutingProblem; import jsprit.core.problem.VehicleRoutingProblem.FleetSize; import jsprit.core.problem.constraint.HardRouteStateLevelConstraint; import jsprit.core.problem.job.Shipment; import jsprit.core.problem.misc.JobInsertionContext; +import jsprit.core.problem.solution.SolutionCostCalculator; import jsprit.core.problem.solution.VehicleRoutingProblemSolution; import jsprit.core.problem.vehicle.Vehicle; import jsprit.core.problem.vehicle.VehicleImpl; @@ -21,6 +26,7 @@ import jsprit.core.problem.vehicle.VehicleImpl.Builder; import jsprit.core.problem.vehicle.VehicleType; import jsprit.core.problem.vehicle.VehicleTypeImpl; import jsprit.core.util.Coordinate; +import jsprit.core.util.CrowFlyCosts; import jsprit.core.util.Solutions; import jsprit.util.Examples; @@ -131,14 +137,35 @@ public class TransportOfDisabledPeople { return true; } }; + + CrowFlyCosts crowFlyCosts = new CrowFlyCosts(vrpBuilder.getLocations()); + StateManager stateManager = new StateManager(crowFlyCosts); + //add the constraint to the problem vrpBuilder.addConstraint(wheelchair_bus_passenger_pickup_constraint); + vrpBuilder.addConstraint(new DellAmicoFixCostCalculator(vrpBuilder.getAddedJobs().size(), stateManager)); + vrpBuilder.addConstraint(new VariableTransportCostCalculator(crowFlyCosts)); + SolutionCostCalculator objectiveFunction = new SolutionCostCalculator() { + + @Override + public double getCosts(VehicleRoutingProblemSolution solution) { + // TODO Auto-generated method stub + return 0; + } + }; //build the problem VehicleRoutingProblem problem = vrpBuilder.build(); + VehicleRoutingAlgorithmBuilder algorithmBuilder = new VehicleRoutingAlgorithmBuilder(problem, "input/algorithmConfig_noVehicleSwitch.xml"); + algorithmBuilder.setObjectiveFunction(objectiveFunction); + algorithmBuilder.setStateManager(stateManager); + algorithmBuilder.addCoreConstraints(); + algorithmBuilder.addVariableCostCalculator(); + algorithmBuilder.addFixCostCalculator(); + VehicleRoutingAlgorithm vra = algorithmBuilder.build(); /* * get a sample algorithm. *