diff --git a/jsprit-core/src/main/java/jsprit/core/problem/VehicleRoutingProblem.java b/jsprit-core/src/main/java/jsprit/core/problem/VehicleRoutingProblem.java index 154e5aa1..d9d10d14 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/VehicleRoutingProblem.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/VehicleRoutingProblem.java @@ -31,6 +31,7 @@ import jsprit.core.problem.driver.Driver; import jsprit.core.problem.job.Job; import jsprit.core.problem.job.Service; import jsprit.core.problem.job.Shipment; +import jsprit.core.problem.solution.route.VehicleRoute; import jsprit.core.problem.solution.route.activity.TourActivity; import jsprit.core.problem.vehicle.PenaltyVehicleType; import jsprit.core.problem.vehicle.Vehicle; @@ -162,8 +163,6 @@ public class VehicleRoutingProblem { private Collection services; - private Collection vehicles; - private Map coordinates; private FleetSize fleetSize = FleetSize.INFINITE; @@ -175,6 +174,10 @@ public class VehicleRoutingProblem { private Collection vehicleTypes; + private Collection initialRoutes = new ArrayList(); + + private Set uniqueVehicles = new HashSet(); + /** * @deprecated is not going to be used anymore */ @@ -206,7 +209,7 @@ public class VehicleRoutingProblem { @Deprecated public Builder() { jobs = new HashMap(); - vehicles = new ArrayList(); + new ArrayList(); coordinates = new HashMap(); vehicleTypes = new ArrayList(); services = new ArrayList(); @@ -307,7 +310,27 @@ public class VehicleRoutingProblem { throw new IllegalStateException("job must be either a service or a shipment"); } - + public Builder addInitialVehicleRoute(VehicleRoute route){ + addVehicle(route.getVehicle()); + for(Job job : route.getTourActivities().getJobs()){ + if(job instanceof Service) coordinates.put(((Service)job).getLocationId(), ((Service)job).getCoord()); + if(job instanceof Shipment){ + Shipment shipment = (Shipment)job; + coordinates.put(shipment.getPickupLocation(), shipment.getPickupCoord()); + coordinates.put(shipment.getDeliveryLocation(), shipment.getDeliveryCoord()); + } + } + initialRoutes.add(route); + return this; + } + + public Builder addInitialVehicleRoutes(Collection routes){ + for(VehicleRoute r : routes){ + addInitialVehicleRoute(r); + } + return this; + } + private void addShipment(Shipment job) { if(jobs.containsKey(job.getId())){ logger.warn("job " + job + " already in job list. overrides existing job."); } coordinates.put(job.getPickupLocation(), job.getPickupCoord()); @@ -323,7 +346,7 @@ public class VehicleRoutingProblem { * @return this builder */ public Builder addVehicle(Vehicle vehicle) { - vehicles.add(vehicle); + uniqueVehicles.add(vehicle); if(!vehicleTypes.contains(vehicle.getType())){ vehicleTypes.add(vehicle.getType()); } @@ -376,7 +399,7 @@ public class VehicleRoutingProblem { private void addPenaltyVehicles() { Set locTypeKeys = new HashSet(); List uniqueVehicles = new ArrayList(); - for(Vehicle v : vehicles){ + for(Vehicle v : this.uniqueVehicles){ LocTypeKey key = new LocTypeKey(v.getStartLocationId(),v.getType().getTypeId()); if(!locTypeKeys.contains(key)){ uniqueVehicles.add(v); @@ -404,8 +427,8 @@ public class VehicleRoutingProblem { } } - public Builder addLocation(String id, Coordinate coord) { - coordinates.put(id, coord); + public Builder addLocation(String locationId, Coordinate coord) { + coordinates.put(locationId, coord); return this; } @@ -441,7 +464,7 @@ public class VehicleRoutingProblem { * @return collection of vehicles */ public Collection getAddedVehicles(){ - return Collections.unmodifiableCollection(vehicles); + return Collections.unmodifiableCollection(uniqueVehicles); } /** @@ -640,6 +663,9 @@ public class VehicleRoutingProblem { */ private final Collection vehicleTypes; + + private final Collection initialVehicleRoutes; + /** * An enum that indicates type of fleetSize. By default, it is INFINTE */ @@ -650,6 +676,8 @@ public class VehicleRoutingProblem { */ private final Collection constraints; + private final Locations locations; + /** * @deprecated not used anymore */ @@ -670,13 +698,15 @@ public class VehicleRoutingProblem { this.jobs = builder.jobs; this.fleetComposition = builder.fleetComposition; this.fleetSize = builder.fleetSize; - this.vehicles=builder.vehicles; + this.vehicles=builder.uniqueVehicles; this.vehicleTypes = builder.vehicleTypes; + this.initialVehicleRoutes = builder.initialRoutes; this.transportCosts = builder.transportCosts; this.activityCosts = builder.activityCosts; this.neighborhood = builder.neighborhood; this.problemConstraints = builder.problemConstraints; this.constraints = builder.constraints; + this.locations = builder.getLocations(); logger.info("initialise " + this); } @@ -705,6 +735,10 @@ public class VehicleRoutingProblem { public Map getJobs() { return Collections.unmodifiableMap(jobs); } + + public Collection getInitialVehicleRoutes(){ + return Collections.unmodifiableCollection(initialVehicleRoutes); + } /** * Returns the entire, unmodifiable collection of types. @@ -752,6 +786,10 @@ public class VehicleRoutingProblem { public Collection getConstraints(){ return Collections.unmodifiableCollection(constraints); } + + public Locations getLocations(){ + return locations; + } /** * Returns fleet-composition. diff --git a/jsprit-core/src/test/java/jsprit/core/problem/VehicleRoutingProblemTest.java b/jsprit-core/src/test/java/jsprit/core/problem/VehicleRoutingProblemTest.java index d52bd42a..f7e0b6ce 100644 --- a/jsprit-core/src/test/java/jsprit/core/problem/VehicleRoutingProblemTest.java +++ b/jsprit-core/src/test/java/jsprit/core/problem/VehicleRoutingProblemTest.java @@ -31,15 +31,18 @@ import jsprit.core.problem.constraint.Constraint; import jsprit.core.problem.cost.AbstractForwardVehicleRoutingTransportCosts; import jsprit.core.problem.cost.VehicleRoutingActivityCosts; import jsprit.core.problem.driver.Driver; +import jsprit.core.problem.driver.DriverImpl; import jsprit.core.problem.job.Delivery; import jsprit.core.problem.job.Pickup; import jsprit.core.problem.job.Service; import jsprit.core.problem.job.Shipment; +import jsprit.core.problem.solution.route.VehicleRoute; import jsprit.core.problem.solution.route.activity.TourActivity; import jsprit.core.problem.vehicle.Vehicle; import jsprit.core.problem.vehicle.VehicleImpl; import jsprit.core.problem.vehicle.VehicleType; import jsprit.core.problem.vehicle.VehicleTypeImpl; +import jsprit.core.util.Coordinate; import org.junit.Test; @@ -489,4 +492,40 @@ public class VehicleRoutingProblemTest { vrpBuilder.addVehicle(vehicle); assertTrue(vrpBuilder.getLocationMap().containsKey("end")); } + + @Test + public void whenAddingInitialRoute_itShouldBeAddedCorrectly(){ + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setStartLocationId("start").setEndLocationId("end").build(); + VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, DriverImpl.noDriver()).build(); + VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); + vrpBuilder.addInitialVehicleRoute(route); + VehicleRoutingProblem vrp = vrpBuilder.build(); + assertTrue(!vrp.getInitialVehicleRoutes().isEmpty()); + } + + @Test + public void whenAddingInitialRoutes_theyShouldBeAddedCorrectly(){ + Vehicle vehicle1 = VehicleImpl.Builder.newInstance("v").setStartLocationId("start").setEndLocationId("end").build(); + VehicleRoute route1 = VehicleRoute.Builder.newInstance(vehicle1, DriverImpl.noDriver()).build(); + + Vehicle vehicle2 = VehicleImpl.Builder.newInstance("v").setStartLocationId("start").setEndLocationId("end").build(); + VehicleRoute route2 = VehicleRoute.Builder.newInstance(vehicle2, DriverImpl.noDriver()).build(); + + VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); + vrpBuilder.addInitialVehicleRoutes(Arrays.asList(route1,route2)); + + VehicleRoutingProblem vrp = vrpBuilder.build(); + assertEquals(2,vrp.getInitialVehicleRoutes().size()); + } + + @Test + public void whenAddingInitialRoute_locationOfVehicleMustBeMemorized(){ + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setStartLocationId("start").setStartLocationCoordinate(Coordinate.newInstance(0, 1)).setEndLocationId("end").build(); + VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, DriverImpl.noDriver()).build(); + VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); + vrpBuilder.addInitialVehicleRoute(route); + VehicleRoutingProblem vrp = vrpBuilder.build(); + assertEquals(0.,vrp.getLocations().getCoord("start").getX(),0.01); + assertEquals(1.,vrp.getLocations().getCoord("start").getY(),0.01); + } }