From 1075e385044b2ec15c61cec5ac18e12ee12dd308 Mon Sep 17 00:00:00 2001 From: oblonski Date: Sun, 13 Dec 2015 19:55:32 +0100 Subject: [PATCH] mtw --- .../recreate/ServiceInsertionCalculator.java | 38 +++--- .../ruin/NearestNeighborhoodIterator.java | 4 +- ...vityStartsAsSoonAsNextTimeWindowOpens.java | 28 ++-- .../algorithm/state/UpdateActivityTimes.java | 4 + ...VehicleDependentTimeWindowConstraints.java | 16 +-- .../route/activity/DeliverService.java | 2 + .../route/activity/PickupService.java | 2 + .../route/activity/ServiceActivity.java | 2 + .../examples/MultipleTimeWindowExample.java | 124 ++++++++++++++++++ 9 files changed, 177 insertions(+), 43 deletions(-) create mode 100644 jsprit-examples/src/main/java/jsprit/examples/MultipleTimeWindowExample.java diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/ServiceInsertionCalculator.java b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/ServiceInsertionCalculator.java index 7190136c..def15202 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/ServiceInsertionCalculator.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/ServiceInsertionCalculator.java @@ -133,27 +133,27 @@ final class ServiceInsertionCalculator implements JobInsertionCostsCalculator { } double actArrTime = prevActStartTime + transportCosts.getTransportTime(prevAct.getLocation(),deliveryAct2Insert.getLocation(),prevActStartTime,newDriver,newVehicle); Collection timeWindows = service.getTimeWindows(actArrTime); - TimeWindow timeWindow = getNextTimeWindow(actArrTime,timeWindows); - if(timeWindow == null) break; +// TimeWindow timeWindow = getNextTimeWindow(actArrTime,timeWindows); +// if(timeWindow == null) break; boolean not_fulfilled_break = true; -// for(TimeWindow timeWindow : timeWindows) { - deliveryAct2Insert.setTheoreticalEarliestOperationStartTime(timeWindow.getStart()); - deliveryAct2Insert.setTheoreticalLatestOperationStartTime(timeWindow.getEnd()); - ConstraintsStatus status = hardActivityLevelConstraint.fulfilled(insertionContext, prevAct, deliveryAct2Insert, nextAct, prevActStartTime); - if (status.equals(ConstraintsStatus.FULFILLED)) { - //from job2insert induced costs at activity level - double additionalICostsAtActLevel = softActivityConstraint.getCosts(insertionContext, prevAct, deliveryAct2Insert, nextAct, prevActStartTime); - double additionalTransportationCosts = additionalTransportCostsCalculator.getCosts(insertionContext, prevAct, nextAct, deliveryAct2Insert, prevActStartTime); - if (additionalICostsAtRouteLevel + additionalICostsAtActLevel + additionalTransportationCosts < bestCost) { - bestCost = additionalICostsAtRouteLevel + additionalICostsAtActLevel + additionalTransportationCosts; - insertionIndex = actIndex; - bestTimeWindow = timeWindow; + for(TimeWindow timeWindow : timeWindows) { + deliveryAct2Insert.setTheoreticalEarliestOperationStartTime(timeWindow.getStart()); + deliveryAct2Insert.setTheoreticalLatestOperationStartTime(timeWindow.getEnd()); + ConstraintsStatus status = hardActivityLevelConstraint.fulfilled(insertionContext, prevAct, deliveryAct2Insert, nextAct, prevActStartTime); + if (status.equals(ConstraintsStatus.FULFILLED)) { + //from job2insert induced costs at activity level + double additionalICostsAtActLevel = softActivityConstraint.getCosts(insertionContext, prevAct, deliveryAct2Insert, nextAct, prevActStartTime); + double additionalTransportationCosts = additionalTransportCostsCalculator.getCosts(insertionContext, prevAct, nextAct, deliveryAct2Insert, prevActStartTime); + if (additionalICostsAtRouteLevel + additionalICostsAtActLevel + additionalTransportationCosts < bestCost) { + bestCost = additionalICostsAtRouteLevel + additionalICostsAtActLevel + additionalTransportationCosts; + insertionIndex = actIndex; + bestTimeWindow = timeWindow; + } + not_fulfilled_break = false; + } else if (status.equals(ConstraintsStatus.NOT_FULFILLED)) { + not_fulfilled_break = false; } - not_fulfilled_break = false; - } else if (status.equals(ConstraintsStatus.NOT_FULFILLED)) { - not_fulfilled_break = false; - } -// } + } if(not_fulfilled_break) break; double nextActArrTime = prevActStartTime + transportCosts.getTransportTime(prevAct.getLocation(), nextAct.getLocation(), prevActStartTime, newDriver, newVehicle); prevActStartTime = CalculationUtils.getActivityEndTime(nextActArrTime, nextAct); diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/ruin/NearestNeighborhoodIterator.java b/jsprit-core/src/main/java/jsprit/core/algorithm/ruin/NearestNeighborhoodIterator.java index 1bc5515b..2b7fda43 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/ruin/NearestNeighborhoodIterator.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/ruin/NearestNeighborhoodIterator.java @@ -29,8 +29,8 @@ class NearestNeighborhoodIterator implements Iterator { public boolean hasNext() { if (jobCount < nJobs) { boolean hasNext = jobIter.hasNext(); - if (!hasNext) - log.warn("more jobs are requested then iterator can iterate over. probably the number of neighbors memorized in JobNeighborhoods is too small"); +// if (!hasNext) +// log.warn("more jobs are requested then iterator can iterate over. probably the number of neighbors memorized in JobNeighborhoods is too small"); return hasNext; } return false; diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/state/ActivityStartsAsSoonAsNextTimeWindowOpens.java b/jsprit-core/src/main/java/jsprit/core/algorithm/state/ActivityStartsAsSoonAsNextTimeWindowOpens.java index fb824ec0..6905143f 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/state/ActivityStartsAsSoonAsNextTimeWindowOpens.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/state/ActivityStartsAsSoonAsNextTimeWindowOpens.java @@ -1,6 +1,5 @@ package jsprit.core.algorithm.state; -import jsprit.core.problem.solution.route.activity.TimeWindow; import jsprit.core.problem.solution.route.activity.TourActivity; /** @@ -10,19 +9,20 @@ public class ActivityStartsAsSoonAsNextTimeWindowOpens implements ActivityStartS @Override public double getActivityStartTime(TourActivity activity, double arrivalTime) { - TimeWindow last = null; - for(int i=activity.getTimeWindows().size()-1; i >= 0; i--){ - TimeWindow tw = activity.getTimeWindows().get(i); - if(tw.getStart() <= arrivalTime && tw.getEnd() >= arrivalTime){ - return arrivalTime; - } - else if(arrivalTime > tw.getEnd()){ - if(last != null) return last.getStart(); - else return arrivalTime; - } - last = tw; - } - return Math.max(arrivalTime,last.getStart()); + return Math.max(arrivalTime,activity.getTheoreticalEarliestOperationStartTime()); +// TimeWindow last = null; +// for(int i=activity.getTimeWindows().size()-1; i >= 0; i--){ +// TimeWindow tw = activity.getTimeWindows().get(i); +// if(tw.getStart() <= arrivalTime && tw.getEnd() >= arrivalTime){ +// return arrivalTime; +// } +// else if(arrivalTime > tw.getEnd()){ +// if(last != null) return last.getStart(); +// else return arrivalTime; +// } +// last = tw; +// } +// return Math.max(arrivalTime,last.getStart()); } } diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdateActivityTimes.java b/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdateActivityTimes.java index 175c8701..f4f13467 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdateActivityTimes.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdateActivityTimes.java @@ -66,6 +66,10 @@ public class UpdateActivityTimes implements ActivityVisitor, StateUpdater { timeTracker.visit(activity); activity.setArrTime(timeTracker.getActArrTime()); activity.setEndTime(timeTracker.getActEndTime()); + double theoreticalLatestOperationStartTime = activity.getTheoreticalLatestOperationStartTime(); + if(activity.getArrTime() > theoreticalLatestOperationStartTime){ + throw new IllegalStateException("arrTime > latestArrTime"); + } } @Override diff --git a/jsprit-core/src/main/java/jsprit/core/problem/constraint/VehicleDependentTimeWindowConstraints.java b/jsprit-core/src/main/java/jsprit/core/problem/constraint/VehicleDependentTimeWindowConstraints.java index d9bd2c97..10296012 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/constraint/VehicleDependentTimeWindowConstraints.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/constraint/VehicleDependentTimeWindowConstraints.java @@ -55,7 +55,7 @@ public class VehicleDependentTimeWindowConstraints implements HardActivityConstr double latestVehicleArrival = iFacts.getNewVehicle().getLatestArrival(); Double latestArrTimeAtNextAct; Location nextActLocation; - double nextAct_theoreticalLatestOperationStartTime = getLatestOperationStartTime(nextAct); +// double nextAct_theoreticalLatestOperationStartTime = getLatestOperationStartTime(nextAct); if (nextAct instanceof End) { latestArrTimeAtNextAct = latestVehicleArrival; @@ -84,14 +84,14 @@ public class VehicleDependentTimeWindowConstraints implements HardActivityConstr * |--- vehicle's operation time ---| * |--- prevAct or newAct or nextAct ---| */ - double prevAct_theoreticalEarliestOperationStartTime = getEarliestOperationStartTime(prevAct); - double newAct_theoreticalEarliestOperationStartTime = getEarliestOperationStartTime(newAct); +// double prevAct_theoreticalEarliestOperationStartTime = getEarliestOperationStartTime(prevAct); + double newAct_theoreticalEarliestOperationStartTime = newAct.getTheoreticalEarliestOperationStartTime(); // newAct.getTheoreticalEarliestOperationStartTime(); - double nextAct_theoreticalEarliestOperationStartTime = getEarliestOperationStartTime(nextAct); +// double nextAct_theoreticalEarliestOperationStartTime = getEarliestOperationStartTime(nextAct); // nextAct.getTheoreticalEarliestOperationStartTime(); if (latestVehicleArrival < prevAct.getTheoreticalEarliestOperationStartTime() || - latestVehicleArrival < newAct.getTheoreticalEarliestOperationStartTime() || + latestVehicleArrival < newAct_theoreticalEarliestOperationStartTime || latestVehicleArrival < nextAct.getTheoreticalEarliestOperationStartTime()) { return ConstraintsStatus.NOT_FULFILLED_BREAK; } @@ -102,9 +102,9 @@ public class VehicleDependentTimeWindowConstraints implements HardActivityConstr * |--- prevAct ---| * |--- newAct ---| */ - double newAct_theoreticalLatestOperationStartTime = getLatestOperationStartTime(newAct); + double newAct_theoreticalLatestOperationStartTime = newAct.getTheoreticalLatestOperationStartTime(); - if (newAct.getTheoreticalLatestOperationStartTime() < prevAct.getTheoreticalEarliestOperationStartTime()) { + if (newAct_theoreticalLatestOperationStartTime < prevAct.getTheoreticalEarliestOperationStartTime()) { return ConstraintsStatus.NOT_FULFILLED_BREAK; } @@ -122,7 +122,7 @@ public class VehicleDependentTimeWindowConstraints implements HardActivityConstr * |--- newAct ---| * |--- nextAct ---| */ - if(newAct_theoreticalEarliestOperationStartTime > nextAct_theoreticalLatestOperationStartTime){ + if(newAct_theoreticalEarliestOperationStartTime > nextAct.getTheoreticalLatestOperationStartTime()){ return ConstraintsStatus.NOT_FULFILLED; } // log.info("check insertion of " + newAct + " between " + prevAct + " and " + nextAct + ". prevActDepTime=" + prevActDepTime); diff --git a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/DeliverService.java b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/DeliverService.java index 5c668b6d..972bb0b6 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/DeliverService.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/DeliverService.java @@ -54,6 +54,8 @@ public final class DeliverService extends AbstractActivity implements DeliveryAc capacity = deliveryActivity.getSize(); setIndex(deliveryActivity.getIndex()); timeWindows = new ArrayList(delivery.getTimeWindows(0.)); + this.theoreticalEarliest = deliveryActivity.getTheoreticalEarliestOperationStartTime(); + this.theoreticalLatest = deliveryActivity.getTheoreticalLatestOperationStartTime(); } @Override diff --git a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/PickupService.java b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/PickupService.java index 03768933..13c5e977 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/PickupService.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/PickupService.java @@ -57,6 +57,8 @@ public final class PickupService extends AbstractActivity implements PickupActiv this.depTime = pickupActivity.getEndTime(); setIndex(pickupActivity.getIndex()); timeWindows = new ArrayList(pickup.getTimeWindows(0.)); + this.theoreticalEarliest = pickupActivity.getTheoreticalEarliestOperationStartTime(); + this.theoreticalLatest = pickupActivity.getTheoreticalLatestOperationStartTime(); } @Override diff --git a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/ServiceActivity.java b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/ServiceActivity.java index 33703b87..b7ef836b 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/ServiceActivity.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/ServiceActivity.java @@ -92,6 +92,8 @@ public class ServiceActivity extends AbstractActivity implements JobActivity { this.endTime = serviceActivity.getEndTime(); setIndex(serviceActivity.getIndex()); timeWindows = new ArrayList(serviceActivity.getTimeWindows()); + this.theoreticalEarliest = serviceActivity.getTheoreticalEarliestOperationStartTime(); + this.theoreticalLatest = serviceActivity.getTheoreticalLatestOperationStartTime(); } diff --git a/jsprit-examples/src/main/java/jsprit/examples/MultipleTimeWindowExample.java b/jsprit-examples/src/main/java/jsprit/examples/MultipleTimeWindowExample.java new file mode 100644 index 00000000..6ad57b16 --- /dev/null +++ b/jsprit-examples/src/main/java/jsprit/examples/MultipleTimeWindowExample.java @@ -0,0 +1,124 @@ +/******************************************************************************* + * 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 . + ******************************************************************************/ +package jsprit.examples; + +import jsprit.core.algorithm.VehicleRoutingAlgorithm; +import jsprit.core.algorithm.box.Jsprit; +import jsprit.core.problem.Location; +import jsprit.core.problem.VehicleRoutingProblem; +import jsprit.core.problem.job.Service; +import jsprit.core.problem.solution.VehicleRoutingProblemSolution; +import jsprit.core.problem.vehicle.VehicleImpl; +import jsprit.core.problem.vehicle.VehicleImpl.Builder; +import jsprit.core.problem.vehicle.VehicleType; +import jsprit.core.problem.vehicle.VehicleTypeImpl; +import jsprit.core.reporting.SolutionPrinter; +import jsprit.core.util.ManhattanCosts; +import jsprit.core.util.Solutions; + +import java.util.Collection; + + +public class MultipleTimeWindowExample { + + + public static void main(String[] args) { + + /* + * get a vehicle type-builder and build a type with the typeId "vehicleType" and one capacity dimension, i.e. weight, and capacity dimension value of 2 + */ + final int WEIGHT_INDEX = 0; + VehicleTypeImpl.Builder vehicleTypeBuilder = VehicleTypeImpl.Builder.newInstance("vehicleType") + .addCapacityDimension(WEIGHT_INDEX, 10).setCostPerWaitingTime(1.); + VehicleType vehicleType = vehicleTypeBuilder.build(); + + /* + * get a vehicle-builder and build a vehicle located at (10,10) with type "vehicleType" + */ + Builder vehicleBuilder = Builder.newInstance("vehicle"); + vehicleBuilder.setStartLocation(Location.newInstance(0, 0)); + vehicleBuilder.setType(vehicleType); + VehicleImpl vehicle = vehicleBuilder.build(); + + /* + * build services at the required locations, each with a capacity-demand of 1. + */ + Service service1 = Service.Builder.newInstance("1") + .addTimeWindow(5, 10) + .addTimeWindow(20,35) + .addSizeDimension(WEIGHT_INDEX, 1).setLocation(Location.newInstance(10, 0)).build(); + + Service service2 = Service.Builder.newInstance("2") + .addSizeDimension(WEIGHT_INDEX, 1).setLocation(Location.newInstance(20, 0)).build(); + + Service service3 = Service.Builder.newInstance("3") + .addTimeWindow(5, 10) + .addTimeWindow(35, 40) + .addSizeDimension(WEIGHT_INDEX, 1).setLocation(Location.newInstance(30, 0)).build(); + + Service service4 = Service.Builder.newInstance("4") +// .addTimeWindow(5,10) + .addTimeWindow(20, 40) + .addTimeWindow(70, 80) + .addSizeDimension(WEIGHT_INDEX, 1).setLocation(Location.newInstance(40, 0)).build(); + + Service service5 = Service.Builder.newInstance("5") + .addTimeWindow(5,10) +// .addTimeWindow(20, 40) + .addTimeWindow(35,100) + .addSizeDimension(WEIGHT_INDEX, 1).setLocation(Location.newInstance(20, 0)).build(); + + + VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); + vrpBuilder.addVehicle(vehicle); + vrpBuilder.addJob(service1).addJob(service2) + .addJob(service3) + .addJob(service4) + .addJob(service5) + ; + vrpBuilder.setFleetSize(VehicleRoutingProblem.FleetSize.FINITE); + vrpBuilder.setRoutingCost(new ManhattanCosts()); + VehicleRoutingProblem problem = vrpBuilder.build(); + + /* + * get the algorithm out-of-the-box. + */ + VehicleRoutingAlgorithm algorithm = Jsprit.createAlgorithm(problem); + + /* + * and search a solution + */ + Collection solutions = algorithm.searchSolutions(); + + /* + * get the best + */ + VehicleRoutingProblemSolution bestSolution = Solutions.bestOf(solutions); + +// new VrpXMLWriter(problem, solutions).write("output/problem-with-solution.xml"); + + SolutionPrinter.print(problem, bestSolution, SolutionPrinter.Print.VERBOSE); + + /* + * plot + */ +// new Plotter(problem,bestSolution).setLabel(Plotter.Label.ID).plot("output/plot", "mtw"); + +// new GraphStreamViewer(problem, bestSolution).labelWith(Label.ID).setRenderDelay(200).display(); + } + +}