From ca72c6f05fc13549667579753cffa880abe7925b Mon Sep 17 00:00:00 2001 From: kandelirina Date: Mon, 11 Feb 2019 07:58:53 +0200 Subject: [PATCH] OPTI-505 include break data in vehicle key (#78) * include break data in vehicle key * add fixed cost --- .../core/problem/vehicle/VehicleImpl.java | 7 ++++- .../core/problem/vehicle/VehicleTypeKey.java | 23 ++++++++++++-- .../core/algorithm/MaxTimeInVehicleTest.java | 9 ++++-- .../core/problem/vehicle/VehicleImplTest.java | 31 +++++++++++++++++++ 4 files changed, 64 insertions(+), 6 deletions(-) diff --git a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/vehicle/VehicleImpl.java b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/vehicle/VehicleImpl.java index f6121eaf..e113867b 100644 --- a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/vehicle/VehicleImpl.java +++ b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/vehicle/VehicleImpl.java @@ -364,7 +364,12 @@ public class VehicleImpl extends AbstractVehicle { aBreak = builder.aBreak; prohibitedTasks = builder.prohibitedTasks; // setVehicleIdentifier(new VehicleTypeKey(type.getTypeId(),startLocation.getId(),endLocation.getId(),earliestDeparture,latestArrival,skills)); - setVehicleIdentifier(new VehicleTypeKey(type.getTypeId(), startLocation.getId(), endLocation.getId(), earliestDeparture, latestArrival, skills, returnToDepot, getUserData())); + + if (builder.aBreak != null) { + setVehicleIdentifier(new VehicleTypeKey(type.getTypeId(), startLocation.getId(), endLocation.getId(), earliestDeparture, latestArrival, skills, returnToDepot, getUserData(), aBreak.getTimeWindow().getStart(), aBreak.getTimeWindow().getEnd(), aBreak.getServiceDuration())); + } else { + setVehicleIdentifier(new VehicleTypeKey(type.getTypeId(), startLocation.getId(), endLocation.getId(), earliestDeparture, latestArrival, skills, returnToDepot, getUserData())); + } } /** diff --git a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/vehicle/VehicleTypeKey.java b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/vehicle/VehicleTypeKey.java index d66be173..8d04180e 100644 --- a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/vehicle/VehicleTypeKey.java +++ b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/vehicle/VehicleTypeKey.java @@ -39,9 +39,11 @@ public class VehicleTypeKey extends AbstractVehicle.AbstractTypeKey { public final Skills skills; public final boolean returnToDepot; public final Object userData; + public final double earliestBreakStart; + public final double latestBreakStart; + public final double breakDuration; - public VehicleTypeKey(String typeId, String startLocationId, String endLocationId, double earliestStart, double latestEnd, Skills skills, boolean returnToDepot, Object userData) { - super(); + public VehicleTypeKey(String typeId, String startLocationId, String endLocationId, double earliestStart, double latestEnd, Skills skills, boolean returnToDepot, Object userData, double earliestBreakStart, double latestBreakStart, double breakDuration) { this.type = typeId; this.startLocationId = startLocationId; this.endLocationId = endLocationId; @@ -50,6 +52,13 @@ public class VehicleTypeKey extends AbstractVehicle.AbstractTypeKey { this.skills = skills; this.returnToDepot = returnToDepot; this.userData = userData; + this.earliestBreakStart = earliestBreakStart; + this.latestBreakStart = latestBreakStart; + this.breakDuration = breakDuration; + } + + public VehicleTypeKey(String typeId, String startLocationId, String endLocationId, double earliestStart, double latestEnd, Skills skills, boolean returnToDepot, Object userData) { + this(typeId, startLocationId, endLocationId, earliestStart, latestEnd, skills, returnToDepot, userData, 0, Double.MAX_VALUE, 0); } public VehicleTypeKey(String typeId, String startLocationId, String endLocationId, double earliestStart, double latestEnd, Skills skills, boolean returnToDepot) { @@ -71,6 +80,9 @@ public class VehicleTypeKey extends AbstractVehicle.AbstractTypeKey { if (!startLocationId.equals(that.startLocationId)) return false; if (!type.equals(that.type)) return false; if (!Objects.equals(that.userData, this.userData)) return false; + if (Double.compare(that.breakDuration, breakDuration) != 0) return false; + if (Double.compare(that.earliestBreakStart, earliestBreakStart) != 0) return false; + if (Double.compare(that.latestBreakStart, latestBreakStart) != 0) return false; return true; } @@ -91,6 +103,13 @@ public class VehicleTypeKey extends AbstractVehicle.AbstractTypeKey { if (userData != null) result = 31 * result + userData.hashCode(); + temp = Double.doubleToLongBits(breakDuration); + result = 31 * result + (int) (temp ^ (temp >>> 32)); + temp = Double.doubleToLongBits(earliestBreakStart); + result = 31 * result + (int) (temp ^ (temp >>> 32)); + temp = Double.doubleToLongBits(latestBreakStart); + result = 31 * result + (int) (temp ^ (temp >>> 32)); + return result; } diff --git a/jsprit-core/src/test/java/com/graphhopper/jsprit/core/algorithm/MaxTimeInVehicleTest.java b/jsprit-core/src/test/java/com/graphhopper/jsprit/core/algorithm/MaxTimeInVehicleTest.java index 9e5134fc..1959e9c3 100644 --- a/jsprit-core/src/test/java/com/graphhopper/jsprit/core/algorithm/MaxTimeInVehicleTest.java +++ b/jsprit-core/src/test/java/com/graphhopper/jsprit/core/algorithm/MaxTimeInVehicleTest.java @@ -235,10 +235,13 @@ public class MaxTimeInVehicleTest { .setMaxTimeInVehicle(14) .setLocation(Location.newInstance(10, 5)).setServiceTime(2).build(); + final VehicleTypeImpl type = VehicleTypeImpl.Builder.newInstance("1").setFixedCost(1).build(); VehicleImpl v1 = VehicleImpl.Builder.newInstance("v1") + .setType(type) .setStartLocation(Location.newInstance(8,5)).setReturnToDepot(true).build(); VehicleImpl v2 = VehicleImpl.Builder.newInstance("v2") + .setType(type) .setStartLocation(Location.newInstance(5,0)).setReturnToDepot(true).build(); VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance() @@ -258,9 +261,9 @@ public class MaxTimeInVehicleTest { VehicleRoutingAlgorithm vra = Jsprit.Builder.newInstance(vrp).setStateAndConstraintManager(stateManager,constraintManager).buildAlgorithm(); VehicleRoutingProblemSolution solution = Solutions.bestOf(vra.searchSolutions()); - SolutionPrinter.print(vrp,solution, SolutionPrinter.Print.VERBOSE); - assertEquals(1,solution.getRoutes().size()); - assertEquals(0,solution.getUnassignedJobs().size()); + SolutionPrinter.print(vrp, solution, SolutionPrinter.Print.VERBOSE); + assertEquals(1, solution.getRoutes().size()); + assertEquals(0, solution.getUnassignedJobs().size()); } diff --git a/jsprit-core/src/test/java/com/graphhopper/jsprit/core/problem/vehicle/VehicleImplTest.java b/jsprit-core/src/test/java/com/graphhopper/jsprit/core/problem/vehicle/VehicleImplTest.java index cf276e48..f85a029d 100644 --- a/jsprit-core/src/test/java/com/graphhopper/jsprit/core/problem/vehicle/VehicleImplTest.java +++ b/jsprit-core/src/test/java/com/graphhopper/jsprit/core/problem/vehicle/VehicleImplTest.java @@ -25,6 +25,7 @@ import org.junit.Test; import java.util.HashMap; import java.util.Map; +import java.util.UUID; import static org.junit.Assert.*; @@ -255,4 +256,34 @@ public class VehicleImplTest { assertNull(three.getUserData()); } + @Test + public void testBreakTimesIncludedInKey() { + VehicleTypeImpl type = VehicleTypeImpl.Builder.newInstance("type").build(); + Vehicle one = VehicleImpl.Builder.newInstance("v1").setType(type) + .setStartLocation(Location.newInstance("start")) + .setEndLocation(Location.newInstance("end")) + .setEarliestStart(100) + .setLatestArrival(300) + .setBreak(Break.Builder.newInstance(UUID.randomUUID().toString()).addTimeWindow(0, 150).setServiceTime(60).build()) + .build(); + + Vehicle two = VehicleImpl.Builder.newInstance("v2").setType(type) + .setStartLocation(Location.newInstance("start")) + .setEndLocation(Location.newInstance("end")) + .setEarliestStart(100) + .setLatestArrival(300) + .setBreak(Break.Builder.newInstance(UUID.randomUUID().toString()).addTimeWindow(0, 150).setServiceTime(60).build()) + .build(); + + Vehicle three = VehicleImpl.Builder.newInstance("v3").setType(type) + .setStartLocation(Location.newInstance("start")) + .setEndLocation(Location.newInstance("end")) + .setEarliestStart(100) + .setLatestArrival(300) + .setBreak(Break.Builder.newInstance(UUID.randomUUID().toString()).addTimeWindow(100, 250).setServiceTime(60).build()) + .build(); + + assertEquals(one.getVehicleTypeIdentifier(), two.getVehicleTypeIdentifier()); + assertNotEquals(one.getVehicleTypeIdentifier(), three.getVehicleTypeIdentifier()); + } }