From 1919c05ceb8b1d0b096e0ae2190398c1792a7cbc Mon Sep 17 00:00:00 2001 From: oblonski Date: Wed, 23 Sep 2015 18:19:32 +0200 Subject: [PATCH] break feature --- .../jsprit/core/algorithm/box/Jsprit.java | 12 ++ .../core/algorithm/ruin/RuinBreaks.java | 2 +- .../java/jsprit/core/problem/job/Break.java | 8 +- .../core/problem/vehicle/VehicleImpl.java | 49 +---- .../core/problem/vehicle/VehicleImplTest.java | 185 ------------------ .../java/jsprit/examples/BreakExample.java | 25 ++- 6 files changed, 34 insertions(+), 247 deletions(-) diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/box/Jsprit.java b/jsprit-core/src/main/java/jsprit/core/algorithm/box/Jsprit.java index a64ebdcd..be52e916 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/box/Jsprit.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/box/Jsprit.java @@ -17,6 +17,7 @@ import jsprit.core.problem.constraint.ConstraintManager; import jsprit.core.problem.solution.SolutionCostCalculator; import jsprit.core.problem.solution.VehicleRoutingProblemSolution; import jsprit.core.problem.solution.route.VehicleRoute; +import jsprit.core.problem.solution.route.activity.BreakActivity; import jsprit.core.problem.solution.route.activity.TourActivity; import jsprit.core.problem.vehicle.FiniteFleetManagerFactory; import jsprit.core.problem.vehicle.InfiniteFleetManagerFactory; @@ -485,8 +486,10 @@ public class Jsprit { vra.addListener(noiseMaker); vra.addListener(noise); vra.addListener(clusters); + vra.addListener(new RuinBreaks()); handleExecutorShutdown(vra); vra.setMaxIterations(Integer.valueOf(properties.getProperty(Parameter.ITERATIONS.toString()))); + return vra; } @@ -546,15 +549,24 @@ public class Jsprit { @Override public double getCosts(VehicleRoutingProblemSolution solution) { double costs = 0.; + for (VehicleRoute route : solution.getRoutes()) { costs += route.getVehicle().getType().getVehicleCostParams().fix; + boolean hasBreak = false; TourActivity prevAct = route.getStart(); for (TourActivity act : route.getActivities()) { + if(act instanceof BreakActivity) hasBreak = true; costs += vrp.getTransportCosts().getTransportCost(prevAct.getLocation(), act.getLocation(), prevAct.getEndTime(), route.getDriver(), route.getVehicle()); costs += vrp.getActivityCosts().getActivityCost(act, act.getArrTime(), route.getDriver(), route.getVehicle()); prevAct = act; } costs += vrp.getTransportCosts().getTransportCost(prevAct.getLocation(), route.getEnd().getLocation(), prevAct.getEndTime(), route.getDriver(), route.getVehicle()); + if(route.getVehicle().getBreak() != null){ + if(!hasBreak){ + //break defined but not assigned penalty + costs += maxCosts * 2; + } + } } costs += solution.getUnassignedJobs().size() * maxCosts * 2; return costs; diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/ruin/RuinBreaks.java b/jsprit-core/src/main/java/jsprit/core/algorithm/ruin/RuinBreaks.java index f3f56f75..aaf4540a 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/ruin/RuinBreaks.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/ruin/RuinBreaks.java @@ -25,7 +25,7 @@ public class RuinBreaks implements RuinListener { Break aBreak = r.getVehicle().getBreak(); if(aBreak != null){ r.getTourActivities().removeJob(aBreak); - logger.trace("ruin: " + aBreak.getId()); + logger.trace("ruin: {}",aBreak.getId()); unassignedJobs.add(aBreak); } } diff --git a/jsprit-core/src/main/java/jsprit/core/problem/job/Break.java b/jsprit-core/src/main/java/jsprit/core/problem/job/Break.java index 4295eeaf..2664dd25 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/job/Break.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/job/Break.java @@ -11,7 +11,7 @@ * 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 + * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . ******************************************************************************/ package jsprit.core.problem.job; @@ -22,13 +22,13 @@ import jsprit.core.problem.Skills; /** * Pickup extends Service and is intended to model a Service where smth is LOADED (i.e. picked up) to a transport unit. - * + * * @author schroeder * */ public class Break extends Service { - public static class Builder extends Service.Builder { + public static class Builder extends Service.Builder { /** * Returns a new instance of builder that builds a pickup. @@ -76,5 +76,5 @@ public class Break extends Service { public boolean hasVariableLocation(){ return variableLocation; } - + } diff --git a/jsprit-core/src/main/java/jsprit/core/problem/vehicle/VehicleImpl.java b/jsprit-core/src/main/java/jsprit/core/problem/vehicle/VehicleImpl.java index 2d882477..3172faac 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/vehicle/VehicleImpl.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/vehicle/VehicleImpl.java @@ -88,11 +88,12 @@ public class VehicleImpl extends AbstractVehicle { public Skills getSkills() { return null; } - } + @Override public Break getBreak() { return null; } - } + + } /** * Builder that builds the vehicle. @@ -179,28 +180,6 @@ public class VehicleImpl extends AbstractVehicle { return this; } - /** - * Sets earliest-start of vehicle which should be the lower bound of the vehicle's departure times. - * - * @param earliest_startTime the earliest start time / departure time of the vehicle at its start location - * @return this builder - */ - public Builder setEarliestStart(double earliest_startTime){ - this.earliestStart = earliest_startTime; - return this; - } - - /** - * Sets the latest arrival at vehicle's end-location which is the upper bound of the vehicle's arrival times. - * - * @param latest_arrTime the latest arrival time of the vehicle at its end location - * @return this builder - */ - public Builder setLatestArrival(double latest_arrTime){ - this.latestArrival = latest_arrTime; - return this; - } - /** * Sets earliest-start of vehicle which should be the lower bound of the vehicle's departure times. * @@ -292,8 +271,6 @@ public class VehicleImpl extends AbstractVehicle { return new NoVehicle(); } - private final String id; - private final String id; private final VehicleType type; @@ -333,29 +310,15 @@ public class VehicleImpl extends AbstractVehicle { */ @Override public String toString() { - return "[id="+id+"]" + - "[type="+type+"]" + - "[startLocation="+startLocation+"]" + - "[endLocation=" + endLocation+"]" + - "[isReturnToDepot=" + isReturnToDepot() + "]" + - "[skills="+ skills + "]"; - - /** - * Returns String with attributes of this vehicle - *

- *

String has the following format [attr1=val1][attr2=val2]...[attrn=valn] - */ - @Override - public String toString() { return "[id=" + id + "]" + "[type=" + type + "]" + "[startLocation=" + startLocation + "]" + "[endLocation=" + endLocation + "]" + "[isReturnToDepot=" + isReturnToDepot() + "]" + "[skills=" + skills + "]"; - } + @Override public double getEarliestDeparture() { return earliestDeparture; @@ -437,7 +400,5 @@ public class VehicleImpl extends AbstractVehicle { return true; } - - - } + diff --git a/jsprit-core/src/test/java/jsprit/core/problem/vehicle/VehicleImplTest.java b/jsprit-core/src/test/java/jsprit/core/problem/vehicle/VehicleImplTest.java index 4d07c5a7..5412586f 100644 --- a/jsprit-core/src/test/java/jsprit/core/problem/vehicle/VehicleImplTest.java +++ b/jsprit-core/src/test/java/jsprit/core/problem/vehicle/VehicleImplTest.java @@ -37,191 +37,6 @@ public class VehicleImplTest { Vehicle v = VehicleImpl.Builder.newInstance("v").build(); } - @Test - public void whenVehicleIsBuiltToReturnToDepot_itShouldReturnToDepot(){ - Vehicle v = VehicleImpl.Builder.newInstance("v").setReturnToDepot(true).setStartLocation(Location.newInstance("loc")).build(); - assertTrue(v.isReturnToDepot()); - } - - @Test - public void whenVehicleIsBuiltToNotReturnToDepot_itShouldNotReturnToDepot(){ - Vehicle v = VehicleImpl.Builder.newInstance("v").setReturnToDepot(false).setStartLocation(Location.newInstance("loc")).build(); - assertFalse(v.isReturnToDepot()); - } - - @Test - public void whenVehicleIsBuiltWithLocation_itShouldHvTheCorrectLocation(){ - Vehicle v = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance("loc")).build(); - assertEquals("loc",v.getStartLocation().getId()); - } - - @Test - public void whenVehicleIsBuiltWithCoord_itShouldHvTheCorrectCoord(){ - Vehicle v = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance(1, 2)).build(); - assertEquals(1.0,v.getStartLocation().getCoordinate().getX(),0.01); - assertEquals(2.0,v.getStartLocation().getCoordinate().getY(),0.01); - } - - @Test - public void whenVehicleIsBuiltAndEarliestStartIsNotSet_itShouldSetTheDefaultOfZero(){ - Vehicle v = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance(1, 2)).build(); - assertEquals(0.0,v.getEarliestDeparture(),0.01); - } - - @Test - public void whenVehicleIsBuiltAndEarliestStartSet_itShouldBeSetCorrectly(){ - Vehicle v = VehicleImpl.Builder.newInstance("v").setEarliestStart(10.0).setStartLocation(Location.newInstance(1, 2)).build(); - assertEquals(10.0,v.getEarliestDeparture(),0.01); - } - - @Test - public void whenVehicleIsBuiltAndLatestArrivalIsNotSet_itShouldSetDefaultOfDoubleMaxValue(){ - Vehicle v = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance(1, 2)).build(); - assertEquals(Double.MAX_VALUE,v.getLatestArrival(),0.01); - } - - @Test - public void whenVehicleIsBuiltAndLatestArrivalIsSet_itShouldBeSetCorrectly(){ - Vehicle v = VehicleImpl.Builder.newInstance("v").setLatestArrival(30.0).setStartLocation(Location.newInstance(1, 2)).build(); - assertEquals(30.0,v.getLatestArrival(),0.01); - } - - @Test - public void whenNoVehicleIsCreate_itShouldHvTheCorrectId(){ - Vehicle v = VehicleImpl.createNoVehicle(); - assertEquals("noVehicle",v.getId()); - } - - @Test - public void whenStartLocationIsSet_itIsDoneCorrectly(){ - Vehicle v = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance("startLoc")).build(); - assertEquals("startLoc", v.getStartLocation().getId()); - } - - @Test(expected=IllegalStateException.class) - public void whenStartLocationIsNull_itThrowsException(){ - @SuppressWarnings("unused") - Vehicle v = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance(null)).build(); - } - - @Test - public void whenStartLocationCoordIsSet_itIsDoneCorrectly(){ - Vehicle v = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance(1, 2)).build(); - assertEquals(1.0, v.getStartLocation().getCoordinate().getX(),0.01); - assertEquals(2.0, v.getStartLocation().getCoordinate().getY(),0.01); - } - - @Test - public void whenEndLocationIsSet_itIsDoneCorrectly(){ - Vehicle v = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance("startLoc")).setEndLocation(Location.newInstance("endLoc")).build(); - assertEquals("startLoc", v.getStartLocation().getId()); - assertEquals("endLoc", v.getEndLocation().getId()); - } - - @Test - public void whenEndLocationCoordIsSet_itIsDoneCorrectly(){ - Vehicle v = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance("startLoc")).setEndLocation(Location.newInstance(1, 2)).build(); - assertEquals(1.0, v.getEndLocation().getCoordinate().getX(),0.01); - assertEquals(2.0, v.getEndLocation().getCoordinate().getY(),0.01); - } - - - @Test - public void whenNeitherEndLocationIdNorEndLocationCoordAreSet_endLocationIdMustBeEqualToStartLocationId(){ - Vehicle v = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance("startLoc")).build(); - assertEquals("startLoc", v.getEndLocation().getId()); - } - - @Test - public void whenNeitherEndLocationIdNorEndLocationCoordAreSet_endLocationCoordMustBeEqualToStartLocationCoord(){ - Vehicle v = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance("startLoc")).build(); - assertEquals(v.getEndLocation().getCoordinate(), v.getStartLocation().getCoordinate()); - } - - @Test - public void whenNeitherEndLocationIdNorEndLocationCoordAreSet_endLocationCoordMustBeEqualToStartLocationCoordV2(){ - Vehicle v = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance(1.0, 2.0)).build(); - assertEquals(v.getEndLocation().getCoordinate(), v.getStartLocation().getCoordinate()); - } - - @Test - public void whenEndLocationCoordinateIsSetButNoId_idMustBeCoordToString(){ - Vehicle v = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance(1.0, 2.0)).setEndLocation(Location.newInstance(3.0, 4.0)).build(); - assertEquals(v.getEndLocation().getCoordinate().toString(), v.getEndLocation().getId()); - } - - @Test(expected=IllegalStateException.class) - public void whenEndLocationIdIsSpecifiedANDReturnToDepotIsFalse_itShouldThrowException(){ - @SuppressWarnings("unused") - Vehicle v = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance(1.0, 2.0)).setEndLocation(Location.newInstance("endLoc")).setReturnToDepot(false).build(); - } - - @Test(expected=IllegalStateException.class) - public void whenEndLocationCoordIsSpecifiedANDReturnToDepotIsFalse_itShouldThrowException(){ - @SuppressWarnings("unused") - Vehicle v = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance(1.0, 2.0)).setEndLocation(Location.newInstance(3, 4)).setReturnToDepot(false).build(); - } - - @Test - public void whenEndLocationCoordIsNotSpecifiedANDReturnToDepotIsFalse_endLocationCoordMustBeStartLocationCoord(){ - Vehicle v = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance(1.0, 2.0)).setReturnToDepot(false).build(); - assertEquals(v.getStartLocation().getCoordinate(),v.getEndLocation().getCoordinate()); - } - - @Test - public void whenEndLocationIdIsNotSpecifiedANDReturnToDepotIsFalse_endLocationIdMustBeStartLocationId(){ - Vehicle v = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance(1.0, 2.0)).setReturnToDepot(false).build(); - assertEquals(v.getStartLocation().getCoordinate().toString(),v.getEndLocation().getId()); - } - - @Test(expected=IllegalStateException.class) - public void whenStartAndEndAreUnequalANDReturnToDepotIsFalse_itShouldThrowException(){ - @SuppressWarnings("unused") - Vehicle v = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance("start")).setEndLocation(Location.newInstance("end")).setReturnToDepot(false).build(); - } - - @Test - public void whenStartAndEndAreEqualANDReturnToDepotIsFalse_itShouldThrowException(){ - @SuppressWarnings("unused") - Vehicle v = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance("start")).setEndLocation(Location.newInstance("start")).setReturnToDepot(false).build(); - assertTrue(true); - } - - @Test - public void whenTwoVehiclesHaveTheSameId_theyShouldBeEqual(){ - Vehicle v = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance("start")).setEndLocation(Location.newInstance("start")).setReturnToDepot(false).build(); - Vehicle v2 = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance("start")).setEndLocation(Location.newInstance("start")).setReturnToDepot(false).build(); - assertTrue(v.equals(v2)); - } - - - @Test - public void whenAddingSkills_theyShouldBeAddedCorrectly(){ - VehicleTypeImpl type1 = VehicleTypeImpl.Builder.newInstance("type").build(); - Vehicle v = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance("start")).setType(type1).setEndLocation(Location.newInstance("start")) - .addSkill("drill").addSkill("screwdriver").build(); - assertTrue(v.getSkills().containsSkill("drill")); - assertTrue(v.getSkills().containsSkill("drill")); - assertTrue(v.getSkills().containsSkill("screwdriver")); - } - - @Test - public void whenAddingSkillsCaseSens_theyShouldBeAddedCorrectly(){ - VehicleTypeImpl type1 = VehicleTypeImpl.Builder.newInstance("type").build(); - Vehicle v = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance("start")).setType(type1).setEndLocation(Location.newInstance("start")) - .addSkill("drill").addSkill("screwdriver").build(); - assertTrue(v.getSkills().containsSkill("drill")); - assertTrue(v.getSkills().containsSkill("dRill")); - assertTrue(v.getSkills().containsSkill("ScrewDriver")); - } - - @Test - public void whenAddingSkillsCaseSensV2_theyShouldBeAddedCorrectly(){ - VehicleTypeImpl type1 = VehicleTypeImpl.Builder.newInstance("type").build(); - Vehicle v = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance("start")).setType(type1).setEndLocation(Location.newInstance("start")) - .addSkill("drill").build(); - assertFalse(v.getSkills().containsSkill("ScrewDriver")); - } @Test public void whenAddingDriverBreak_itShouldBeAddedCorrectly(){ diff --git a/jsprit-examples/src/main/java/jsprit/examples/BreakExample.java b/jsprit-examples/src/main/java/jsprit/examples/BreakExample.java index 212033b8..e9bba9e2 100644 --- a/jsprit-examples/src/main/java/jsprit/examples/BreakExample.java +++ b/jsprit-examples/src/main/java/jsprit/examples/BreakExample.java @@ -11,7 +11,7 @@ * 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 + * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . ******************************************************************************/ package jsprit.examples; @@ -19,7 +19,6 @@ package jsprit.examples; import jsprit.analysis.toolbox.Plotter; import jsprit.core.algorithm.VehicleRoutingAlgorithm; import jsprit.core.algorithm.box.Jsprit; -import jsprit.core.algorithm.ruin.RuinBreaks; import jsprit.core.problem.Location; import jsprit.core.problem.VehicleRoutingProblem; import jsprit.core.problem.job.Break; @@ -56,7 +55,8 @@ public class BreakExample { */ Builder vehicleBuilder = Builder.newInstance("v1"); vehicleBuilder.setStartLocation(Location.newInstance(10, 10)); - Break myFirstBreak = (Break) Break.Builder.newInstance("myFirstBreak").setTimeWindow(TimeWindow.newInstance(10, 15)).setServiceTime(100).build(); + Break myFirstBreak = Break.Builder.newInstance("myFirstBreak") + .setTimeWindow(TimeWindow.newInstance(10, 15)).setServiceTime(100).build(); vehicleBuilder.setBreak(myFirstBreak); vehicleBuilder.setType(vehicleType); VehicleImpl vehicle = vehicleBuilder.build(); @@ -68,41 +68,40 @@ public class BreakExample { */ Service service1 = Service.Builder.newInstance("1").addSizeDimension(WEIGHT_INDEX, 1).setLocation(Location.newInstance(5, 7)).build(); Service service2 = Service.Builder.newInstance("2").addSizeDimension(WEIGHT_INDEX, 1).setLocation(Location.newInstance(5, 13)).build(); - + Service service3 = Service.Builder.newInstance("3").addSizeDimension(WEIGHT_INDEX, 1).setLocation(Location.newInstance(15, 7)).build(); Service service4 = Service.Builder.newInstance("4").addSizeDimension(WEIGHT_INDEX, 1).setLocation(Location.newInstance(15, 13)).build(); - - + + VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); vrpBuilder.addVehicle(vehicle); vrpBuilder.addJob(service1).addJob(service2).addJob(service3).addJob(service4).addVehicle(v2); vrpBuilder.setFleetSize(VehicleRoutingProblem.FleetSize.FINITE); VehicleRoutingProblem problem = vrpBuilder.build(); - + /* - * get the algorithm out-of-the-box. + * get the algorithm out-of-the-box. */ VehicleRoutingAlgorithm algorithm = Jsprit.Builder.newInstance(problem) .setProperty(Jsprit.Strategy.CLUSTER_REGRET,"0.") .setProperty(Jsprit.Strategy.CLUSTER_BEST,"0.").buildAlgorithm(); - algorithm.addListener(new RuinBreaks()); /* * and search a solution */ Collection solutions = algorithm.searchSolutions(); - + /* - * get the best + * get the best */ VehicleRoutingProblemSolution bestSolution = Solutions.bestOf(solutions); SolutionPrinter.print(problem, bestSolution, SolutionPrinter.Print.VERBOSE); - + /* * plot */ new Plotter(problem,bestSolution).plot("output/plot","breaks"); - + }