From e51b0c96a8c9dd57f28d89373742a1417fbaf528 Mon Sep 17 00:00:00 2001 From: Stefan Schroeder <4sschroeder@gmail.com> Date: Tue, 28 Jan 2014 14:34:07 +0100 Subject: [PATCH] add tests for VehicleRoute due to adding diff start- and end-locations deprecate VehicleRoute.newInstance(...) and remove resulting warnings --- .../core/algorithm/recreate/Inserter.java | 5 +- .../problem/solution/route/VehicleRoute.java | 78 ++++-- .../core/problem/vehicle/VehicleImpl.java | 3 + .../TestCalculatesServiceInsertion.java | 40 +-- ...alculatesServiceInsertionOnRouteLevel.java | 16 +- .../core/algorithm/recreate/TestInserter.java | 6 + .../TestTourStateUpdaterWithService.java | 32 +-- .../solution/route/TestVehicleRoute.java | 240 ++++++++++-------- .../route/VehicleRouteBuilderTest.java | 1 + 9 files changed, 233 insertions(+), 188 deletions(-) diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/Inserter.java b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/Inserter.java index 6c4d69d2..2a2c5fd0 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/Inserter.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/Inserter.java @@ -60,13 +60,13 @@ class Inserter { @Override public void handleJobInsertion(Job job, InsertionData iData, VehicleRoute route) { if(job instanceof Service){ + route.setVehicleAndDepartureTime(iData.getSelectedVehicle(),iData.getVehicleDepartureTime()); if(!iData.getSelectedVehicle().isReturnToDepot()){ if(iData.getDeliveryInsertionIndex()>=route.getTourActivities().getActivities().size()){ setEndLocation(route,(Service)job); } } route.getTourActivities().addActivity(iData.getDeliveryInsertionIndex(), this.activityFactory.createActivity((Service)job)); - route.setDepartureTime(iData.getVehicleDepartureTime()); } else delegator.handleJobInsertion(job, iData, route); } @@ -92,6 +92,7 @@ class Inserter { if(job instanceof Shipment){ TourActivity pickupShipment = this.activityFactory.createPickup((Shipment)job); TourActivity deliverShipment = this.activityFactory.createDelivery((Shipment)job); + route.setVehicleAndDepartureTime(iData.getSelectedVehicle(),iData.getVehicleDepartureTime()); if(!iData.getSelectedVehicle().isReturnToDepot()){ if(iData.getDeliveryInsertionIndex()>=route.getActivities().size()){ setEndLocation(route,(Shipment)job); @@ -99,7 +100,6 @@ class Inserter { } route.getTourActivities().addActivity(iData.getDeliveryInsertionIndex(), deliverShipment); route.getTourActivities().addActivity(iData.getPickupInsertionIndex(), pickupShipment); - route.setDepartureTime(iData.getVehicleDepartureTime()); } else delegator.handleJobInsertion(job, iData, route); } @@ -132,7 +132,6 @@ class Inserter { if(job == null) throw new IllegalStateException("cannot insert null-job"); if(!(vehicleRoute.getVehicle().getId().toString().equals(insertionData.getSelectedVehicle().getId().toString()))){ insertionListeners.informVehicleSwitched(vehicleRoute, vehicleRoute.getVehicle(), insertionData.getSelectedVehicle()); -// log.debug("vehicle switched from " + vehicleRoute.getVehicle().getId() + " to " + insertionData.getSelectedVehicle().getId()); vehicleRoute.setVehicleAndDepartureTime(insertionData.getSelectedVehicle(), insertionData.getVehicleDepartureTime()); } jobInsertionHandler.handleJobInsertion(job, insertionData, vehicleRoute); diff --git a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/VehicleRoute.java b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/VehicleRoute.java index 835458a6..86e66106 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/VehicleRoute.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/VehicleRoute.java @@ -64,8 +64,10 @@ public class VehicleRoute { * @param tour * @param driver * @param vehicle - * @return + * @return VehicleRoute + * @deprecated use VehicleRoute.Builder instead */ + @Deprecated public static VehicleRoute newInstance(TourActivities tour, Driver driver, Vehicle vehicle) { return new VehicleRoute(tour,driver,vehicle); } @@ -78,7 +80,7 @@ public class VehicleRoute { * @return */ public static VehicleRoute emptyRoute() { - return new VehicleRoute(TourActivities.emptyTour(), DriverImpl.noDriver(), VehicleImpl.createNoVehicle()); + return Builder.newInstance(VehicleImpl.createNoVehicle(), DriverImpl.noDriver()).build(); } /** @@ -92,11 +94,19 @@ public class VehicleRoute { /** * Returns new instance of this builder. * + *

Construction-settings of vehicleRoute: + *

startLocation == vehicle.getStartLocationId() + *

endLocation == vehicle.getEndLocationId() + *

departureTime == vehicle.getEarliestDepartureTime() + *

latestStart == Double.MAX_VALUE + *

earliestEnd == 0.0 + * * @param vehicle * @param driver * @return this builder */ public static Builder newInstance(Vehicle vehicle, Driver driver){ + if(vehicle == null || driver == null) throw new IllegalArgumentException("null arguments not accepted. ini emptyRoute with VehicleImpl.createNoVehicle() and DriverImpl.noDriver()"); return new Builder(vehicle,driver); } @@ -141,9 +151,11 @@ public class VehicleRoute { /** * Constructs the route-builder. * - *

Default startLocation is vehicle.getLocationId()
- * Default departureTime is vehicle.getEarliestDeparture()
- * Default endLocation is either vehicle.getLocationId() or (if !vehicle.isReturnToDepot()) last specified activityLocation + *

startLocation == vehicle.getStartLocationId() + *

endLocation == vehicle.getEndLocationId() + *

departureTime == vehicle.getEarliestDepartureTime() + *

latestStart == Double.MAX_VALUE + *

earliestEnd == 0.0 * @param vehicle * @param driver */ @@ -151,18 +163,22 @@ public class VehicleRoute { super(); this.vehicle = vehicle; this.driver = driver; - start = Start.newInstance(vehicle.getLocationId(), vehicle.getEarliestDeparture(), vehicle.getLatestArrival()); + start = Start.newInstance(vehicle.getStartLocationId(), vehicle.getEarliestDeparture(), Double.MAX_VALUE); start.setEndTime(vehicle.getEarliestDeparture()); - end = End.newInstance(vehicle.getLocationId(), vehicle.getEarliestDeparture(), vehicle.getLatestArrival()); + end = End.newInstance(vehicle.getLocationId(), 0.0, vehicle.getLatestArrival()); } /** * Sets the departure-time of the route, i.e. which is the time the vehicle departs from start-location. * + *

Note that departureTime cannot be lower than earliestDepartureTime of vehicle. + * * @param departureTime - * @return + * @return builder + * @throws IllegalArgumentException if departureTime < vehicle.getEarliestDeparture() */ public Builder setDepartureTime(double departureTime){ + if(departureTime < start.getEndTime()) throw new IllegalArgumentException("departureTime < vehicle.getEarliestDepartureTime(). this must not be."); start.setEndTime(departureTime); return this; } @@ -172,8 +188,10 @@ public class VehicleRoute { * * @param endTime * @return this builder + * @throws IllegalArgumentException if endTime > vehicle.getLatestArrival() */ public Builder setRouteEndArrivalTime(double endTime){ + if(endTime > vehicle.getLatestArrival()) throw new IllegalArgumentException("endTime > vehicle.getLatestArrival(). this must not be."); end.setArrTime(endTime); return this; } @@ -306,6 +324,11 @@ public class VehicleRoute { private End end; + /** + * Copy constructor copying a route. + * + * @param route + */ private VehicleRoute(VehicleRoute route){ this.start = Start.copyOf(route.getStart()); this.end = End.copyOf(route.getEnd()); @@ -314,6 +337,7 @@ public class VehicleRoute { this.driver = route.getDriver(); } + @Deprecated private VehicleRoute(TourActivities tour, Driver driver, Vehicle vehicle) { super(); verify(tour, driver, vehicle); @@ -323,7 +347,11 @@ public class VehicleRoute { setStartAndEnd(vehicle, vehicle.getEarliestDeparture()); } - + /** + * Constructs route. + * + * @param builder + */ private VehicleRoute(Builder builder){ this.tourActivities = builder.tourActivities; this.vehicle = builder.vehicle; @@ -332,6 +360,14 @@ public class VehicleRoute { this.end = builder.end; } + /** + * + * @param tour + * @param driver + * @param vehicle + * @deprecated verification is a task of VehicleRoute.Builder + */ + @Deprecated private void verify(TourActivities tour, Driver driver, Vehicle vehicle) { if(tour == null || driver == null || vehicle == null) throw new IllegalStateException("null is not allowed for tour, driver or vehicle. use emptyRoute. use Tour.emptyTour, DriverImpl.noDriver() and VehicleImpl.noVehicle() instead." + "\n\tor make it easier and use VehicleRoute.emptyRoute()"); @@ -349,6 +385,11 @@ public class VehicleRoute { return Collections.unmodifiableList(tourActivities.getActivities()); } + /** + * Returns TourActivities. + * + * @return {@link TourActivities} + */ public TourActivities getTourActivities() { return tourActivities; } @@ -388,17 +429,7 @@ public class VehicleRoute { */ public void setVehicleAndDepartureTime(Vehicle vehicle, double vehicleDepTime){ this.vehicle = vehicle; - if(start == null && end == null){ - start = Start.newInstance(vehicle.getStartLocationId(), vehicle.getEarliestDeparture(), vehicle.getLatestArrival()); - end = End.newInstance(vehicle.getEndLocationId(), vehicle.getEarliestDeparture(), vehicle.getLatestArrival()); - } - start.setEndTime(Math.max(vehicleDepTime, vehicle.getEarliestDeparture())); - start.setTheoreticalEarliestOperationStartTime(vehicle.getEarliestDeparture()); - start.setTheoreticalLatestOperationStartTime(vehicle.getLatestArrival()); - start.setLocationId(vehicle.getLocationId()); - end.setLocationId(vehicle.getLocationId()); - end.setTheoreticalEarliestOperationStartTime(vehicle.getEarliestDeparture()); - end.setTheoreticalLatestOperationStartTime(vehicle.getLatestArrival()); + setStartAndEnd(vehicle, vehicleDepTime); } /** @@ -444,14 +475,17 @@ public class VehicleRoute { * Sets departureTime of this route, i.e. the time the vehicle departs from its start-location. * * @param vehicleDepTime + * @deprecated use .setVehicleAndDepartureTime(...) instead (vehicle requires departureTime and the other way around, and earliestDepartureTime + * of a vehicle is a physical constraint of the vehicle and cannot be broken. Using this method might break this constraint.) */ + @Deprecated public void setDepartureTime(double vehicleDepTime){ if(start == null) throw new IllegalStateException("cannot set departureTime without having a vehicle on this route. use setVehicle(vehicle,departureTime) instead."); start.setEndTime(vehicleDepTime); } /** - * Returns the departureTime of this vehicle. + * Returns the departureTime of this vehicle in this route. * * @return departureTime * @throws IllegalStateException if start is null @@ -464,7 +498,7 @@ public class VehicleRoute { /** * Returns tour if tour-activity-sequence is empty, i.e. to activity on the tour yet. * - * @return + * @return true if route is empty */ public boolean isEmpty() { return tourActivities.isEmpty(); 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 90ac6325..6a534e7e 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 @@ -250,6 +250,9 @@ public class VehicleImpl implements Vehicle { * or (endLocationId!=null AND returnToDepot=false) */ public VehicleImpl build(){ + if((locationId == null && locationCoord == null) && (startLocationId == null && startLocationCoord == null)){ + throw new IllegalStateException("vehicle requires startLocation. but neither locationId nor locationCoord nor startLocationId nor startLocationCoord has been set"); + } if(locationId == null && locationCoord != null) { locationId = locationCoord.toString(); startLocationId = locationCoord.toString(); diff --git a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestCalculatesServiceInsertion.java b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestCalculatesServiceInsertion.java index 675bcb98..9e820e3f 100644 --- a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestCalculatesServiceInsertion.java +++ b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestCalculatesServiceInsertion.java @@ -34,9 +34,7 @@ import jsprit.core.problem.driver.DriverImpl.NoDriver; import jsprit.core.problem.job.Job; import jsprit.core.problem.job.Service; import jsprit.core.problem.solution.route.VehicleRoute; -import jsprit.core.problem.solution.route.activity.ServiceActivity; import jsprit.core.problem.solution.route.activity.TimeWindow; -import jsprit.core.problem.solution.route.activity.TourActivities; import jsprit.core.problem.solution.route.activity.TourActivity; import jsprit.core.problem.vehicle.Vehicle; @@ -184,12 +182,9 @@ public class TestCalculatesServiceInsertion { @Test public void whenInsertingTheFirstJobInAnEmptyTourWithVehicle_itCalculatesMarginalCostChanges(){ - TourActivities tour = new TourActivities(); - - VehicleRoute route = VehicleRoute.newInstance(tour,driver,vehicle); + VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, driver).build(); states.informInsertionStarts(Arrays.asList(route), null); -// stateUpdater.update(route); - + InsertionData iData = serviceInsertion.getInsertionData(route, first, vehicle, vehicle.getEarliestDeparture(), null, Double.MAX_VALUE); assertEquals(20.0, iData.getInsertionCost(), 0.2); assertEquals(0, iData.getDeliveryInsertionIndex()); @@ -197,10 +192,7 @@ public class TestCalculatesServiceInsertion { @Test public void whenInsertingTheSecondJobInAnNonEmptyTourWithVehicle_itCalculatesMarginalCostChanges(){ - TourActivities tour = new TourActivities(); - tour.addActivity(ServiceActivity.newInstance(first)); - - VehicleRoute route = VehicleRoute.newInstance(tour,driver,vehicle); + VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, driver).addService(first).build(); states.informInsertionStarts(Arrays.asList(route), null); InsertionData iData = serviceInsertion.getInsertionData(route, second, vehicle, vehicle.getEarliestDeparture(), null, Double.MAX_VALUE); @@ -210,11 +202,7 @@ public class TestCalculatesServiceInsertion { @Test public void whenInsertingThirdJobWithVehicle_itCalculatesMarginalCostChanges(){ - TourActivities tour = new TourActivities(); - tour.addActivity(ServiceActivity.newInstance(first)); - tour.addActivity(ServiceActivity.newInstance(second)); - - VehicleRoute route = VehicleRoute.newInstance(tour,driver,vehicle); + VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, driver).addService(first).addService(second).build(); states.informInsertionStarts(Arrays.asList(route), null); InsertionData iData = serviceInsertion.getInsertionData(route, third, vehicle, vehicle.getEarliestDeparture(), null, Double.MAX_VALUE); @@ -224,11 +212,7 @@ public class TestCalculatesServiceInsertion { @Test public void whenInsertingThirdJobWithNewVehicle_itCalculatesMarginalCostChanges(){ - TourActivities tour = new TourActivities(); - tour.addActivity(ServiceActivity.newInstance(first)); - tour.addActivity(ServiceActivity.newInstance(second)); - - VehicleRoute route = VehicleRoute.newInstance(tour,driver,vehicle); + VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, driver).addService(first).addService(second).build(); states.informInsertionStarts(Arrays.asList(route), null); InsertionData iData = serviceInsertion.getInsertionData(route, third, newVehicle, newVehicle.getEarliestDeparture(), null, Double.MAX_VALUE); @@ -238,11 +222,7 @@ public class TestCalculatesServiceInsertion { @Test public void whenInsertingASecondJobWithAVehicle_itCalculatesLocalMarginalCostChanges(){ - TourActivities tour = new TourActivities(); - tour.addActivity(ServiceActivity.newInstance(first)); - tour.addActivity(ServiceActivity.newInstance(third)); - - VehicleRoute route = VehicleRoute.newInstance(tour,driver,vehicle); + VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, driver).addService(first).addService(third).build(); states.informInsertionStarts(Arrays.asList(route), null); InsertionData iData = serviceInsertion.getInsertionData(route, second, vehicle, vehicle.getEarliestDeparture(), null, Double.MAX_VALUE); @@ -252,13 +232,7 @@ public class TestCalculatesServiceInsertion { @Test public void whenInsertingASecondJobWithANewVehicle_itCalculatesLocalMarginalCostChanges(){ - TourActivities tour = new TourActivities(); - tour.addActivity(ServiceActivity.newInstance(first)); - tour.addActivity(ServiceActivity.newInstance(third)); - - VehicleRoute route = VehicleRoute.newInstance(tour,driver,vehicle); -// route.addActivity(states.getActivity(first,true)); -// route.addActivity(states.getActivity(third,true)); + VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, driver).addService(first).addService(third).build(); states.informInsertionStarts(Arrays.asList(route), null); InsertionData iData = serviceInsertion.getInsertionData(route, second, newVehicle, newVehicle.getEarliestDeparture(), null, Double.MAX_VALUE); diff --git a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestCalculatesServiceInsertionOnRouteLevel.java b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestCalculatesServiceInsertionOnRouteLevel.java index b8e45474..98f82120 100644 --- a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestCalculatesServiceInsertionOnRouteLevel.java +++ b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestCalculatesServiceInsertionOnRouteLevel.java @@ -80,6 +80,8 @@ public class TestCalculatesServiceInsertionOnRouteLevel { vehicle = mock(Vehicle.class); when(vehicle.getCapacity()).thenReturn(1000); when(vehicle.getLocationId()).thenReturn("0,0"); + when(vehicle.getStartLocationId()).thenReturn("0,0"); + when(vehicle.getEndLocationId()).thenReturn("0,0"); when(vehicle.getEarliestDeparture()).thenReturn(0.0); when(vehicle.getLatestArrival()).thenReturn(100.0); when(vehicle.isReturnToDepot()).thenReturn(true); @@ -87,6 +89,8 @@ public class TestCalculatesServiceInsertionOnRouteLevel { newVehicle = mock(Vehicle.class); when(newVehicle.getCapacity()).thenReturn(1000); when(newVehicle.getLocationId()).thenReturn("0,0"); + when(newVehicle.getStartLocationId()).thenReturn("0,0"); + when(newVehicle.getEndLocationId()).thenReturn("0,0"); when(newVehicle.getEarliestDeparture()).thenReturn(0.0); when(newVehicle.getLatestArrival()).thenReturn(100.0); when(newVehicle.isReturnToDepot()).thenReturn(true); @@ -175,9 +179,7 @@ public class TestCalculatesServiceInsertionOnRouteLevel { @Test public void whenInsertingTheFirstJobInAnEmptyTourWithVehicle_itCalculatesMarginalCostChanges(){ - TourActivities tour = new TourActivities(); - - VehicleRoute route = VehicleRoute.newInstance(tour,driver,vehicle); + VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, driver).build(); states.informInsertionStarts(Arrays.asList(route), null); InsertionData iData = serviceInsertion.getInsertionData(route, first, vehicle, vehicle.getEarliestDeparture(), null, Double.MAX_VALUE); @@ -191,7 +193,7 @@ public class TestCalculatesServiceInsertionOnRouteLevel { tour.addActivity(ServiceActivity.newInstance(first)); tour.addActivity(ServiceActivity.newInstance(second)); - VehicleRoute route = VehicleRoute.newInstance(tour,driver,vehicle); + VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, driver).addService(first).addService(second).build(); states.informInsertionStarts(Arrays.asList(route), null); InsertionData iData = serviceInsertion.getInsertionData(route, third, vehicle, vehicle.getEarliestDeparture(), null, Double.MAX_VALUE); @@ -205,7 +207,7 @@ public class TestCalculatesServiceInsertionOnRouteLevel { tour.addActivity(ServiceActivity.newInstance(first)); tour.addActivity(ServiceActivity.newInstance(second)); - VehicleRoute route = VehicleRoute.newInstance(tour,driver,vehicle); + VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, driver).addService(first).addService(second).build(); states.informInsertionStarts(Arrays.asList(route), null); InsertionData iData = serviceInsertion.getInsertionData(route, third, newVehicle, vehicle.getEarliestDeparture(), null, Double.MAX_VALUE); @@ -219,7 +221,7 @@ public class TestCalculatesServiceInsertionOnRouteLevel { tour.addActivity(ServiceActivity.newInstance(first)); tour.addActivity(ServiceActivity.newInstance(third)); - VehicleRoute route = VehicleRoute.newInstance(tour,driver,vehicle); + VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, driver).addService(first).addService(third).build(); states.informInsertionStarts(Arrays.asList(route), null); InsertionData iData = serviceInsertion.getInsertionData(route, second, vehicle, vehicle.getEarliestDeparture(), null, Double.MAX_VALUE); @@ -233,7 +235,7 @@ public class TestCalculatesServiceInsertionOnRouteLevel { tour.addActivity(ServiceActivity.newInstance(first)); tour.addActivity(ServiceActivity.newInstance(third)); - VehicleRoute route = VehicleRoute.newInstance(tour,driver,vehicle); + VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, driver).addService(first).addService(third).build(); states.informInsertionStarts(Arrays.asList(route), null); InsertionData iData = serviceInsertion.getInsertionData(route, second, newVehicle, vehicle.getEarliestDeparture(), null, Double.MAX_VALUE); diff --git a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestInserter.java b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestInserter.java index 00bbd067..672d3236 100644 --- a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestInserter.java +++ b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestInserter.java @@ -23,6 +23,8 @@ public class TestInserter { Service service = mock(Service.class); Vehicle vehicle = mock(Vehicle.class); when(vehicle.getLocationId()).thenReturn("vehLoc"); + when(vehicle.getStartLocationId()).thenReturn("vehLoc"); + when(vehicle.getEndLocationId()).thenReturn("vehLoc"); when(vehicle.isReturnToDepot()).thenReturn(true); when(vehicle.getId()).thenReturn("vehId"); @@ -48,6 +50,8 @@ public class TestInserter { Service service = mock(Service.class); Vehicle vehicle = mock(Vehicle.class); when(vehicle.getLocationId()).thenReturn("vehLoc"); + when(vehicle.getStartLocationId()).thenReturn("vehLoc"); + when(vehicle.getEndLocationId()).thenReturn("vehLoc"); when(vehicle.isReturnToDepot()).thenReturn(false); when(vehicle.getId()).thenReturn("vehId"); @@ -73,6 +77,8 @@ public class TestInserter { Shipment shipment = mock(Shipment.class); Vehicle vehicle = mock(Vehicle.class); when(vehicle.getLocationId()).thenReturn("vehLoc"); + when(vehicle.getStartLocationId()).thenReturn("vehLoc"); + when(vehicle.getEndLocationId()).thenReturn("vehLoc"); when(vehicle.isReturnToDepot()).thenReturn(true); when(vehicle.getId()).thenReturn("vehId"); diff --git a/jsprit-core/src/test/java/jsprit/core/algorithm/state/TestTourStateUpdaterWithService.java b/jsprit-core/src/test/java/jsprit/core/algorithm/state/TestTourStateUpdaterWithService.java index 83ec3285..f659b405 100644 --- a/jsprit-core/src/test/java/jsprit/core/algorithm/state/TestTourStateUpdaterWithService.java +++ b/jsprit-core/src/test/java/jsprit/core/algorithm/state/TestTourStateUpdaterWithService.java @@ -59,6 +59,10 @@ public class TestTourStateUpdaterWithService { private VehicleRoute vehicleRoute; + private ServiceActivity act1; + + private ServiceActivity act2; + @Before public void setUp() { @@ -115,11 +119,12 @@ public class TestTourStateUpdaterWithService { states.addStateUpdater(new UpdateVariableCosts(vrp.getActivityCosts(), vrp.getTransportCosts(), states)); states.addStateUpdater(new UpdateActivityTimes(vrp.getTransportCosts())); - tour = new TourActivities(); - tour.addActivity(ServiceActivity.newInstance(firstService)); - tour.addActivity(ServiceActivity.newInstance(secondService)); - - vehicleRoute = VehicleRoute.newInstance(tour,DriverImpl.noDriver(),vehicle); + act1 = ServiceActivity.newInstance(firstService); + act2 = ServiceActivity.newInstance(secondService); + + vehicleRoute = VehicleRoute.Builder.newInstance(vehicle, DriverImpl.noDriver()).build();//.newInstance(tour,DriverImpl.noDriver(),vehicle); + vehicleRoute.getTourActivities().addActivity(act1); + vehicleRoute.getTourActivities().addActivity(act2); } @Test @@ -135,27 +140,24 @@ public class TestTourStateUpdaterWithService { assertEquals(0.0, vehicleRoute.getStart().getEndTime(),0.05); assertEquals(vehicleRoute.getVehicle().getLocationId(), vehicleRoute.getStart().getLocationId()); assertEquals(vehicleRoute.getVehicle().getEarliestDeparture(), vehicleRoute.getStart().getTheoreticalEarliestOperationStartTime(),0.05); - assertEquals(vehicleRoute.getVehicle().getLatestArrival(), vehicleRoute.getStart().getTheoreticalLatestOperationStartTime(),0.05); + assertEquals(Double.MAX_VALUE, vehicleRoute.getStart().getTheoreticalLatestOperationStartTime(),0.05); } @Test public void testStatesOfAct1(){ states.informInsertionStarts(Arrays.asList(vehicleRoute), null); - assertEquals(10.0, states.getActivityState(tour.getActivities().get(0), StateFactory.COSTS).toDouble(),0.05); - assertEquals(5.0, states.getActivityState(tour.getActivities().get(0), StateFactory.LOAD).toDouble(),0.05); -// assertEquals(10.0, states.getActivityState(tour.getActivities().get(0), StateTypes.EARLIEST_OPERATION_START_TIME).toDouble(),0.05); - assertEquals(20.0, states.getActivityState(tour.getActivities().get(0), StateFactory.LATEST_OPERATION_START_TIME).toDouble(),0.05); + assertEquals(10.0, states.getActivityState(act1, StateFactory.COSTS).toDouble(),0.05); + assertEquals(5.0, states.getActivityState(act1, StateFactory.LOAD).toDouble(),0.05); + assertEquals(20.0, states.getActivityState(act1, StateFactory.LATEST_OPERATION_START_TIME).toDouble(),0.05); } @Test public void testStatesOfAct2(){ states.informInsertionStarts(Arrays.asList(vehicleRoute), null); - - assertEquals(30.0, states.getActivityState(tour.getActivities().get(1), StateFactory.COSTS).toDouble(),0.05); - assertEquals(10.0, states.getActivityState(tour.getActivities().get(1), StateFactory.LOAD).toDouble(),0.05); -// assertEquals(10.0, states.getActivityState(tour.getActivities().get(0), StateTypes.EARLIEST_OPERATION_START_TIME).toDouble(),0.05); - assertEquals(40.0, states.getActivityState(tour.getActivities().get(1), StateFactory.LATEST_OPERATION_START_TIME).toDouble(),0.05); + assertEquals(30.0, states.getActivityState(act2, StateFactory.COSTS).toDouble(),0.05); + assertEquals(10.0, states.getActivityState(act2, StateFactory.LOAD).toDouble(),0.05); + assertEquals(40.0, states.getActivityState(act2, StateFactory.LATEST_OPERATION_START_TIME).toDouble(),0.05); } @Test diff --git a/jsprit-core/src/test/java/jsprit/core/problem/solution/route/TestVehicleRoute.java b/jsprit-core/src/test/java/jsprit/core/problem/solution/route/TestVehicleRoute.java index 135ee7ec..6c78d14a 100644 --- a/jsprit-core/src/test/java/jsprit/core/problem/solution/route/TestVehicleRoute.java +++ b/jsprit-core/src/test/java/jsprit/core/problem/solution/route/TestVehicleRoute.java @@ -24,10 +24,7 @@ import java.util.Iterator; import jsprit.core.problem.driver.DriverImpl; import jsprit.core.problem.driver.DriverImpl.NoDriver; import jsprit.core.problem.job.Service; -import jsprit.core.problem.solution.route.VehicleRoute; import jsprit.core.problem.solution.route.activity.ServiceActivity; -import jsprit.core.problem.solution.route.activity.Start; -import jsprit.core.problem.solution.route.activity.TourActivities; import jsprit.core.problem.solution.route.activity.TourActivity; import jsprit.core.problem.vehicle.Vehicle; import jsprit.core.problem.vehicle.VehicleImpl; @@ -47,12 +44,10 @@ public class TestVehicleRoute { vehicle = VehicleImpl.Builder.newInstance("v").setLocationId("loc").setType(VehicleTypeImpl.Builder.newInstance("yo", 0).build()).build(); driver = DriverImpl.noDriver(); } - - - + @Test public void whenBuildingEmptyRouteCorrectly_go(){ - VehicleRoute route = VehicleRoute.newInstance(TourActivities.emptyTour(),DriverImpl.noDriver(),VehicleImpl.createNoVehicle()); + VehicleRoute route = VehicleRoute.Builder.newInstance(VehicleImpl.createNoVehicle(),DriverImpl.noDriver()).build(); assertTrue(route!=null); } @@ -74,56 +69,17 @@ public class TestVehicleRoute { assertEquals(0,count); } - @Test(expected=IllegalStateException.class) - public void whenBuildingEmptyRoute_(){ + @Test(expected=IllegalArgumentException.class) + public void whenBuildingRouteWithNulls_itThrowsException(){ @SuppressWarnings("unused") - VehicleRoute route = VehicleRoute.newInstance(null,null,null); + VehicleRoute route = VehicleRoute.Builder.newInstance(null, null).build(); } - @Test(expected=IllegalStateException.class) - public void whenBuildingRouteWithNonEmptyTour_throwException(){ - TourActivities tour = new TourActivities(); - tour.addActivity(ServiceActivity.newInstance(Service.Builder.newInstance("jo", 10).build())); - @SuppressWarnings("unused") - VehicleRoute route = VehicleRoute.newInstance(tour,DriverImpl.noDriver(),VehicleImpl.createNoVehicle()); - } - - @Test - public void whenBuildingEmptyTour_tourIterIteratesOverAnEmptyList(){ - TourActivities tour = new TourActivities(); - Vehicle v = VehicleImpl.Builder.newInstance("v").setLocationId("loc").setType(VehicleTypeImpl.Builder.newInstance("yo", 0).build()).build(); - VehicleRoute route = VehicleRoute.newInstance(tour,DriverImpl.noDriver(),v); - Iterator iter = route.getTourActivities().iterator(); - int count = 0; - while(iter.hasNext()){ - @SuppressWarnings("unused") - TourActivity act = iter.next(); - count++; - } - assertEquals(0,count); - } - - @Test - public void whenBuildingANonEmptyTour_tourIterIteratesOverActivitiesCorrectly(){ - TourActivities tour = new TourActivities(); - tour.addActivity(Start.newInstance("", 0, 0)); - VehicleRoute route = VehicleRoute.newInstance(tour, driver, vehicle); - Iterator iter = route.getTourActivities().iterator(); - int count = 0; - while(iter.hasNext()){ - @SuppressWarnings("unused") - TourActivity act = iter.next(); - count++; - } - assertEquals(1,count); - } - - @Test public void whenBuildingANonEmptyTour2Times_tourIterIteratesOverActivitiesCorrectly(){ - TourActivities tour = new TourActivities(); - tour.addActivity(ServiceActivity.newInstance(Service.Builder.newInstance("2", 30).setLocationId("1").build())); - VehicleRoute route = VehicleRoute.newInstance(tour, driver, vehicle); + VehicleRoute.Builder routeBuilder = VehicleRoute.Builder.newInstance(vehicle, driver); + routeBuilder.addService(Service.Builder.newInstance("2", 30).setLocationId("1").build()); + VehicleRoute route = routeBuilder.build(); { Iterator iter = route.getTourActivities().iterator(); @@ -136,7 +92,7 @@ public class TestVehicleRoute { assertEquals(1,count); } { - tour.addActivity(ServiceActivity.newInstance(Service.Builder.newInstance("3", 30).setLocationId("1").build())); + route.getTourActivities().addActivity(ServiceActivity.newInstance(Service.Builder.newInstance("3", 30).setLocationId("1").build())); Iterator iter = route.getTourActivities().iterator(); int count = 0; while(iter.hasNext()){ @@ -150,8 +106,7 @@ public class TestVehicleRoute { @Test public void whenBuildingANonEmptyTour_tourReverseIterIteratesOverActivitiesCorrectly(){ - TourActivities tour = new TourActivities(); - VehicleRoute route = VehicleRoute.newInstance(tour, driver, vehicle); + VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, driver).build(); Iterator iter = route.getTourActivities().reverseActivityIterator(); int count = 0; while(iter.hasNext()){ @@ -164,9 +119,9 @@ public class TestVehicleRoute { @Test public void whenBuildingANonEmptyTourV2_tourReverseIterIteratesOverActivitiesCorrectly(){ - TourActivities tour = new TourActivities(); - tour.addActivity(ServiceActivity.newInstance(Service.Builder.newInstance("2", 30).setLocationId("1").build())); - VehicleRoute route = VehicleRoute.newInstance(tour, driver, vehicle); + VehicleRoute.Builder routeBuilder = VehicleRoute.Builder.newInstance(vehicle, driver); + routeBuilder.addService(Service.Builder.newInstance("2", 30).setLocationId("1").build()); + VehicleRoute route = routeBuilder.build(); Iterator iter = route.getTourActivities().reverseActivityIterator(); int count = 0; while(iter.hasNext()){ @@ -177,78 +132,147 @@ public class TestVehicleRoute { assertEquals(1,count); } - @Test - public void whenBuildingANonEmptyTourV3_tourReverseIterIteratesOverActivitiesCorrectly(){ - TourActivities tour = new TourActivities(); - tour.addActivity(ServiceActivity.newInstance(Service.Builder.newInstance("2", 30).setLocationId("1").build())); - ServiceActivity del = ServiceActivity.newInstance(Service.Builder.newInstance("3", 30).setLocationId("1").build()); - tour.addActivity(del); - VehicleRoute route = VehicleRoute.newInstance(tour, driver, vehicle); - Iterator iter = route.getTourActivities().reverseActivityIterator(); - int count = 0; - TourActivity memAct = null; - while(iter.hasNext()){ - TourActivity act = iter.next(); - if(count==0) memAct = act; - count++; - } - assertEquals(memAct,del); - } - - @Test - public void whenBuildingANonEmptyTourV4_tourReverseIterIteratesOverActivitiesCorrectly(){ - TourActivities tour = new TourActivities(); - tour.addActivity(ServiceActivity.newInstance(Service.Builder.newInstance("2", 30).setLocationId("1").build())); - ServiceActivity del = ServiceActivity.newInstance(Service.Builder.newInstance("3", 30).setLocationId("1").build()); - tour.addActivity(del); - VehicleRoute route = VehicleRoute.newInstance(tour, driver, vehicle); - Iterator iter = route.getTourActivities().reverseActivityIterator(); - int count = 0; - TourActivity memAct = null; - while(iter.hasNext()){ - TourActivity act = iter.next(); - if(count==0) memAct = act; - count++; - } - assertEquals(memAct,del); - assertEquals(2,count); - } - @Test public void whenBuildingANonEmptyTour2Times_tourReverseIterIteratesOverActivitiesCorrectly(){ - TourActivities tour = new TourActivities(); - tour.addActivity(ServiceActivity.newInstance(Service.Builder.newInstance("2", 30).setLocationId("1").build())); - ServiceActivity del = ServiceActivity.newInstance(Service.Builder.newInstance("3", 30).setLocationId("1").build()); - tour.addActivity(del); - VehicleRoute route = VehicleRoute.newInstance(tour, driver, vehicle); + VehicleRoute.Builder routeBuilder = VehicleRoute.Builder.newInstance(vehicle, driver); + routeBuilder.addService(Service.Builder.newInstance("2", 30).setLocationId("1").build()); + routeBuilder.addService(Service.Builder.newInstance("3", 30).setLocationId("2").build()); + VehicleRoute route = routeBuilder.build(); { Iterator iter = route.getTourActivities().reverseActivityIterator(); int count = 0; - TourActivity memAct = null; while(iter.hasNext()){ TourActivity act = iter.next(); - if(count==0) memAct = act; + if(count==0) { + assertEquals("2",act.getLocationId()); + } count++; } - assertEquals(memAct,del); assertEquals(2,count); } { Iterator secondIter = route.getTourActivities().reverseActivityIterator(); int count = 0; - TourActivity memAct = null; while(secondIter.hasNext()){ TourActivity act = secondIter.next(); - if(count==0) memAct = act; + if(count==0) { + assertEquals("2",act.getLocationId()); + } count++; } - assertEquals(memAct,del); assertEquals(2,count); } } - public void whenBuildingRouteWithVehicleThatHasDifferentStartAndEndLocation_routeMustBeBuiltCorrectly(){ - + public void whenBuildingRouteWithVehicleThatHasDifferentStartAndEndLocation_routeMustHaveCorrectStartLocation(){ + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setStartLocationId("start").setEndLocationId("end").build(); + VehicleRoute vRoute = VehicleRoute.Builder.newInstance(vehicle, DriverImpl.noDriver()).build(); + assertTrue(vRoute.getStart().getLocationId().equals("start")); + } + + public void whenBuildingRouteWithVehicleThatHasDifferentStartAndEndLocation_routeMustHaveCorrectEndLocation(){ + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setStartLocationId("start").setEndLocationId("end").build(); + VehicleRoute vRoute = VehicleRoute.Builder.newInstance(vehicle, DriverImpl.noDriver()).build(); + assertTrue(vRoute.getEnd().getLocationId().equals("end")); + } + + public void whenBuildingRouteWithVehicleThatHasSameStartAndEndLocation_routeMustHaveCorrectStartLocation(){ + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setStartLocationId("start").setEndLocationId("start").build(); + VehicleRoute vRoute = VehicleRoute.Builder.newInstance(vehicle, DriverImpl.noDriver()).build(); + assertTrue(vRoute.getStart().getLocationId().equals("start")); + } + + public void whenBuildingRouteWithVehicleThatHasSameStartAndEndLocation_routeMustHaveCorrectEndLocation(){ + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setStartLocationId("start").setEndLocationId("start").build(); + VehicleRoute vRoute = VehicleRoute.Builder.newInstance(vehicle, DriverImpl.noDriver()).build(); + assertTrue(vRoute.getEnd().getLocationId().equals("start")); + } + + public void whenBuildingRouteWithVehicleThatHasSameStartAndEndLocation_routeMustHaveCorrectStartLocationV2(){ + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setLocationId("start").setEndLocationId("start").build(); + VehicleRoute vRoute = VehicleRoute.Builder.newInstance(vehicle, DriverImpl.noDriver()).build(); + assertTrue(vRoute.getStart().getLocationId().equals("start")); + } + + public void whenBuildingRouteWithVehicleThatHasSameStartAndEndLocation_routeMustHaveCorrectEndLocationV2(){ + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setLocationId("start").setEndLocationId("start").build(); + VehicleRoute vRoute = VehicleRoute.Builder.newInstance(vehicle, DriverImpl.noDriver()).build(); + assertTrue(vRoute.getEnd().getLocationId().equals("start")); + } + + public void whenBuildingRouteWithVehicleThatHasDifferentStartAndEndLocation_routeMustHaveCorrectDepartureTime(){ + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setEarliestStart(100).setStartLocationId("start").setEndLocationId("end").build(); + VehicleRoute vRoute = VehicleRoute.Builder.newInstance(vehicle, DriverImpl.noDriver()).build(); + assertEquals(vRoute.getDepartureTime(),100.0,0.01); + assertEquals(vRoute.getStart().getEndTime(),100.0,0.01); + } + + public void whenBuildingRouteWithVehicleThatHasDifferentStartAndEndLocation_routeMustHaveCorrectEndTime(){ + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setEarliestStart(100).setLatestArrival(200).setStartLocationId("start").setEndLocationId("end").build(); + VehicleRoute vRoute = VehicleRoute.Builder.newInstance(vehicle, DriverImpl.noDriver()).build(); + assertEquals(vRoute.getEnd().getArrTime(),100.0,0.01); + assertEquals(vRoute.getEnd().getTheoreticalLatestOperationStartTime(),100.0,0.01); + } + + public void whenSettingDepartureTimeInBetweenEarliestStartAndLatestArr_routeMustHaveCorrectDepartureTime(){ + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setEarliestStart(100).setLatestArrival(200).setStartLocationId("start").setEndLocationId("end").build(); + VehicleRoute vRoute = VehicleRoute.Builder.newInstance(vehicle, DriverImpl.noDriver()).build(); + vRoute.setVehicleAndDepartureTime(vehicle, 150.0); + assertEquals(vRoute.getStart().getEndTime(),150.0,0.01); + assertEquals(vRoute.getDepartureTime(),150.0,0.01); + } + + public void whenSettingDepartureEarlierThanEarliestStart_routeMustHaveEarliestDepTimeAsDepTime(){ + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setEarliestStart(100).setLatestArrival(200).setStartLocationId("start").setEndLocationId("end").build(); + VehicleRoute vRoute = VehicleRoute.Builder.newInstance(vehicle, DriverImpl.noDriver()).build(); + vRoute.setVehicleAndDepartureTime(vehicle, 50.0); + assertEquals(vRoute.getStart().getEndTime(),100.0,0.01); + assertEquals(vRoute.getDepartureTime(),100.0,0.01); + } + + public void whenSettingDepartureTimeLaterThanLatestArrival_routeMustHaveThisDepTime(){ + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setEarliestStart(100).setLatestArrival(200).setStartLocationId("start").setEndLocationId("end").build(); + VehicleRoute vRoute = VehicleRoute.Builder.newInstance(vehicle, DriverImpl.noDriver()).build(); + vRoute.setVehicleAndDepartureTime(vehicle, 50.0); + assertEquals(vRoute.getStart().getEndTime(),100.0,0.01); + assertEquals(vRoute.getDepartureTime(),100.0,0.01); + } + + public void whenCreatingEmptyRoute_itMustReturnEmptyRoute(){ + @SuppressWarnings("unused") + VehicleRoute route = VehicleRoute.emptyRoute(); + assertTrue(true); + } + + public void whenIniRouteWithNewVehicle_startLocationMustBeCorrect(){ + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setEarliestStart(100).setLatestArrival(200).setStartLocationId("start").setEndLocationId("end").build(); + Vehicle new_vehicle = VehicleImpl.Builder.newInstance("new_v").setEarliestStart(1000).setLatestArrival(2000).setStartLocationId("new_start").setEndLocationId("new_end").build(); + VehicleRoute vRoute = VehicleRoute.Builder.newInstance(vehicle, DriverImpl.noDriver()).build(); + vRoute.setVehicleAndDepartureTime(new_vehicle, 50.0); + assertEquals("new_start",vRoute.getStart().getLocationId()); + } + + public void whenIniRouteWithNewVehicle_endLocationMustBeCorrect(){ + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setEarliestStart(100).setLatestArrival(200).setStartLocationId("start").setEndLocationId("end").build(); + Vehicle new_vehicle = VehicleImpl.Builder.newInstance("new_v").setEarliestStart(1000).setLatestArrival(2000).setStartLocationId("new_start").setEndLocationId("new_end").build(); + VehicleRoute vRoute = VehicleRoute.Builder.newInstance(vehicle, DriverImpl.noDriver()).build(); + vRoute.setVehicleAndDepartureTime(new_vehicle, 50.0); + assertEquals("new_end",vRoute.getStart().getLocationId()); } + public void whenIniRouteWithNewVehicle_depTimeMustBeEarliestDepTimeOfNewVehicle(){ + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setEarliestStart(100).setLatestArrival(200).setStartLocationId("start").setEndLocationId("end").build(); + Vehicle new_vehicle = VehicleImpl.Builder.newInstance("new_v").setEarliestStart(1000).setLatestArrival(2000).setStartLocationId("new_start").setEndLocationId("new_end").build(); + VehicleRoute vRoute = VehicleRoute.Builder.newInstance(vehicle, DriverImpl.noDriver()).build(); + vRoute.setVehicleAndDepartureTime(new_vehicle, 50.0); + assertEquals(1000.0,vRoute.getDepartureTime(),0.01); + } + + public void whenIniRouteWithNewVehicle_depTimeMustBeSetDepTime(){ + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setEarliestStart(100).setLatestArrival(200).setStartLocationId("start").setEndLocationId("end").build(); + Vehicle new_vehicle = VehicleImpl.Builder.newInstance("new_v").setEarliestStart(1000).setLatestArrival(2000).setStartLocationId("new_start").setEndLocationId("new_end").build(); + VehicleRoute vRoute = VehicleRoute.Builder.newInstance(vehicle, DriverImpl.noDriver()).build(); + vRoute.setVehicleAndDepartureTime(new_vehicle, 1500.0); + assertEquals(1500.0,vRoute.getDepartureTime(),0.01); + } } diff --git a/jsprit-core/src/test/java/jsprit/core/problem/solution/route/VehicleRouteBuilderTest.java b/jsprit-core/src/test/java/jsprit/core/problem/solution/route/VehicleRouteBuilderTest.java index 3a584e17..900c5ec9 100644 --- a/jsprit-core/src/test/java/jsprit/core/problem/solution/route/VehicleRouteBuilderTest.java +++ b/jsprit-core/src/test/java/jsprit/core/problem/solution/route/VehicleRouteBuilderTest.java @@ -120,6 +120,7 @@ public class VehicleRouteBuilderTest { Vehicle vehicle = mock(Vehicle.class); when(vehicle.isReturnToDepot()).thenReturn(false); when(vehicle.getLocationId()).thenReturn("vehLoc"); + when(vehicle.getLatestArrival()).thenReturn(200.0); VehicleRoute.Builder builder = VehicleRoute.Builder.newInstance(vehicle, mock(Driver.class)); builder.addPickup(s); builder.addPickup(s2);