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:
parent
bd5adcd0f1
commit
48212569c4
2 changed files with 87 additions and 10 deletions
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue