diff --git a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/recreate/DefaultScorer.java b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/recreate/DefaultScorer.java index 280de34d..d2e58c2f 100644 --- a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/recreate/DefaultScorer.java +++ b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/recreate/DefaultScorer.java @@ -20,9 +20,9 @@ package com.graphhopper.jsprit.core.algorithm.recreate; import com.graphhopper.jsprit.core.problem.Location; import com.graphhopper.jsprit.core.problem.VehicleRoutingProblem; +import com.graphhopper.jsprit.core.problem.job.Activity; import com.graphhopper.jsprit.core.problem.job.Job; -import com.graphhopper.jsprit.core.problem.job.Service; -import com.graphhopper.jsprit.core.problem.job.Shipment; +import com.graphhopper.jsprit.core.problem.solution.route.activity.TimeWindow; /** * Created by schroeder on 15/10/15. @@ -51,42 +51,30 @@ public class DefaultScorer implements ScoringFunction { @Override public double score(InsertionData best, Job job) { - double score; - if (job instanceof Service) { - score = scoreService(best, job); - } else if (job instanceof Shipment) { - score = scoreShipment(best, job); - } else throw new IllegalStateException("not supported"); - return score; + return scoreJob(best, job); } - private double scoreShipment(InsertionData best, Job job) { - Shipment shipment = (Shipment) job; - double maxDepotDistance_1 = Math.max( - getDistance(best.getSelectedVehicle().getStartLocation(), shipment.getPickupLocation()), - getDistance(best.getSelectedVehicle().getStartLocation(), shipment.getDeliveryLocation()) - ); - double maxDepotDistance_2 = Math.max( - getDistance(best.getSelectedVehicle().getEndLocation(), shipment.getPickupLocation()), - getDistance(best.getSelectedVehicle().getEndLocation(), shipment.getDeliveryLocation()) - ); - double maxDepotDistance = Math.max(maxDepotDistance_1, maxDepotDistance_2); - double minTimeToOperate = Math.min(shipment.getPickupTimeWindow().getEnd() - shipment.getPickupTimeWindow().getStart(), - shipment.getDeliveryTimeWindow().getEnd() - shipment.getDeliveryTimeWindow().getStart()); + private double scoreJob(InsertionData best, Job job) { + Location startLocation = best.getSelectedVehicle().getStartLocation(); + Location endLocation = best.getSelectedVehicle().getEndLocation(); + double maxDepotDistance = 0; + double minTimeToOperate = Double.MAX_VALUE; + for (Activity act : job.getActivities()) { + maxDepotDistance = Math.max(maxDepotDistance, getDistance(startLocation, act.getLocation())); + maxDepotDistance = Math.max(maxDepotDistance, getDistance(endLocation, act.getLocation())); + TimeWindow tw = getLargestTimeWindow(act); + minTimeToOperate = Math.min(minTimeToOperate, tw.getEnd() - tw.getStart()); + } return Math.max(timeWindowParam * minTimeToOperate, minTimeWindowScore) + depotDistanceParam * maxDepotDistance; } - private double scoreService(InsertionData best, Job job) { - Location location = ((Service) job).getLocation(); - double maxDepotDistance = 0; - if (location != null) { - maxDepotDistance = Math.max( - getDistance(best.getSelectedVehicle().getStartLocation(), location), - getDistance(best.getSelectedVehicle().getEndLocation(), location) - ); + private TimeWindow getLargestTimeWindow(Activity act) { + TimeWindow timeWindow = null; + for (TimeWindow tw : act.getTimeWindows()) { + if (timeWindow == null) timeWindow = tw; + else if (tw.larger(timeWindow)) timeWindow = tw; } - return Math.max(timeWindowParam * (((Service) job).getTimeWindow().getEnd() - ((Service) job).getTimeWindow().getStart()), minTimeWindowScore) + - depotDistanceParam * maxDepotDistance; + return TimeWindow.newInstance(0, Double.MAX_VALUE); } diff --git a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/VehicleRoutingProblem.java b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/VehicleRoutingProblem.java index c688ce9c..4c630fab 100644 --- a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/VehicleRoutingProblem.java +++ b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/VehicleRoutingProblem.java @@ -20,10 +20,7 @@ package com.graphhopper.jsprit.core.problem; import com.graphhopper.jsprit.core.problem.cost.VehicleRoutingActivityCosts; import com.graphhopper.jsprit.core.problem.cost.VehicleRoutingTransportCosts; import com.graphhopper.jsprit.core.problem.cost.WaitingTimeCosts; -import com.graphhopper.jsprit.core.problem.job.Break; -import com.graphhopper.jsprit.core.problem.job.Job; -import com.graphhopper.jsprit.core.problem.job.Service; -import com.graphhopper.jsprit.core.problem.job.Shipment; +import com.graphhopper.jsprit.core.problem.job.*; import com.graphhopper.jsprit.core.problem.solution.route.VehicleRoute; import com.graphhopper.jsprit.core.problem.solution.route.activity.BreakActivity; import com.graphhopper.jsprit.core.problem.solution.route.activity.DefaultShipmentActivityFactory; @@ -226,18 +223,8 @@ public class VehicleRoutingProblem { } private void addLocationToTentativeLocations(Job job) { - if (job instanceof Service) { - Location location = ((Service) job).getLocation(); -// tentative_coordinates.put(location.getId(), location.getCoordinate()); - addLocationToTentativeLocations(location); - } else if (job instanceof Shipment) { - Shipment shipment = (Shipment) job; - Location pickupLocation = shipment.getPickupLocation(); - addLocationToTentativeLocations(pickupLocation); -// tentative_coordinates.put(pickupLocation.getId(), pickupLocation.getCoordinate()); - Location deliveryLocation = shipment.getDeliveryLocation(); - addLocationToTentativeLocations(deliveryLocation); -// tentative_coordinates.put(deliveryLocation.getId(), deliveryLocation.getCoordinate()); + for (Activity act : job.getActivities()) { + addLocationToTentativeLocations(act.getLocation()); } } @@ -247,13 +234,7 @@ public class VehicleRoutingProblem { } private void addJobToFinalJobMapAndCreateActivities(Job job) { - if (job instanceof Service) { - Service service = (Service) job; - addService(service); - } else if (job instanceof Shipment) { - Shipment shipment = (Shipment) job; - addShipment(shipment); - } + addJobToFinalMap(job); List jobActs = jobActivityFactory.createActivities(job); for (AbstractActivity act : jobActs) { act.setIndex(activityIndexCounter); @@ -333,13 +314,11 @@ public class VehicleRoutingProblem { return this; } - private void addShipment(Shipment job) { + private void addJobToFinalMap(Job job) { if (jobs.containsKey(job.getId())) { logger.warn("The job " + job + " has already been added to the job list. This overrides the existing job."); } addLocationToTentativeLocations(job); -// tentative_coordinates.put(job.getPickupLocation().getId(), job.getPickupLocation().getCoordinate()); -// tentative_coordinates.put(job.getDeliveryLocation().getId(), job.getDeliveryLocation().getCoordinate()); jobs.put(job.getId(), job); } @@ -516,15 +495,6 @@ public class VehicleRoutingProblem { return Collections.unmodifiableCollection(tentativeJobs.values()); } - private Builder addService(Service service) { - addLocationToTentativeLocations(service); - if (jobs.containsKey(service.getId())) { - logger.warn("The service " + service + " has already been added to job list. This overrides existing job."); - } - jobs.put(service.getId(), service); - return this; - } - } diff --git a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/job/Delivery.java b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/job/Delivery.java index 40b70a75..98e708bf 100644 --- a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/job/Delivery.java +++ b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/job/Delivery.java @@ -59,6 +59,7 @@ public class Delivery extends Service { this.setType("delivery"); super.capacity = super.capacityBuilder.build(); super.skills = super.skillBuilder.build(); + super.activity = new Activity.Builder(location, Activity.Type.DELIVERY).setTimeWindows(timeWindows.getTimeWindows()).setServiceTime(serviceTime).build(); return new Delivery(this); } diff --git a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/job/Pickup.java b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/job/Pickup.java index 2a893d5f..bba2b437 100644 --- a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/job/Pickup.java +++ b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/job/Pickup.java @@ -61,6 +61,7 @@ public class Pickup extends Service { this.setType("pickup"); super.capacity = super.capacityBuilder.build(); super.skills = super.skillBuilder.build(); + super.activity = new Activity.Builder(location, Activity.Type.PICKUP).setTimeWindows(timeWindows.getTimeWindows()).setServiceTime(serviceTime).build(); return new Pickup(this); } diff --git a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/job/Service.java b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/job/Service.java index c16a74db..7d0067f5 100644 --- a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/job/Service.java +++ b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/job/Service.java @@ -96,7 +96,7 @@ public class Service extends AbstractJob { protected double maxTimeInVehicle = Double.MAX_VALUE; - private Activity activity; + protected Activity activity; Builder(String id){ this.id = id; diff --git a/jsprit-core/src/test/java/com/graphhopper/jsprit/core/problem/VehicleRoutingProblemTest.java b/jsprit-core/src/test/java/com/graphhopper/jsprit/core/problem/VehicleRoutingProblemTest.java index 046f1934..4a993cd0 100644 --- a/jsprit-core/src/test/java/com/graphhopper/jsprit/core/problem/VehicleRoutingProblemTest.java +++ b/jsprit-core/src/test/java/com/graphhopper/jsprit/core/problem/VehicleRoutingProblemTest.java @@ -130,12 +130,8 @@ public class VehicleRoutingProblemTest { @Test public void whenServicesAreAdded_vrpShouldContainThem() { - Service s1 = mock(Service.class); - when(s1.getId()).thenReturn("s1"); - when(s1.getLocation()).thenReturn(Location.Builder.newInstance().setIndex(1).build()); - Service s2 = mock(Service.class); - when(s2.getId()).thenReturn("s2"); - when(s2.getLocation()).thenReturn(Location.Builder.newInstance().setIndex(1).build()); + Service s1 = Service.Builder.newInstance("s1").setLocation(Location.Builder.newInstance().setIndex(1).build()).build(); + Service s2 = Service.Builder.newInstance("s2").setLocation(Location.Builder.newInstance().setIndex(1).build()).build(); VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); vrpBuilder.addJob(s1).addJob(s2);