diff --git a/jsprit-core/src/main/java/jsprit/core/analysis/SolutionAnalyser.java b/jsprit-core/src/main/java/jsprit/core/analysis/SolutionAnalyser.java index 50ee9120..77578b70 100644 --- a/jsprit-core/src/main/java/jsprit/core/analysis/SolutionAnalyser.java +++ b/jsprit-core/src/main/java/jsprit/core/analysis/SolutionAnalyser.java @@ -38,6 +38,17 @@ import java.util.Set; */ public class SolutionAnalyser { + private final static String PICKUP_COUNT = "pickup-count"; + + private final static String PICKUP_COUNT_AT_BEGINNING = "pickup-count-at-beginning"; + + private final static String DELIVERY_COUNT = "delivery-count"; + + private final static String DELIVERY_COUNT_AT_END = "delivery-count-at-end"; + + private final static String LOAD_PICKED = "load-picked"; + + private final static String LOAD_DELIVERED = "load-delivered"; public static interface DistanceCalculator { @@ -45,6 +56,86 @@ public class SolutionAnalyser { } + private static class LoadAndActivityCounter implements StateUpdater, ActivityVisitor { + + private final StateManager stateManager; + + private int pickupCounter; + + private int pickupAtBeginningCounter; + + private int deliveryCounter; + + private int deliverAtEndCounter; + + private Capacity pickedUp; + + private Capacity delivered; + + private StateId pickup_count_id; + + private StateId pickup_at_beginning_count_id; + + private StateId delivery_count_id; + + private StateId delivery_at_end_count_id; + + private StateId load_picked_id; + + private StateId load_delivered_id; + + private VehicleRoute route; + + private LoadAndActivityCounter(StateManager stateManager) { + this.stateManager = stateManager; + pickup_count_id = stateManager.createStateId(PICKUP_COUNT); + delivery_count_id = stateManager.createStateId(DELIVERY_COUNT); + load_picked_id = stateManager.createStateId(LOAD_PICKED); + load_delivered_id = stateManager.createStateId(LOAD_DELIVERED); + pickup_at_beginning_count_id = stateManager.createStateId(PICKUP_COUNT_AT_BEGINNING); + delivery_at_end_count_id = stateManager.createStateId(DELIVERY_COUNT_AT_END); + } + + @Override + public void begin(VehicleRoute route) { + this.route = route; + pickupCounter = 0; + pickupAtBeginningCounter = 0; + deliveryCounter = 0; + deliverAtEndCounter = 0; + pickedUp = Capacity.Builder.newInstance().build(); + delivered = Capacity.Builder.newInstance().build(); + } + + @Override + public void visit(TourActivity activity) { + if(activity instanceof PickupActivity){ + pickupCounter++; + pickedUp = Capacity.addup(pickedUp, ((PickupActivity) activity).getJob().getSize()); + if(activity instanceof PickupService){ + deliverAtEndCounter++; + } + } + else if(activity instanceof DeliveryActivity){ + deliveryCounter++; + delivered = Capacity.addup(delivered, ((DeliveryActivity) activity).getJob().getSize()); + if(activity instanceof DeliverService){ + pickupAtBeginningCounter++; + } + } + } + + @Override + public void finish() { + stateManager.putRouteState(route,pickup_count_id,pickupCounter); + stateManager.putRouteState(route,delivery_count_id,deliveryCounter); + stateManager.putRouteState(route,load_picked_id,pickedUp); + stateManager.putRouteState(route,load_delivered_id,delivered); + stateManager.putRouteState(route,pickup_at_beginning_count_id,pickupAtBeginningCounter); + stateManager.putRouteState(route,delivery_at_end_count_id,deliverAtEndCounter); + } + } + private static class BackhaulAndShipmentUpdater implements StateUpdater, ActivityVisitor { private final StateId backhaul_id; @@ -328,6 +419,15 @@ public class SolutionAnalyser { private Boolean hasSkillConstraintViolation; private Boolean hasBackhaulConstraintViolation; private Boolean hasShipmentConstraintViolation; + private Integer noPickups; + private Integer noPickupsAtBeginning; + private Integer noDeliveries; + private Integer noDeliveriesAtEnd; + private Capacity pickupLoad; + private Capacity pickupLoadAtBeginning; + private Capacity deliveryLoad; + private Capacity deliveryLoadAtEnd; + private Double total_costs; @@ -371,6 +471,7 @@ public class SolutionAnalyser { stateManager.addStateUpdater(new DistanceUpdater(distance_id,stateManager,distanceCalculator)); stateManager.addStateUpdater(new BackhaulAndShipmentUpdater(backhaul_id,shipment_id,stateManager)); stateManager.addStateUpdater(new SkillUpdater(stateManager,skill_id)); + stateManager.addStateUpdater(new LoadAndActivityCounter(stateManager)); } @@ -395,6 +496,14 @@ public class SolutionAnalyser { if(hasSkillConstraintViolation(route)) hasSkillConstraintViolation = true; if(hasShipmentConstraintViolation(route)) hasShipmentConstraintViolation = true; if(hasBackhaulConstraintViolation(route)) hasBackhaulConstraintViolation = true; + noPickups += getNumberOfPickups(route); + noPickupsAtBeginning += getNumberOfPickupsAtBeginning(route); + noDeliveries += getNumberOfDeliveries(route); + noDeliveriesAtEnd += getNumberOfDeliveriesAtEnd(route); + pickupLoad = Capacity.addup(pickupLoad,getLoadPickedUp(route)); + pickupLoadAtBeginning = Capacity.addup(pickupLoadAtBeginning,getLoadAtBeginning(route)); + deliveryLoad = Capacity.addup(deliveryLoad,getLoadDelivered(route)); + deliveryLoadAtEnd = Capacity.addup(deliveryLoadAtEnd,getLoadAtEnd(route)); } total_costs = solutionCostCalculator.getCosts(this.solution); } @@ -413,6 +522,14 @@ public class SolutionAnalyser { hasBackhaulConstraintViolation = false; hasShipmentConstraintViolation = false; hasSkillConstraintViolation = false; + noPickups = 0; + noPickupsAtBeginning = 0; + noDeliveries = 0; + noDeliveriesAtEnd = 0; + pickupLoad = Capacity.Builder.newInstance().build(); + pickupLoadAtBeginning = Capacity.Builder.newInstance().build(); + deliveryLoad = Capacity.Builder.newInstance().build(); + deliveryLoadAtEnd = Capacity.Builder.newInstance().build(); } public void informSolutionChanged(VehicleRoutingProblemSolution newSolution){ @@ -488,6 +605,42 @@ public class SolutionAnalyser { else return null; } + /** + * @param route to get number of pickups from + * @return number of pickups picked up on specified route (without load at beginning) + */ + public Integer getNumberOfPickups(VehicleRoute route){ + if(route == null) throw new IllegalStateException("route is missing."); + return stateManager.getRouteState(route,stateManager.createStateId(PICKUP_COUNT),Integer.class); + } + + /** + * @param route to get number of deliveries from + * @return number of deliveries delivered on specified route (without load at end) + */ + public Integer getNumberOfDeliveries(VehicleRoute route){ + if(route == null) throw new IllegalStateException("route is missing."); + return stateManager.getRouteState(route,stateManager.createStateId(DELIVERY_COUNT),Integer.class); + } + + /** + * @param route to get the picked load from + * @return picked load (without load at beginning) + */ + public Capacity getLoadPickedUp(VehicleRoute route){ + if(route == null) throw new IllegalStateException("route is missing."); + return stateManager.getRouteState(route,stateManager.createStateId(LOAD_PICKED),Capacity.class); + } + + /** + * @param route to get delivered load from + * @return delivered laod (without load at end) + */ + public Capacity getLoadDelivered(VehicleRoute route){ + if(route == null) throw new IllegalStateException("route is missing."); + return stateManager.getRouteState(route,stateManager.createStateId(LOAD_DELIVERED),Capacity.class); + } + /** * @param route to get the capacity violation from * @return the capacity violation on this route, i.e. maxLoad - vehicleCapacity @@ -755,6 +908,82 @@ public class SolutionAnalyser { return stateManager.getActivityState(activity, distance_id, Double.class); } + /** + * @return number of pickups in specified solution (without load at beginning of each route) + */ + public Integer getNumberOfPickups(){ + return noPickups; + } + + /** + * @param route to get the number of pickups at beginning from + * @return number of pickups at beginning + */ + public Integer getNumberOfPickupsAtBeginning(VehicleRoute route){ + if(route == null) throw new IllegalArgumentException("route is missing."); + return stateManager.getRouteState(route,stateManager.createStateId(PICKUP_COUNT_AT_BEGINNING),Integer.class); + } + + /** + * @return number of pickups in specified solution at beginning of each route + */ + public Integer getNumberOfPickupsAtBeginning(){ + return noPickupsAtBeginning; + } + + /** + * @return number of deliveries in specified solution (without load at end of each route) + */ + public Integer getNumberOfDeliveries(){ + return noDeliveries; + } + + /** + * @return number of deliveries in specified solution at end of each route + */ + public Integer getNumberOfDeliveriesAtEnd(){ + return noDeliveriesAtEnd; + } + + /** + * @param route to get the number of deliveries at end from + * @return number of deliveries at end of specified route + */ + public Integer getNumberOfDeliveriesAtEnd(VehicleRoute route){ + if(route == null) throw new IllegalArgumentException("route is missing."); + return stateManager.getRouteState(route,stateManager.createStateId(DELIVERY_COUNT_AT_END),Integer.class); + } + + /** + * @return load picked up in solution (without load at beginning of each route) + */ + public Capacity getLoadPickedUp(){ + return pickupLoad; + } + + /** + * @return load picked up in solution at beginning of each route + */ + public Capacity getLoadAtBeginning(){ + return pickupLoadAtBeginning; + } + + /** + * @return load delivered in solution (without load at end of each route) + */ + public Capacity getLoadDelivered(){ + return deliveryLoad; + } + + /** + * @return load delivered in solution at end of each route + */ + public Capacity getLoadAtEnd(){ + return deliveryLoadAtEnd; + } + + + /** * @return total distance for specified solution */ diff --git a/jsprit-core/src/test/java/jsprit/core/analysis/SolutionAnalyserTest.java b/jsprit-core/src/test/java/jsprit/core/analysis/SolutionAnalyserTest.java index 65c3ef26..fb76a0c5 100644 --- a/jsprit-core/src/test/java/jsprit/core/analysis/SolutionAnalyserTest.java +++ b/jsprit-core/src/test/java/jsprit/core/analysis/SolutionAnalyserTest.java @@ -386,6 +386,392 @@ public class SolutionAnalyserTest { Assert.assertEquals(12, analyser.getMaxLoad(route).get(0)); } + @Test + public void pickupCount_OfRoute1ShouldWork(){ + SolutionAnalyser analyser = new SolutionAnalyser(vrp,solution, new SolutionAnalyser.DistanceCalculator() { + @Override + public double getDistance(String fromLocationId, String toLocationId) { + return vrp.getTransportCosts().getTransportCost(fromLocationId,toLocationId,0.,null,null); + } + }); + VehicleRoute route = solution.getRoutes().iterator().next(); + Assert.assertEquals(3, analyser.getNumberOfPickups(route), 0.01); + } + + @Test + public void pickupCountAtBeginning_OfRoute1ShouldWork(){ + SolutionAnalyser analyser = new SolutionAnalyser(vrp,solution, new SolutionAnalyser.DistanceCalculator() { + @Override + public double getDistance(String fromLocationId, String toLocationId) { + return vrp.getTransportCosts().getTransportCost(fromLocationId,toLocationId,0.,null,null); + } + }); + VehicleRoute route = solution.getRoutes().iterator().next(); + Assert.assertEquals(0, analyser.getNumberOfPickupsAtBeginning(route), 0.01); + } + + @Test + public void pickupCount_OfRoute1OfAnotherSolutionShouldWork(){ + buildAnotherScenarioWithOnlyOneVehicleAndWithoutAnyConstraintsBefore(); + SolutionAnalyser analyser = new SolutionAnalyser(vrp,solution, new SolutionAnalyser.DistanceCalculator() { + @Override + public double getDistance(String fromLocationId, String toLocationId) { + return vrp.getTransportCosts().getTransportCost(fromLocationId,toLocationId,0.,null,null); + } + }); + VehicleRoute route = solution.getRoutes().iterator().next(); + Assert.assertEquals(4, analyser.getNumberOfPickups(route), 0.01); + } + + @Test + public void pickupCountAtBeginning_OfRoute1OfAnotherSolutionShouldWork(){ + buildAnotherScenarioWithOnlyOneVehicleAndWithoutAnyConstraintsBefore(); + SolutionAnalyser analyser = new SolutionAnalyser(vrp,solution, new SolutionAnalyser.DistanceCalculator() { + @Override + public double getDistance(String fromLocationId, String toLocationId) { + return vrp.getTransportCosts().getTransportCost(fromLocationId,toLocationId,0.,null,null); + } + }); + VehicleRoute route = solution.getRoutes().iterator().next(); + Assert.assertEquals(2, analyser.getNumberOfPickupsAtBeginning(route), 0.01); + } + + @Test + public void pickupCount_onSolutionShouldWork(){ + SolutionAnalyser analyser = new SolutionAnalyser(vrp,solution, new SolutionAnalyser.DistanceCalculator() { + @Override + public double getDistance(String fromLocationId, String toLocationId) { + return vrp.getTransportCosts().getTransportCost(fromLocationId,toLocationId,0.,null,null); + } + }); + Assert.assertEquals(6, analyser.getNumberOfPickups(), 0.01); + } + + @Test + public void pickupCountAtBeginning_onSolutionShouldWork(){ + SolutionAnalyser analyser = new SolutionAnalyser(vrp,solution, new SolutionAnalyser.DistanceCalculator() { + @Override + public double getDistance(String fromLocationId, String toLocationId) { + return vrp.getTransportCosts().getTransportCost(fromLocationId,toLocationId,0.,null,null); + } + }); + Assert.assertEquals(0, analyser.getNumberOfPickupsAtBeginning(), 0.01); + } + + @Test + public void pickupCount_onAnotherSolutionShouldWork(){ + buildAnotherScenarioWithOnlyOneVehicleAndWithoutAnyConstraintsBefore(); + SolutionAnalyser analyser = new SolutionAnalyser(vrp,solution, new SolutionAnalyser.DistanceCalculator() { + @Override + public double getDistance(String fromLocationId, String toLocationId) { + return vrp.getTransportCosts().getTransportCost(fromLocationId,toLocationId,0.,null,null); + } + }); + Assert.assertEquals(4, analyser.getNumberOfPickups(), 0.01); + } + + @Test + public void pickupCountAtBeginning_onAnotherSolutionShouldWork(){ + buildAnotherScenarioWithOnlyOneVehicleAndWithoutAnyConstraintsBefore(); + SolutionAnalyser analyser = new SolutionAnalyser(vrp,solution, new SolutionAnalyser.DistanceCalculator() { + @Override + public double getDistance(String fromLocationId, String toLocationId) { + return vrp.getTransportCosts().getTransportCost(fromLocationId,toLocationId,0.,null,null); + } + }); + Assert.assertEquals(2, analyser.getNumberOfPickupsAtBeginning(), 0.01); + } + + @Test + public void pickupLoad_OfRoute1ShouldWork(){ + SolutionAnalyser analyser = new SolutionAnalyser(vrp,solution, new SolutionAnalyser.DistanceCalculator() { + @Override + public double getDistance(String fromLocationId, String toLocationId) { + return vrp.getTransportCosts().getTransportCost(fromLocationId,toLocationId,0.,null,null); + } + }); + VehicleRoute route = solution.getRoutes().iterator().next(); + Assert.assertEquals(15, analyser.getLoadPickedUp(route).get(0), 0.01); + } + + @Test + public void pickupLoadAtBeginning_OfRoute1ShouldWork(){ + SolutionAnalyser analyser = new SolutionAnalyser(vrp,solution, new SolutionAnalyser.DistanceCalculator() { + @Override + public double getDistance(String fromLocationId, String toLocationId) { + return vrp.getTransportCosts().getTransportCost(fromLocationId,toLocationId,0.,null,null); + } + }); + VehicleRoute route = solution.getRoutes().iterator().next(); + Assert.assertEquals(0, analyser.getLoadAtBeginning(route).get(0), 0.01); + } + + @Test + public void pickupLoad_OfRoute1OfAnotherShouldWork(){ + buildAnotherScenarioWithOnlyOneVehicleAndWithoutAnyConstraintsBefore(); + SolutionAnalyser analyser = new SolutionAnalyser(vrp,solution, new SolutionAnalyser.DistanceCalculator() { + @Override + public double getDistance(String fromLocationId, String toLocationId) { + return vrp.getTransportCosts().getTransportCost(fromLocationId,toLocationId,0.,null,null); + } + }); + VehicleRoute route = solution.getRoutes().iterator().next(); + Assert.assertEquals(50, analyser.getLoadPickedUp(route).get(0), 0.01); + } + + @Test + public void pickupLoadAtBeginning_OfRoute1OfAnotherShouldWork(){ + buildAnotherScenarioWithOnlyOneVehicleAndWithoutAnyConstraintsBefore(); + SolutionAnalyser analyser = new SolutionAnalyser(vrp,solution, new SolutionAnalyser.DistanceCalculator() { + @Override + public double getDistance(String fromLocationId, String toLocationId) { + return vrp.getTransportCosts().getTransportCost(fromLocationId,toLocationId,0.,null,null); + } + }); + VehicleRoute route = solution.getRoutes().iterator().next(); + Assert.assertEquals(40, analyser.getLoadAtBeginning(route).get(0), 0.01); + } + + @Test + public void pickupLoad_onSolutionShouldWork(){ + SolutionAnalyser analyser = new SolutionAnalyser(vrp,solution, new SolutionAnalyser.DistanceCalculator() { + @Override + public double getDistance(String fromLocationId, String toLocationId) { + return vrp.getTransportCosts().getTransportCost(fromLocationId,toLocationId,0.,null,null); + } + }); + Assert.assertEquals(30, analyser.getLoadPickedUp().get(0), 0.01); + } + + @Test + public void pickupLoadAtBeginning_onSolutionShouldWork(){ + SolutionAnalyser analyser = new SolutionAnalyser(vrp,solution, new SolutionAnalyser.DistanceCalculator() { + @Override + public double getDistance(String fromLocationId, String toLocationId) { + return vrp.getTransportCosts().getTransportCost(fromLocationId,toLocationId,0.,null,null); + } + }); + Assert.assertEquals(0, analyser.getLoadAtBeginning().get(0), 0.01); + } + + @Test + public void pickupLoad_onAnotherSolutionShouldWork(){ + buildAnotherScenarioWithOnlyOneVehicleAndWithoutAnyConstraintsBefore(); + SolutionAnalyser analyser = new SolutionAnalyser(vrp,solution, new SolutionAnalyser.DistanceCalculator() { + @Override + public double getDistance(String fromLocationId, String toLocationId) { + return vrp.getTransportCosts().getTransportCost(fromLocationId,toLocationId,0.,null,null); + } + }); + Assert.assertEquals(50, analyser.getLoadPickedUp().get(0), 0.01); + } + + @Test + public void pickupLoadAtBeginning_onAnotherSolutionShouldWork(){ + buildAnotherScenarioWithOnlyOneVehicleAndWithoutAnyConstraintsBefore(); + SolutionAnalyser analyser = new SolutionAnalyser(vrp,solution, new SolutionAnalyser.DistanceCalculator() { + @Override + public double getDistance(String fromLocationId, String toLocationId) { + return vrp.getTransportCosts().getTransportCost(fromLocationId,toLocationId,0.,null,null); + } + }); + Assert.assertEquals(40, analyser.getLoadAtBeginning().get(0), 0.01); + } + + @Test + public void deliveryCount_OfRoute1ShouldWork(){ + SolutionAnalyser analyser = new SolutionAnalyser(vrp,solution, new SolutionAnalyser.DistanceCalculator() { + @Override + public double getDistance(String fromLocationId, String toLocationId) { + return vrp.getTransportCosts().getTransportCost(fromLocationId,toLocationId,0.,null,null); + } + }); + VehicleRoute route = solution.getRoutes().iterator().next(); + Assert.assertEquals(1, analyser.getNumberOfDeliveries(route), 0.01); + } + + @Test + public void deliveryCountAtEnd_OfRoute1ShouldWork(){ + SolutionAnalyser analyser = new SolutionAnalyser(vrp,solution, new SolutionAnalyser.DistanceCalculator() { + @Override + public double getDistance(String fromLocationId, String toLocationId) { + return vrp.getTransportCosts().getTransportCost(fromLocationId,toLocationId,0.,null,null); + } + }); + VehicleRoute route = solution.getRoutes().iterator().next(); + Assert.assertEquals(2, analyser.getNumberOfDeliveriesAtEnd(route), 0.01); + } + + @Test + public void deliveryCount_OfRoute1OfAnotherSolutionShouldWork(){ + buildAnotherScenarioWithOnlyOneVehicleAndWithoutAnyConstraintsBefore(); + SolutionAnalyser analyser = new SolutionAnalyser(vrp,solution, new SolutionAnalyser.DistanceCalculator() { + @Override + public double getDistance(String fromLocationId, String toLocationId) { + return vrp.getTransportCosts().getTransportCost(fromLocationId,toLocationId,0.,null,null); + } + }); + VehicleRoute route = solution.getRoutes().iterator().next(); + Assert.assertEquals(4, analyser.getNumberOfDeliveries(route), 0.01); + } + + @Test + public void deliveryCountAtEnd_OfRoute1OfAnotherSolutionShouldWork(){ + buildAnotherScenarioWithOnlyOneVehicleAndWithoutAnyConstraintsBefore(); + SolutionAnalyser analyser = new SolutionAnalyser(vrp,solution, new SolutionAnalyser.DistanceCalculator() { + @Override + public double getDistance(String fromLocationId, String toLocationId) { + return vrp.getTransportCosts().getTransportCost(fromLocationId,toLocationId,0.,null,null); + } + }); + VehicleRoute route = solution.getRoutes().iterator().next(); + Assert.assertEquals(2, analyser.getNumberOfDeliveriesAtEnd(route), 0.01); + } + + @Test + public void deliveryCount_onSolutionShouldWork(){ + SolutionAnalyser analyser = new SolutionAnalyser(vrp,solution, new SolutionAnalyser.DistanceCalculator() { + @Override + public double getDistance(String fromLocationId, String toLocationId) { + return vrp.getTransportCosts().getTransportCost(fromLocationId,toLocationId,0.,null,null); + } + }); + Assert.assertEquals(2, analyser.getNumberOfDeliveries(), 0.01); + } + + @Test + public void deliveryCountAtEnd_onSolutionShouldWork(){ + SolutionAnalyser analyser = new SolutionAnalyser(vrp,solution, new SolutionAnalyser.DistanceCalculator() { + @Override + public double getDistance(String fromLocationId, String toLocationId) { + return vrp.getTransportCosts().getTransportCost(fromLocationId,toLocationId,0.,null,null); + } + }); + Assert.assertEquals(4, analyser.getNumberOfDeliveriesAtEnd(), 0.01); + } + + @Test + public void deliveryCount_onAnotherSolutionShouldWork(){ + buildAnotherScenarioWithOnlyOneVehicleAndWithoutAnyConstraintsBefore(); + SolutionAnalyser analyser = new SolutionAnalyser(vrp,solution, new SolutionAnalyser.DistanceCalculator() { + @Override + public double getDistance(String fromLocationId, String toLocationId) { + return vrp.getTransportCosts().getTransportCost(fromLocationId,toLocationId,0.,null,null); + } + }); + Assert.assertEquals(4, analyser.getNumberOfDeliveries(), 0.01); + } + + @Test + public void deliveryCountAtEnd_onAnotherSolutionShouldWork(){ + buildAnotherScenarioWithOnlyOneVehicleAndWithoutAnyConstraintsBefore(); + SolutionAnalyser analyser = new SolutionAnalyser(vrp,solution, new SolutionAnalyser.DistanceCalculator() { + @Override + public double getDistance(String fromLocationId, String toLocationId) { + return vrp.getTransportCosts().getTransportCost(fromLocationId,toLocationId,0.,null,null); + } + }); + Assert.assertEquals(2, analyser.getNumberOfDeliveriesAtEnd(), 0.01); + } + + @Test + public void deliveryLoad_OfRoute1ShouldWork(){ + SolutionAnalyser analyser = new SolutionAnalyser(vrp,solution, new SolutionAnalyser.DistanceCalculator() { + @Override + public double getDistance(String fromLocationId, String toLocationId) { + return vrp.getTransportCosts().getTransportCost(fromLocationId,toLocationId,0.,null,null); + } + }); + VehicleRoute route = solution.getRoutes().iterator().next(); + Assert.assertEquals(10, analyser.getLoadDelivered(route).get(0), 0.01); + } + + @Test + public void deliveryLoadAtEnd_OfRoute1ShouldWork(){ + SolutionAnalyser analyser = new SolutionAnalyser(vrp,solution, new SolutionAnalyser.DistanceCalculator() { + @Override + public double getDistance(String fromLocationId, String toLocationId) { + return vrp.getTransportCosts().getTransportCost(fromLocationId,toLocationId,0.,null,null); + } + }); + VehicleRoute route = solution.getRoutes().iterator().next(); + Assert.assertEquals(5, analyser.getLoadAtEnd(route).get(0), 0.01); + } + + @Test + public void deliveryLoad_OfRoute1OfAnotherSolutionShouldWork(){ + buildAnotherScenarioWithOnlyOneVehicleAndWithoutAnyConstraintsBefore(); + SolutionAnalyser analyser = new SolutionAnalyser(vrp,solution, new SolutionAnalyser.DistanceCalculator() { + @Override + public double getDistance(String fromLocationId, String toLocationId) { + return vrp.getTransportCosts().getTransportCost(fromLocationId,toLocationId,0.,null,null); + } + }); + VehicleRoute route = solution.getRoutes().iterator().next(); + Assert.assertEquals(70, analyser.getLoadDelivered(route).get(0), 0.01); + } + + @Test + public void deliveryLoadAtEnd_OfRoute1OfAnotherSolutionShouldWork(){ + buildAnotherScenarioWithOnlyOneVehicleAndWithoutAnyConstraintsBefore(); + SolutionAnalyser analyser = new SolutionAnalyser(vrp,solution, new SolutionAnalyser.DistanceCalculator() { + @Override + public double getDistance(String fromLocationId, String toLocationId) { + return vrp.getTransportCosts().getTransportCost(fromLocationId,toLocationId,0.,null,null); + } + }); + VehicleRoute route = solution.getRoutes().iterator().next(); + Assert.assertEquals(20, analyser.getLoadAtEnd(route).get(0), 0.01); + } + + @Test + public void deliveryLoad_onSolutionShouldWork(){ + SolutionAnalyser analyser = new SolutionAnalyser(vrp,solution, new SolutionAnalyser.DistanceCalculator() { + @Override + public double getDistance(String fromLocationId, String toLocationId) { + return vrp.getTransportCosts().getTransportCost(fromLocationId,toLocationId,0.,null,null); + } + }); + Assert.assertEquals(20, analyser.getLoadDelivered().get(0), 0.01); + } + + @Test + public void deliveryLoadAtEnd_onSolutionShouldWork(){ + SolutionAnalyser analyser = new SolutionAnalyser(vrp,solution, new SolutionAnalyser.DistanceCalculator() { + @Override + public double getDistance(String fromLocationId, String toLocationId) { + return vrp.getTransportCosts().getTransportCost(fromLocationId,toLocationId,0.,null,null); + } + }); + Assert.assertEquals(10, analyser.getLoadAtEnd().get(0), 0.01); + } + + @Test + public void deliveryLoad_onAnotherSolutionShouldWork(){ + buildAnotherScenarioWithOnlyOneVehicleAndWithoutAnyConstraintsBefore(); + SolutionAnalyser analyser = new SolutionAnalyser(vrp,solution, new SolutionAnalyser.DistanceCalculator() { + @Override + public double getDistance(String fromLocationId, String toLocationId) { + return vrp.getTransportCosts().getTransportCost(fromLocationId,toLocationId,0.,null,null); + } + }); + VehicleRoute route = solution.getRoutes().iterator().next(); + Assert.assertEquals(70, analyser.getLoadDelivered().get(0), 0.01); + } + + @Test + public void deliveryLoadAtEnd_onAnotherSolutionShouldWork(){ + buildAnotherScenarioWithOnlyOneVehicleAndWithoutAnyConstraintsBefore(); + SolutionAnalyser analyser = new SolutionAnalyser(vrp,solution, new SolutionAnalyser.DistanceCalculator() { + @Override + public double getDistance(String fromLocationId, String toLocationId) { + return vrp.getTransportCosts().getTransportCost(fromLocationId,toLocationId,0.,null,null); + } + }); + VehicleRoute route = solution.getRoutes().iterator().next(); + Assert.assertEquals(20, analyser.getLoadAtEnd().get(0), 0.01); + } + @Test public void operationTime_OfRoute1ShouldWork(){ SolutionAnalyser analyser = new SolutionAnalyser(vrp,solution, new SolutionAnalyser.DistanceCalculator() { @@ -1753,6 +2139,27 @@ public class SolutionAnalyserTest { assertTrue(violation); } + @Test + public void shipmentViolationOnSolution_shouldWorkWhenRemovingPickup(){ + buildAnotherScenarioWithOnlyOneVehicleAndWithoutAnyConstraintsBefore(); + VehicleRoute route = solution.getRoutes().iterator().next(); + SolutionPrinter.print(vrp,solution, SolutionPrinter.Print.VERBOSE); + TourActivity pickupShipment = route.getActivities().get(1); + route.getTourActivities().removeActivity(pickupShipment); + assertFalse(route.getTourActivities().hasActivity(pickupShipment)); + SolutionPrinter.print(vrp,solution, SolutionPrinter.Print.VERBOSE); + + SolutionAnalyser analyser = new SolutionAnalyser(vrp,solution, new SolutionAnalyser.DistanceCalculator() { + @Override + public double getDistance(String fromLocationId, String toLocationId) { + return vrp.getTransportCosts().getTransportCost(fromLocationId,toLocationId,0.,null,null); + } + }); + + Boolean violation = analyser.hasShipmentConstraintViolation(); + assertTrue(violation); + } + @Test public void skillViolationOnRoute_shouldWorkWhenViolated(){ SolutionAnalyser analyser = new SolutionAnalyser(vrp,solution, new SolutionAnalyser.DistanceCalculator() { @@ -1862,6 +2269,69 @@ public class SolutionAnalyserTest { assertFalse(violated); } + @Test + public void skillViolationOnSolution_shouldWork(){ + SolutionAnalyser analyser = new SolutionAnalyser(vrp,solution, new SolutionAnalyser.DistanceCalculator() { + @Override + public double getDistance(String fromLocationId, String toLocationId) { + return vrp.getTransportCosts().getTransportCost(fromLocationId,toLocationId,0.,null,null); + } + }); + Boolean violated = analyser.hasSkillConstraintViolation(); + assertTrue(violated); + } + + @Test + public void backhaulViolationOnSolution_shouldWork(){ + SolutionAnalyser analyser = new SolutionAnalyser(vrp,solution, new SolutionAnalyser.DistanceCalculator() { + @Override + public double getDistance(String fromLocationId, String toLocationId) { + return vrp.getTransportCosts().getTransportCost(fromLocationId,toLocationId,0.,null,null); + } + }); + Boolean violated = analyser.hasBackhaulConstraintViolation(); + assertFalse(violated); + } + + @Test + public void backhaulViolationOnSolution_shouldWorkWhenViolated(){ + buildAnotherScenarioWithOnlyOneVehicleAndWithoutAnyConstraintsBefore(); + SolutionAnalyser analyser = new SolutionAnalyser(vrp,solution, new SolutionAnalyser.DistanceCalculator() { + @Override + public double getDistance(String fromLocationId, String toLocationId) { + return vrp.getTransportCosts().getTransportCost(fromLocationId,toLocationId,0.,null,null); + } + }); + Boolean violated = analyser.hasBackhaulConstraintViolation(); + assertTrue(violated); + } + + @Test + public void shipmentViolationOnSolution_shouldWork(){ + buildAnotherScenarioWithOnlyOneVehicleAndWithoutAnyConstraintsBefore(); + SolutionAnalyser analyser = new SolutionAnalyser(vrp,solution, new SolutionAnalyser.DistanceCalculator() { + @Override + public double getDistance(String fromLocationId, String toLocationId) { + return vrp.getTransportCosts().getTransportCost(fromLocationId,toLocationId,0.,null,null); + } + }); + Boolean violated = analyser.hasShipmentConstraintViolation(); + assertFalse(violated); + } + + @Test + public void skillViolationOnSolution_shouldWorkWhenNotViolated() { + buildAnotherScenarioWithOnlyOneVehicleAndWithoutAnyConstraintsBefore(); + SolutionAnalyser analyser = new SolutionAnalyser(vrp, solution, new SolutionAnalyser.DistanceCalculator() { + @Override + public double getDistance(String fromLocationId, String toLocationId) { + return vrp.getTransportCosts().getTransportCost(fromLocationId, toLocationId, 0., null, null); + } + }); + Boolean violated = analyser.hasSkillConstraintViolation(); + assertFalse(violated); + } + diff --git a/jsprit-examples/src/main/java/jsprit/examples/VRPWithBackhaulsExample2.java b/jsprit-examples/src/main/java/jsprit/examples/VRPWithBackhaulsExample2.java index bcceb071..8fae4994 100644 --- a/jsprit-examples/src/main/java/jsprit/examples/VRPWithBackhaulsExample2.java +++ b/jsprit-examples/src/main/java/jsprit/examples/VRPWithBackhaulsExample2.java @@ -21,6 +21,7 @@ import jsprit.core.algorithm.VehicleRoutingAlgorithmBuilder; import jsprit.core.algorithm.selector.SelectBest; import jsprit.core.algorithm.state.StateManager; import jsprit.core.analysis.SolutionAnalyser; +import jsprit.core.problem.Capacity; import jsprit.core.problem.VehicleRoutingProblem; import jsprit.core.problem.constraint.ConstraintManager; import jsprit.core.problem.constraint.ServiceDeliveriesFirstConstraint; @@ -157,6 +158,15 @@ public class VRPWithBackhaulsExample2 { System.out.println("-----"); System.out.println("aggreate solution stats"); + System.out.println("total freight moved: " + Capacity.addup(analyser.getLoadAtBeginning(),analyser.getLoadPickedUp())); + System.out.println("total no. picks at beginning: " + analyser.getNumberOfPickupsAtBeginning()); + System.out.println("total no. picks on routes: " + analyser.getNumberOfPickups()); + System.out.println("total picked load at beginnnig: " + analyser.getLoadAtBeginning()); + System.out.println("total picked load on routes: " + analyser.getLoadPickedUp()); + System.out.println("total no. deliveries at end: " + analyser.getNumberOfDeliveriesAtEnd()); + System.out.println("total no. deliveries on routes: " + analyser.getNumberOfDeliveries()); + System.out.println("total delivered load at end: " + analyser.getLoadAtEnd()); + System.out.println("total delivered load on routes: " + analyser.getLoadDelivered()); System.out.println("total tp_distance: " + analyser.getDistance()); System.out.println("total tp_time: " + analyser.getTransportTime()); System.out.println("total waiting_time: " + analyser.getWaitingTime());