1
0
Fork 0
mirror of https://github.com/graphhopper/jsprit.git synced 2020-01-24 07:45:05 +01:00

added methods to easily add initial routes to

core.problem.VehicleRoutingProblem.java
This commit is contained in:
oblonski 2014-04-21 17:12:10 +02:00
parent bd5adcd0f1
commit 48212569c4
2 changed files with 87 additions and 10 deletions

View file

@ -31,6 +31,7 @@ import jsprit.core.problem.driver.Driver;
import jsprit.core.problem.job.Job; import jsprit.core.problem.job.Job;
import jsprit.core.problem.job.Service; import jsprit.core.problem.job.Service;
import jsprit.core.problem.job.Shipment; 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.solution.route.activity.TourActivity;
import jsprit.core.problem.vehicle.PenaltyVehicleType; import jsprit.core.problem.vehicle.PenaltyVehicleType;
import jsprit.core.problem.vehicle.Vehicle; import jsprit.core.problem.vehicle.Vehicle;
@ -162,8 +163,6 @@ public class VehicleRoutingProblem {
private Collection<Service> services; private Collection<Service> services;
private Collection<Vehicle> vehicles;
private Map<String, Coordinate> coordinates; private Map<String, Coordinate> coordinates;
private FleetSize fleetSize = FleetSize.INFINITE; private FleetSize fleetSize = FleetSize.INFINITE;
@ -175,6 +174,10 @@ public class VehicleRoutingProblem {
private Collection<VehicleType> vehicleTypes; private Collection<VehicleType> vehicleTypes;
private Collection<VehicleRoute> initialRoutes = new ArrayList<VehicleRoute>();
private Set<Vehicle> uniqueVehicles = new HashSet<Vehicle>();
/** /**
* @deprecated is not going to be used anymore * @deprecated is not going to be used anymore
*/ */
@ -206,7 +209,7 @@ public class VehicleRoutingProblem {
@Deprecated @Deprecated
public Builder() { public Builder() {
jobs = new HashMap<String, Job>(); jobs = new HashMap<String, Job>();
vehicles = new ArrayList<Vehicle>(); new ArrayList<Vehicle>();
coordinates = new HashMap<String, Coordinate>(); coordinates = new HashMap<String, Coordinate>();
vehicleTypes = new ArrayList<VehicleType>(); vehicleTypes = new ArrayList<VehicleType>();
services = new ArrayList<Service>(); services = new ArrayList<Service>();
@ -307,7 +310,27 @@ public class VehicleRoutingProblem {
throw new IllegalStateException("job must be either a service or a shipment"); 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<VehicleRoute> routes){
for(VehicleRoute r : routes){
addInitialVehicleRoute(r);
}
return this;
}
private void addShipment(Shipment job) { private void addShipment(Shipment job) {
if(jobs.containsKey(job.getId())){ logger.warn("job " + job + " already in job list. overrides existing job."); } if(jobs.containsKey(job.getId())){ logger.warn("job " + job + " already in job list. overrides existing job."); }
coordinates.put(job.getPickupLocation(), job.getPickupCoord()); coordinates.put(job.getPickupLocation(), job.getPickupCoord());
@ -323,7 +346,7 @@ public class VehicleRoutingProblem {
* @return this builder * @return this builder
*/ */
public Builder addVehicle(Vehicle vehicle) { public Builder addVehicle(Vehicle vehicle) {
vehicles.add(vehicle); uniqueVehicles.add(vehicle);
if(!vehicleTypes.contains(vehicle.getType())){ if(!vehicleTypes.contains(vehicle.getType())){
vehicleTypes.add(vehicle.getType()); vehicleTypes.add(vehicle.getType());
} }
@ -376,7 +399,7 @@ public class VehicleRoutingProblem {
private void addPenaltyVehicles() { private void addPenaltyVehicles() {
Set<LocTypeKey> locTypeKeys = new HashSet<LocTypeKey>(); Set<LocTypeKey> locTypeKeys = new HashSet<LocTypeKey>();
List<Vehicle> uniqueVehicles = new ArrayList<Vehicle>(); List<Vehicle> uniqueVehicles = new ArrayList<Vehicle>();
for(Vehicle v : vehicles){ for(Vehicle v : this.uniqueVehicles){
LocTypeKey key = new LocTypeKey(v.getStartLocationId(),v.getType().getTypeId()); LocTypeKey key = new LocTypeKey(v.getStartLocationId(),v.getType().getTypeId());
if(!locTypeKeys.contains(key)){ if(!locTypeKeys.contains(key)){
uniqueVehicles.add(v); uniqueVehicles.add(v);
@ -404,8 +427,8 @@ public class VehicleRoutingProblem {
} }
} }
public Builder addLocation(String id, Coordinate coord) { public Builder addLocation(String locationId, Coordinate coord) {
coordinates.put(id, coord); coordinates.put(locationId, coord);
return this; return this;
} }
@ -441,7 +464,7 @@ public class VehicleRoutingProblem {
* @return collection of vehicles * @return collection of vehicles
*/ */
public Collection<Vehicle> getAddedVehicles(){ public Collection<Vehicle> getAddedVehicles(){
return Collections.unmodifiableCollection(vehicles); return Collections.unmodifiableCollection(uniqueVehicles);
} }
/** /**
@ -640,6 +663,9 @@ public class VehicleRoutingProblem {
*/ */
private final Collection<VehicleType> vehicleTypes; private final Collection<VehicleType> vehicleTypes;
private final Collection<VehicleRoute> initialVehicleRoutes;
/** /**
* An enum that indicates type of fleetSize. By default, it is INFINTE * An enum that indicates type of fleetSize. By default, it is INFINTE
*/ */
@ -650,6 +676,8 @@ public class VehicleRoutingProblem {
*/ */
private final Collection<jsprit.core.problem.constraint.Constraint> constraints; private final Collection<jsprit.core.problem.constraint.Constraint> constraints;
private final Locations locations;
/** /**
* @deprecated not used anymore * @deprecated not used anymore
*/ */
@ -670,13 +698,15 @@ public class VehicleRoutingProblem {
this.jobs = builder.jobs; this.jobs = builder.jobs;
this.fleetComposition = builder.fleetComposition; this.fleetComposition = builder.fleetComposition;
this.fleetSize = builder.fleetSize; this.fleetSize = builder.fleetSize;
this.vehicles=builder.vehicles; this.vehicles=builder.uniqueVehicles;
this.vehicleTypes = builder.vehicleTypes; this.vehicleTypes = builder.vehicleTypes;
this.initialVehicleRoutes = builder.initialRoutes;
this.transportCosts = builder.transportCosts; this.transportCosts = builder.transportCosts;
this.activityCosts = builder.activityCosts; this.activityCosts = builder.activityCosts;
this.neighborhood = builder.neighborhood; this.neighborhood = builder.neighborhood;
this.problemConstraints = builder.problemConstraints; this.problemConstraints = builder.problemConstraints;
this.constraints = builder.constraints; this.constraints = builder.constraints;
this.locations = builder.getLocations();
logger.info("initialise " + this); logger.info("initialise " + this);
} }
@ -705,6 +735,10 @@ public class VehicleRoutingProblem {
public Map<String, Job> getJobs() { public Map<String, Job> getJobs() {
return Collections.unmodifiableMap(jobs); return Collections.unmodifiableMap(jobs);
} }
public Collection<VehicleRoute> getInitialVehicleRoutes(){
return Collections.unmodifiableCollection(initialVehicleRoutes);
}
/** /**
* Returns the entire, unmodifiable collection of types. * Returns the entire, unmodifiable collection of types.
@ -752,6 +786,10 @@ public class VehicleRoutingProblem {
public Collection<jsprit.core.problem.constraint.Constraint> getConstraints(){ public Collection<jsprit.core.problem.constraint.Constraint> getConstraints(){
return Collections.unmodifiableCollection(constraints); return Collections.unmodifiableCollection(constraints);
} }
public Locations getLocations(){
return locations;
}
/** /**
* Returns fleet-composition. * Returns fleet-composition.

View file

@ -31,15 +31,18 @@ import jsprit.core.problem.constraint.Constraint;
import jsprit.core.problem.cost.AbstractForwardVehicleRoutingTransportCosts; import jsprit.core.problem.cost.AbstractForwardVehicleRoutingTransportCosts;
import jsprit.core.problem.cost.VehicleRoutingActivityCosts; import jsprit.core.problem.cost.VehicleRoutingActivityCosts;
import jsprit.core.problem.driver.Driver; import jsprit.core.problem.driver.Driver;
import jsprit.core.problem.driver.DriverImpl;
import jsprit.core.problem.job.Delivery; import jsprit.core.problem.job.Delivery;
import jsprit.core.problem.job.Pickup; import jsprit.core.problem.job.Pickup;
import jsprit.core.problem.job.Service; import jsprit.core.problem.job.Service;
import jsprit.core.problem.job.Shipment; 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.solution.route.activity.TourActivity;
import jsprit.core.problem.vehicle.Vehicle; import jsprit.core.problem.vehicle.Vehicle;
import jsprit.core.problem.vehicle.VehicleImpl; import jsprit.core.problem.vehicle.VehicleImpl;
import jsprit.core.problem.vehicle.VehicleType; import jsprit.core.problem.vehicle.VehicleType;
import jsprit.core.problem.vehicle.VehicleTypeImpl; import jsprit.core.problem.vehicle.VehicleTypeImpl;
import jsprit.core.util.Coordinate;
import org.junit.Test; import org.junit.Test;
@ -489,4 +492,40 @@ public class VehicleRoutingProblemTest {
vrpBuilder.addVehicle(vehicle); vrpBuilder.addVehicle(vehicle);
assertTrue(vrpBuilder.getLocationMap().containsKey("end")); 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);
}
} }