mirror of
https://github.com/graphhopper/jsprit.git
synced 2020-01-24 07:45:05 +01:00
Merge branch 'master' into multiple-cap-constraints
Conflicts: jsprit-core/src/main/java/jsprit/core/problem/vehicle/VehicleType.java jsprit-core/src/main/java/jsprit/core/problem/vehicle/VehicleTypeImpl.java jsprit-core/src/test/java/jsprit/core/problem/vehicle/VehicleImplTest.java jsprit-core/src/test/java/jsprit/core/problem/vehicle/VehicleTypeImplTest.java
This commit is contained in:
commit
2993202d49
35 changed files with 2623 additions and 64 deletions
|
|
@ -20,7 +20,10 @@ import java.util.ArrayList;
|
|||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import jsprit.core.problem.cost.VehicleRoutingActivityCosts;
|
||||
import jsprit.core.problem.cost.VehicleRoutingTransportCosts;
|
||||
|
|
@ -29,7 +32,9 @@ import jsprit.core.problem.job.Job;
|
|||
import jsprit.core.problem.job.Service;
|
||||
import jsprit.core.problem.job.Shipment;
|
||||
import jsprit.core.problem.solution.route.activity.TourActivity;
|
||||
import jsprit.core.problem.vehicle.PenaltyVehicleType;
|
||||
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;
|
||||
|
|
@ -79,6 +84,57 @@ public class VehicleRoutingProblem {
|
|||
*/
|
||||
public static class Builder {
|
||||
|
||||
/**
|
||||
* Two locTypeKeys are equal if they have the same locationId and typeId
|
||||
*
|
||||
* @author schroeder
|
||||
*
|
||||
*/
|
||||
private static class LocTypeKey {
|
||||
String locationId;
|
||||
String typeId;
|
||||
|
||||
public LocTypeKey(String locationId, String typeId) {
|
||||
super();
|
||||
this.locationId = locationId;
|
||||
this.typeId = typeId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result
|
||||
+ ((locationId == null) ? 0 : locationId.hashCode());
|
||||
result = prime * result
|
||||
+ ((typeId == null) ? 0 : typeId.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
LocTypeKey other = (LocTypeKey) obj;
|
||||
if (locationId == null) {
|
||||
if (other.locationId != null)
|
||||
return false;
|
||||
} else if (!locationId.equals(other.locationId))
|
||||
return false;
|
||||
if (typeId == null) {
|
||||
if (other.typeId != null)
|
||||
return false;
|
||||
} else if (!typeId.equals(other.typeId))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new instance of this builder.
|
||||
*
|
||||
|
|
@ -138,6 +194,16 @@ public class VehicleRoutingProblem {
|
|||
}
|
||||
};
|
||||
|
||||
private boolean addPenaltyVehicles = false;
|
||||
|
||||
private double penaltyFactor = 1.0;
|
||||
|
||||
private Double penaltyFixedCosts = null;
|
||||
|
||||
/**
|
||||
* @deprecated use static method .newInstance() instead
|
||||
*/
|
||||
@Deprecated
|
||||
public Builder() {
|
||||
jobs = new HashMap<String, Job>();
|
||||
vehicles = new ArrayList<Vehicle>();
|
||||
|
|
@ -169,7 +235,7 @@ public class VehicleRoutingProblem {
|
|||
/**
|
||||
* Returns the unmodifiable map of locations (mapped by their id).
|
||||
*
|
||||
* @return
|
||||
* @return map with locations
|
||||
*/
|
||||
public Map<String,Coordinate> getLocationMap(){
|
||||
return Collections.unmodifiableMap(coordinates);
|
||||
|
|
@ -209,10 +275,10 @@ public class VehicleRoutingProblem {
|
|||
/**
|
||||
* Sets the type of fleetSize.
|
||||
*
|
||||
* <p>FleetSize is either FleetSize.INFINITE or FleetSize.FINITE
|
||||
* <p>FleetSize is either FleetSize.INFINITE or FleetSize.FINITE. By default it is FleetSize.INFINITE.
|
||||
*
|
||||
* @param fleetSize
|
||||
* @return
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder setFleetSize(FleetSize fleetSize){
|
||||
this.fleetSize = fleetSize;
|
||||
|
|
@ -225,7 +291,7 @@ public class VehicleRoutingProblem {
|
|||
* <p>Note that job.getId() must be unique, i.e. no job (either it is a shipment or a service) is allowed to have an already allocated id.
|
||||
*
|
||||
* @param job
|
||||
* @return
|
||||
* @return this builder
|
||||
* @throws IllegalStateException if job is neither a shipment nor a service, or jobId has already been added.
|
||||
*/
|
||||
public Builder addJob(Job job) {
|
||||
|
|
@ -254,7 +320,7 @@ public class VehicleRoutingProblem {
|
|||
*
|
||||
*
|
||||
* @param vehicle
|
||||
* @return
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder addVehicle(Vehicle vehicle) {
|
||||
vehicles.add(vehicle);
|
||||
|
|
@ -271,7 +337,7 @@ public class VehicleRoutingProblem {
|
|||
* <p>By default it is set to zero.
|
||||
*
|
||||
* @param activityCosts
|
||||
* @return
|
||||
* @return this builder
|
||||
* @see VehicleRoutingActivityCosts
|
||||
*/
|
||||
public Builder setActivityCosts(VehicleRoutingActivityCosts activityCosts){
|
||||
|
|
@ -292,9 +358,46 @@ public class VehicleRoutingProblem {
|
|||
logger.warn("set routing costs crowFlyDistance.");
|
||||
transportCosts = new CrowFlyCosts(getLocations());
|
||||
}
|
||||
if(addPenaltyVehicles){
|
||||
if(fleetSize.equals(FleetSize.INFINITE)){
|
||||
logger.warn("penaltyType and FleetSize.INFINITE does not make sense. thus no penalty-types are added.");
|
||||
}
|
||||
else{
|
||||
addPenaltyVehicles();
|
||||
}
|
||||
}
|
||||
return new VehicleRoutingProblem(this);
|
||||
}
|
||||
|
||||
private void addPenaltyVehicles() {
|
||||
Set<LocTypeKey> locTypeKeys = new HashSet<LocTypeKey>();
|
||||
List<Vehicle> uniqueVehicles = new ArrayList<Vehicle>();
|
||||
for(Vehicle v : vehicles){
|
||||
LocTypeKey key = new LocTypeKey(v.getLocationId(),v.getType().getTypeId());
|
||||
if(!locTypeKeys.contains(key)){
|
||||
uniqueVehicles.add(v);
|
||||
locTypeKeys.add(key);
|
||||
}
|
||||
}
|
||||
for(Vehicle v : uniqueVehicles){
|
||||
double fixed = v.getType().getVehicleCostParams().fix * penaltyFactor;
|
||||
if(penaltyFixedCosts!=null){
|
||||
fixed = penaltyFixedCosts;
|
||||
}
|
||||
VehicleTypeImpl t = VehicleTypeImpl.Builder.newInstance(v.getType().getTypeId(), v.getCapacity())
|
||||
.setCostPerDistance(penaltyFactor*v.getType().getVehicleCostParams().perDistanceUnit)
|
||||
.setCostPerTime(penaltyFactor*v.getType().getVehicleCostParams().perTimeUnit)
|
||||
.setFixedCost(fixed)
|
||||
.build();
|
||||
PenaltyVehicleType penType = new PenaltyVehicleType(t,penaltyFactor);
|
||||
String vehicleId = "penaltyVehicle_" + v.getLocationId() + "_" + t.getTypeId();
|
||||
Vehicle penVehicle = VehicleImpl.Builder.newInstance(vehicleId).setEarliestStart(v.getEarliestDeparture())
|
||||
.setLatestArrival(v.getLatestArrival()).setLocationCoord(v.getCoord()).setLocationId(v.getLocationId())
|
||||
.setReturnToDepot(v.isReturnToDepot()).setType(penType).build();
|
||||
addVehicle(penVehicle);
|
||||
}
|
||||
}
|
||||
|
||||
public Builder addLocation(String id, Coordinate coord) {
|
||||
coordinates.put(id, coord);
|
||||
return this;
|
||||
|
|
@ -304,7 +407,7 @@ public class VehicleRoutingProblem {
|
|||
* Adds a collection of jobs.
|
||||
*
|
||||
* @param jobs which is a collection of jobs that subclasses Job
|
||||
* @return
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder addAllJobs(Collection<? extends Job> jobs) {
|
||||
for(Job j : jobs){
|
||||
|
|
@ -317,7 +420,7 @@ public class VehicleRoutingProblem {
|
|||
* Adds a collection of vehicles.
|
||||
*
|
||||
* @param vehicles
|
||||
* @return
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder addAllVehicles(Collection<Vehicle> vehicles) {
|
||||
for(Vehicle v : vehicles){
|
||||
|
|
@ -335,17 +438,61 @@ public class VehicleRoutingProblem {
|
|||
return Collections.unmodifiableCollection(vehicles);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an unmodifiable collection of already added vehicle-types.
|
||||
*
|
||||
* @returns collection of vehicle-types
|
||||
*/
|
||||
public Collection<VehicleType> getAddedVehicleTypes(){
|
||||
return Collections.unmodifiableCollection(vehicleTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds constraint to problem.
|
||||
*
|
||||
* @param constraint
|
||||
* @return
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder addConstraint(jsprit.core.problem.constraint.Constraint constraint){
|
||||
constraints.add(constraint);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds penaltyVehicles, i.e. for every unique vehicle-location and type combination a penalty-vehicle is constructed having penaltyFactor times higher fixed and variable costs
|
||||
* (see .addPenaltyVehicles(double penaltyFactor, double penaltyFixedCosts) if fixed costs = 0.0).
|
||||
*
|
||||
* <p>This only makes sense for FleetSize.FINITE. Thus, penaltyVehicles are only added if is FleetSize.FINITE.
|
||||
* <p>The id of penaltyVehicles is constructed as follows vehicleId = "penaltyVehicle" + "_" + {locationId} + "_" + {typeId}.
|
||||
* <p>By default: no penalty-vehicles are added
|
||||
*
|
||||
* @param penaltyFactor
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder addPenaltyVehicles(double penaltyFactor){
|
||||
this.addPenaltyVehicles = true;
|
||||
this.penaltyFactor = penaltyFactor;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds penaltyVehicles, i.e. for every unique vehicle-location and type combination a penalty-vehicle is constructed having penaltyFactor times higher fixed and variable costs.
|
||||
* <p>This method takes penaltyFixedCosts as absolute value in contrary to the method without penaltyFixedCosts where fixedCosts is the product of penaltyFactor and typeFixedCosts.
|
||||
* <p>This only makes sense for FleetSize.FINITE. Thus, penaltyVehicles are only added if is FleetSize.FINITE.
|
||||
* <p>The id of penaltyVehicles is constructed as follows vehicleId = "penaltyVehicle" + "_" + {locationId} + "_" + {typeId}.
|
||||
* <p>By default: no penalty-vehicles are added
|
||||
*
|
||||
* @param penaltyFactor
|
||||
* @param penaltyFixedCosts which is an absolute penaltyValue (in contrary to penaltyFactor)
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder addPenaltyVehicles(double penaltyFactor, double penaltyFixedCosts){
|
||||
this.addPenaltyVehicles = true;
|
||||
this.penaltyFactor = penaltyFactor;
|
||||
this.penaltyFixedCosts = penaltyFixedCosts;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an unmodifiable collection of already added jobs.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ public class FiniteFleetManagerFactory implements VehicleFleetManagerFactory{
|
|||
|
||||
private Collection<Vehicle> vehicles;
|
||||
|
||||
|
||||
/**
|
||||
* Constucts the factory.
|
||||
*
|
||||
|
|
@ -40,9 +39,14 @@ public class FiniteFleetManagerFactory implements VehicleFleetManagerFactory{
|
|||
|
||||
/**
|
||||
* Creates the finite fleetmanager.
|
||||
*
|
||||
* @return VehicleFleetManager
|
||||
* @throws IllegalStateManager if vehicles == null or vehicles.isEmpty()
|
||||
*/
|
||||
@Override
|
||||
public VehicleFleetManager createFleetManager() {
|
||||
if(vehicles == null) throw new IllegalStateException("vehicles is null. this must not be.");
|
||||
if(vehicles.isEmpty()) throw new IllegalStateException("vehicle-collection is empty. this must not be");
|
||||
return new VehicleFleetManagerImpl(vehicles);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -94,12 +94,14 @@ public class VehicleImpl implements Vehicle {
|
|||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link VehicleType}.
|
||||
* Sets the {@link VehicleType}.<br>
|
||||
*
|
||||
* @param type
|
||||
* @throws IllegalStateException if type is null
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder setType(VehicleType type){
|
||||
if(type==null) throw new IllegalStateException("type cannot be null.");
|
||||
this.type = type;
|
||||
return this;
|
||||
}
|
||||
|
|
@ -166,6 +168,9 @@ public class VehicleImpl implements Vehicle {
|
|||
/**
|
||||
* Builds and returns the vehicle.
|
||||
*
|
||||
* <p>if {@link VehicleType} is not set, default vehicle-type is set with id="default" and
|
||||
* capacity=0
|
||||
*
|
||||
* @return vehicle
|
||||
* @throw IllegalStateException if both locationId and locationCoord is not set
|
||||
*/
|
||||
|
|
@ -189,6 +194,8 @@ public class VehicleImpl implements Vehicle {
|
|||
/**
|
||||
* Returns empty/noVehicle which is a vehicle having no capacity, no type and no reasonable id.
|
||||
*
|
||||
* <p>NoVehicle has id="noVehicle" and extends {@link VehicleImpl}
|
||||
*
|
||||
* @return emptyVehicle
|
||||
*/
|
||||
public static NoVehicle createNoVehicle(){
|
||||
|
|
@ -219,9 +226,14 @@ public class VehicleImpl implements Vehicle {
|
|||
returnToDepot = builder.returnToDepot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns String with attributes of this vehicle
|
||||
*
|
||||
* <p>String has the following format [attr1=val1][attr2=val2]...[attrn=valn]
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[id="+id+"][type="+type+"][locationId="+locationId+"][coord=" + coord + "]";
|
||||
return "[id="+id+"][type="+type+"][locationId="+locationId+"][coord=" + coord + "][isReturnToDepot=" + isReturnToDepot() + "]";
|
||||
}
|
||||
|
||||
public Coordinate getCoord() {
|
||||
|
|
|
|||
|
|
@ -19,17 +19,49 @@ package jsprit.core.problem.vehicle;
|
|||
import jsprit.core.problem.Capacity;
|
||||
import jsprit.core.problem.vehicle.VehicleTypeImpl.VehicleCostParams;
|
||||
|
||||
|
||||
/**
|
||||
* Basic interface for vehicle-type-data.
|
||||
*
|
||||
* @author schroeder
|
||||
*
|
||||
*/
|
||||
public interface VehicleType {
|
||||
|
||||
/**
|
||||
* Returns typeId.
|
||||
*
|
||||
* @return typeId
|
||||
*/
|
||||
public String getTypeId();
|
||||
|
||||
/**
|
||||
* Returns capacity.
|
||||
*
|
||||
* <p>In future versions there will be a capacity-object with an arbitrary number of capacity dimensions. (stefan,11.01.14)
|
||||
*
|
||||
* @return cap
|
||||
*/
|
||||
public int getCapacity();
|
||||
|
||||
/**
|
||||
* Returns capacity dimensions.
|
||||
*
|
||||
* @return {@link Capacity}
|
||||
*/
|
||||
public Capacity getCapacityDimensions();
|
||||
|
||||
/**
|
||||
* Returns maximum velocity of this vehicle-type.
|
||||
*
|
||||
* @return max velocity
|
||||
*/
|
||||
public double getMaxVelocity();
|
||||
|
||||
/**
|
||||
* Return the cost-parameter of this vehicle-type.
|
||||
*
|
||||
* @return parameter
|
||||
*/
|
||||
public VehicleCostParams getVehicleCostParams();
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,17 +16,31 @@
|
|||
******************************************************************************/
|
||||
package jsprit.core.problem.vehicle;
|
||||
|
||||
|
||||
import jsprit.core.problem.Capacity;
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of {@link VehicleType}.
|
||||
*
|
||||
* <p>Two vehicle-types are equal if they have the same typeId.
|
||||
*
|
||||
* @author schroeder
|
||||
*
|
||||
*/
|
||||
public class VehicleTypeImpl implements VehicleType {
|
||||
|
||||
/**
|
||||
* CostParameter consisting of fixed cost parameter, time-based cost parameter and distance-based cost parameter.
|
||||
*
|
||||
* @author schroeder
|
||||
*
|
||||
*/
|
||||
public static class VehicleCostParams {
|
||||
|
||||
public static VehicleTypeImpl.VehicleCostParams newInstance(double fix, double perTimeUnit,double perDistanceUnit){
|
||||
return new VehicleCostParams(fix, perTimeUnit, perDistanceUnit);
|
||||
}
|
||||
|
||||
|
||||
public final double fix;
|
||||
public final double perTimeUnit;
|
||||
public final double perDistanceUnit;
|
||||
|
|
@ -44,10 +58,28 @@ public class VehicleTypeImpl implements VehicleType {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Builder that builds the vehicle-type.
|
||||
*
|
||||
* @author schroeder
|
||||
*
|
||||
*/
|
||||
public static class Builder{
|
||||
|
||||
/**
|
||||
* Returns a new instance.
|
||||
*
|
||||
* <p>Input parameters are id and capacity. Note that two vehicle-types are equal
|
||||
* if they have the same vehicleId.
|
||||
*
|
||||
* @param id
|
||||
* @param capacity
|
||||
* @return the vehicleType builder
|
||||
* @throws IllegalStateException if capacity is smaller than zero or id is null
|
||||
*/
|
||||
public static VehicleTypeImpl.Builder newInstance(String id, int capacity){
|
||||
if(capacity < 0) throw new IllegalStateException("capacity cannot be smaller than zero");
|
||||
if(id == null) throw new IllegalStateException("typeId must be null");
|
||||
Builder builder = new Builder(id,capacity);
|
||||
builder.addCapacityDimension(0, capacity);
|
||||
return builder;
|
||||
|
|
@ -72,7 +104,13 @@ public class VehicleTypeImpl implements VehicleType {
|
|||
|
||||
private Capacity capacityDimensions;
|
||||
|
||||
public Builder(String id, int capacity) {
|
||||
/**
|
||||
* Constructs the builder.
|
||||
*
|
||||
* @param id
|
||||
* @param capacity
|
||||
*/
|
||||
private Builder(String id, int capacity) {
|
||||
super();
|
||||
this.id = id;
|
||||
this.capacity = capacity;
|
||||
|
|
@ -82,14 +120,68 @@ public class VehicleTypeImpl implements VehicleType {
|
|||
this.id = id;
|
||||
}
|
||||
|
||||
public VehicleTypeImpl.Builder setMaxVelocity(double inMeterPerSeconds){ this.maxVelo = inMeterPerSeconds; return this; }
|
||||
/**
|
||||
* Sets the maximum velocity this vehicle-type can go [in meter per seconds].
|
||||
*
|
||||
* @param inMeterPerSeconds
|
||||
* @return this builder
|
||||
* @throws IllegalStateException if velocity is smaller than zero
|
||||
*/
|
||||
public VehicleTypeImpl.Builder setMaxVelocity(double inMeterPerSeconds){
|
||||
if(inMeterPerSeconds < 0.0) throw new IllegalStateException("velocity cannot be smaller than zero");
|
||||
this.maxVelo = inMeterPerSeconds; return this;
|
||||
}
|
||||
|
||||
public VehicleTypeImpl.Builder setFixedCost(double fixedCost) { this.fixedCost = fixedCost; return this; }
|
||||
/**
|
||||
* Sets the fixed costs of the vehicle-type.
|
||||
*
|
||||
* <p>by default it is 0.
|
||||
*
|
||||
* @param fixedCost
|
||||
* @return this builder
|
||||
* @throws IllegalStateException if fixedCost is smaller than zero
|
||||
*/
|
||||
public VehicleTypeImpl.Builder setFixedCost(double fixedCost) {
|
||||
if(fixedCost < 0.0) throw new IllegalStateException("fixed costs cannot be smaller than zero");
|
||||
this.fixedCost = fixedCost;
|
||||
return this;
|
||||
}
|
||||
|
||||
public VehicleTypeImpl.Builder setCostPerDistance(double perDistance){ this.perDistance = perDistance; return this; }
|
||||
/**
|
||||
* Sets the cost per distance unit, for instance € per meter.
|
||||
*
|
||||
* <p>by default it is 1.0
|
||||
*
|
||||
* @param perDistance
|
||||
* @return this builder
|
||||
* @throws IllegalStateException if perDistance is smaller than zero
|
||||
*/
|
||||
public VehicleTypeImpl.Builder setCostPerDistance(double perDistance){
|
||||
if(perDistance < 0.0) throw new IllegalStateException("cost per distance must not be smaller than zero");
|
||||
this.perDistance = perDistance;
|
||||
return this;
|
||||
}
|
||||
|
||||
public VehicleTypeImpl.Builder setCostPerTime(double perTime){ this.perTime = perTime; return this; }
|
||||
/**
|
||||
* Sets cost per time unit, for instance € per second.
|
||||
*
|
||||
* <p>by default it is 0.0
|
||||
*
|
||||
* @param perTime
|
||||
* @return this builder
|
||||
* @throws IllegalStateException if costPerTime is smaller than zero
|
||||
*/
|
||||
public VehicleTypeImpl.Builder setCostPerTime(double perTime){
|
||||
if(perTime < 0.0) throw new IllegalStateException();
|
||||
this.perTime = perTime;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the vehicle-type.
|
||||
*
|
||||
* @return VehicleTypeImpl
|
||||
*/
|
||||
public VehicleTypeImpl build(){
|
||||
capacityDimensions = capacityBuilder.build();
|
||||
return new VehicleTypeImpl(this);
|
||||
|
|
@ -112,6 +204,9 @@ public class VehicleTypeImpl implements VehicleType {
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Two vehicle-types are equal if they have the same vehicleId.
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
|
|
@ -135,9 +230,10 @@ public class VehicleTypeImpl implements VehicleType {
|
|||
|
||||
private final VehicleTypeImpl.VehicleCostParams vehicleCostParams;
|
||||
|
||||
private double maxVelocity;
|
||||
|
||||
private Capacity capacityDimensions;
|
||||
private final Capacity capacityDimensions;
|
||||
|
||||
private final double maxVelocity;
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated use builder instead
|
||||
|
|
@ -147,6 +243,11 @@ public class VehicleTypeImpl implements VehicleType {
|
|||
return new VehicleTypeImpl(typeId, capacity, para);
|
||||
}
|
||||
|
||||
/**
|
||||
* priv constructor constructing vehicle-type
|
||||
*
|
||||
* @param builder
|
||||
*/
|
||||
private VehicleTypeImpl(VehicleTypeImpl.Builder builder){
|
||||
typeId = builder.id;
|
||||
capacity = builder.capacity;
|
||||
|
|
@ -155,13 +256,21 @@ public class VehicleTypeImpl implements VehicleType {
|
|||
capacityDimensions = builder.capacityDimensions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use Builder.newInstance(...) instead.
|
||||
*
|
||||
* @param typeId
|
||||
* @param capacity
|
||||
* @param vehicleCostParams
|
||||
*/
|
||||
@Deprecated
|
||||
public VehicleTypeImpl(String typeId, int capacity,VehicleTypeImpl.VehicleCostParams vehicleCostParams) {
|
||||
super();
|
||||
this.typeId = typeId;
|
||||
this.capacity = capacity;
|
||||
this.vehicleCostParams = vehicleCostParams;
|
||||
capacityDimensions = Capacity.Builder.newInstance().addDimension(0, capacity).build();
|
||||
|
||||
this.capacityDimensions = Capacity.Builder.newInstance().addDimension(0, capacity).build();
|
||||
this.maxVelocity = Double.MAX_VALUE;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@
|
|||
package jsprit.core.problem;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
|
|
@ -36,6 +38,7 @@ import jsprit.core.problem.job.Shipment;
|
|||
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 org.junit.Test;
|
||||
|
|
@ -278,5 +281,194 @@ public class VehicleRoutingProblemTest {
|
|||
VehicleRoutingProblem problem = builder.build();
|
||||
assertEquals(4.0,problem.getTransportCosts().getTransportCost("", "", 0.0, null, null),0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenAddingAVehicle_getAddedVehicleTypesShouldReturnItsType(){
|
||||
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
|
||||
VehicleType type = VehicleTypeImpl.Builder.newInstance("type", 0).build();
|
||||
Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setLocationId("loc").setType(type).build();
|
||||
builder.addVehicle(vehicle);
|
||||
|
||||
assertEquals(1,builder.getAddedVehicleTypes().size());
|
||||
assertEquals(type,builder.getAddedVehicleTypes().iterator().next());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenAddingTwoVehicleWithSameType_getAddedVehicleTypesShouldReturnOnlyOneType(){
|
||||
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
|
||||
VehicleType type = VehicleTypeImpl.Builder.newInstance("type", 0).build();
|
||||
Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setLocationId("loc").setType(type).build();
|
||||
Vehicle vehicle2 = VehicleImpl.Builder.newInstance("v").setLocationId("loc").setType(type).build();
|
||||
|
||||
builder.addVehicle(vehicle);
|
||||
builder.addVehicle(vehicle2);
|
||||
|
||||
assertEquals(1,builder.getAddedVehicleTypes().size());
|
||||
assertEquals(type,builder.getAddedVehicleTypes().iterator().next());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenAddingTwoVehicleWithDiffType_getAddedVehicleTypesShouldReturnTheseType(){
|
||||
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
|
||||
VehicleType type = VehicleTypeImpl.Builder.newInstance("type", 0).build();
|
||||
VehicleType type2 = VehicleTypeImpl.Builder.newInstance("type2", 0).build();
|
||||
|
||||
Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setLocationId("loc").setType(type).build();
|
||||
Vehicle vehicle2 = VehicleImpl.Builder.newInstance("v").setLocationId("loc").setType(type2).build();
|
||||
|
||||
builder.addVehicle(vehicle);
|
||||
builder.addVehicle(vehicle2);
|
||||
|
||||
assertEquals(2,builder.getAddedVehicleTypes().size());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSettingAddPenaltyVehicleOptions_itShouldAddPenaltyVehicle(){
|
||||
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
|
||||
VehicleType type = VehicleTypeImpl.Builder.newInstance("type", 0).build();
|
||||
Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setLocationId("loc").setType(type).build();
|
||||
|
||||
builder.addVehicle(vehicle);
|
||||
builder.setFleetSize(FleetSize.FINITE);
|
||||
builder.addPenaltyVehicles(3.0);
|
||||
|
||||
VehicleRoutingProblem vrp = builder.build();
|
||||
|
||||
assertEquals(2,vrp.getVehicles().size());
|
||||
|
||||
boolean penaltyVehicleInCollection = false;
|
||||
for(Vehicle v : vrp.getVehicles()){
|
||||
if(v.getId().equals("penaltyVehicle_loc_type")) penaltyVehicleInCollection = true;
|
||||
}
|
||||
assertTrue(penaltyVehicleInCollection);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSettingAddPenaltyVehicleOptionsAndFleetSizeIsInfinite_noPenaltyVehicleIsAdded(){
|
||||
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
|
||||
VehicleType type = VehicleTypeImpl.Builder.newInstance("type", 0).build();
|
||||
Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setLocationId("loc").setType(type).build();
|
||||
|
||||
builder.addVehicle(vehicle);
|
||||
builder.addPenaltyVehicles(3.0);
|
||||
|
||||
VehicleRoutingProblem vrp = builder.build();
|
||||
|
||||
assertEquals(1,vrp.getVehicles().size());
|
||||
|
||||
boolean penaltyVehicleInCollection = false;
|
||||
for(Vehicle v : vrp.getVehicles()){
|
||||
if(v.getId().equals("penaltyVehicle_loc_type")) penaltyVehicleInCollection = true;
|
||||
}
|
||||
assertFalse(penaltyVehicleInCollection);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSettingAddPenaltyVehicleOptionsAndTwoVehiclesWithSameLocationAndType_onlyOnePenaltyVehicleIsAdded(){
|
||||
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
|
||||
VehicleType type = VehicleTypeImpl.Builder.newInstance("type", 0).build();
|
||||
Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setLocationId("loc").setType(type).build();
|
||||
Vehicle vehicle2 = VehicleImpl.Builder.newInstance("v2").setLocationId("loc").setType(type).build();
|
||||
|
||||
builder.addVehicle(vehicle);
|
||||
builder.addVehicle(vehicle2);
|
||||
builder.setFleetSize(FleetSize.FINITE);
|
||||
builder.addPenaltyVehicles(3.0);
|
||||
|
||||
VehicleRoutingProblem vrp = builder.build();
|
||||
|
||||
assertEquals(3,vrp.getVehicles().size());
|
||||
|
||||
boolean penaltyVehicleInCollection = false;
|
||||
for(Vehicle v : vrp.getVehicles()){
|
||||
if(v.getId().equals("penaltyVehicle_loc_type")) penaltyVehicleInCollection = true;
|
||||
}
|
||||
assertTrue(penaltyVehicleInCollection);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSettingAddPenaltyVehicleOptionsWithAbsoluteFixedCostsAndTwoVehiclesWithSameLocationAndType_onePenaltyVehicleIsAddedWithTheCorrectPenaltyFixedCosts(){
|
||||
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
|
||||
VehicleType type = VehicleTypeImpl.Builder.newInstance("type", 0).build();
|
||||
Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setLocationId("loc").setType(type).build();
|
||||
Vehicle vehicle2 = VehicleImpl.Builder.newInstance("v2").setLocationId("loc").setType(type).build();
|
||||
|
||||
builder.addVehicle(vehicle);
|
||||
builder.addVehicle(vehicle2);
|
||||
builder.setFleetSize(FleetSize.FINITE);
|
||||
builder.addPenaltyVehicles(3.0,10000);
|
||||
|
||||
VehicleRoutingProblem vrp = builder.build();
|
||||
|
||||
assertEquals(3,vrp.getVehicles().size());
|
||||
|
||||
double fix = 0.0;
|
||||
for(Vehicle v : vrp.getVehicles()){
|
||||
if(v.getId().equals("penaltyVehicle_loc_type")) {
|
||||
fix = v.getType().getVehicleCostParams().fix;
|
||||
}
|
||||
}
|
||||
assertEquals(10000,fix,0.01);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSettingAddPenaltyVehicleOptionsAndTwoVehiclesWithDiffLocationAndType_twoPenaltyVehicleIsAdded(){
|
||||
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
|
||||
VehicleType type = VehicleTypeImpl.Builder.newInstance("type", 0).build();
|
||||
Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setLocationId("loc").setType(type).build();
|
||||
Vehicle vehicle2 = VehicleImpl.Builder.newInstance("v2").setLocationId("loc2").setType(type).build();
|
||||
|
||||
builder.addVehicle(vehicle);
|
||||
builder.addVehicle(vehicle2);
|
||||
builder.setFleetSize(FleetSize.FINITE);
|
||||
builder.addPenaltyVehicles(3.0);
|
||||
|
||||
VehicleRoutingProblem vrp = builder.build();
|
||||
|
||||
assertEquals(4,vrp.getVehicles().size());
|
||||
|
||||
boolean penaltyVehicleInCollection = false;
|
||||
boolean anotherPenVehInCollection = false;
|
||||
for(Vehicle v : vrp.getVehicles()){
|
||||
if(v.getId().equals("penaltyVehicle_loc_type")) penaltyVehicleInCollection = true;
|
||||
if(v.getId().equals("penaltyVehicle_loc2_type")) anotherPenVehInCollection = true;
|
||||
}
|
||||
assertTrue(penaltyVehicleInCollection);
|
||||
assertTrue(anotherPenVehInCollection);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSettingAddPenaltyVehicleOptionsAndTwoVehiclesWithSameLocationButDiffType_twoPenaltyVehicleIsAdded(){
|
||||
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
|
||||
VehicleType type = VehicleTypeImpl.Builder.newInstance("type", 0).build();
|
||||
VehicleType type2 = VehicleTypeImpl.Builder.newInstance("type2", 0).build();
|
||||
Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setLocationId("loc").setType(type).build();
|
||||
Vehicle vehicle2 = VehicleImpl.Builder.newInstance("v2").setLocationId("loc").setType(type2).build();
|
||||
|
||||
builder.addVehicle(vehicle);
|
||||
builder.addVehicle(vehicle2);
|
||||
builder.setFleetSize(FleetSize.FINITE);
|
||||
builder.addPenaltyVehicles(3.0);
|
||||
|
||||
VehicleRoutingProblem vrp = builder.build();
|
||||
|
||||
assertEquals(4,vrp.getVehicles().size());
|
||||
|
||||
boolean penaltyVehicleInCollection = false;
|
||||
boolean anotherPenVehInCollection = false;
|
||||
for(Vehicle v : vrp.getVehicles()){
|
||||
if(v.getId().equals("penaltyVehicle_loc_type")) penaltyVehicleInCollection = true;
|
||||
if(v.getId().equals("penaltyVehicle_loc_type2")) anotherPenVehInCollection = true;
|
||||
}
|
||||
assertTrue(penaltyVehicleInCollection);
|
||||
assertTrue(anotherPenVehInCollection);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
package jsprit.core.problem.vehicle;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class FiniteVehicleFleetManagerFactoryTest {
|
||||
|
||||
@Test
|
||||
public void whenFiniteVehicleManagerIsCreated_itShouldReturnCorrectManager(){
|
||||
// VehicleFleetManager vfm = new FiniteFleetManagerFactory(Arrays.asList(mock(Vehicle.class))).createFleetManager();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -28,7 +28,7 @@ import jsprit.core.problem.vehicle.VehicleImpl;
|
|||
import jsprit.core.problem.vehicle.VehicleTypeImpl;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class TestVehicleFleetManager extends TestCase{
|
||||
public class TestVehicleFleetManagerImpl extends TestCase{
|
||||
|
||||
VehicleFleetManager fleetManager;
|
||||
|
||||
|
|
@ -1,7 +1,102 @@
|
|||
package jsprit.core.problem.vehicle;
|
||||
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
import jsprit.core.problem.vehicle.VehicleImpl.NoVehicle;
|
||||
import jsprit.core.util.Coordinate;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
|
||||
public class VehicleImplTest {
|
||||
|
||||
@Test
|
||||
public void whenSettingTypeWithBuilder_typeShouldBeSet(){
|
||||
VehicleType type = mock(VehicleType.class);
|
||||
Vehicle v = VehicleImpl.Builder.newInstance("v").setLocationId("loc").setType(type).build();
|
||||
assertEquals(type,v.getType());
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException.class)
|
||||
public void whenTypeIsNull_itThrowsIllegalStateException(){
|
||||
@SuppressWarnings("unused")
|
||||
Vehicle v = VehicleImpl.Builder.newInstance("v").setLocationId("loc").setType(null).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenTypeIsNotSet_defaultTypeIsSet(){
|
||||
Vehicle v = VehicleImpl.Builder.newInstance("v").setLocationId("loc").build();
|
||||
assertEquals("default",v.getType().getTypeId());
|
||||
assertEquals(0,v.getType().getCapacity());
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException.class)
|
||||
public void whenVehicleIsBuiltWithoutSettingNeitherLocationNorCoord_itThrowsAnIllegalStateException(){
|
||||
@SuppressWarnings("unused")
|
||||
Vehicle v = VehicleImpl.Builder.newInstance("v").build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenVehicleIsBuiltAndReturnToDepotFlagIsNotSet_itShouldReturnToDepot(){
|
||||
Vehicle v = VehicleImpl.Builder.newInstance("v").setLocationId("loc").build();
|
||||
assertTrue(v.isReturnToDepot());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenVehicleIsBuiltToReturnToDepot_itShouldReturnToDepot(){
|
||||
Vehicle v = VehicleImpl.Builder.newInstance("v").setReturnToDepot(true).setLocationId("loc").build();
|
||||
assertTrue(v.isReturnToDepot());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenVehicleIsBuiltToNotReturnToDepot_itShouldNotReturnToDepot(){
|
||||
Vehicle v = VehicleImpl.Builder.newInstance("v").setReturnToDepot(false).setLocationId("loc").build();
|
||||
assertFalse(v.isReturnToDepot());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenVehicleIsBuiltWithLocation_itShouldHvTheCorrectLocation(){
|
||||
Vehicle v = VehicleImpl.Builder.newInstance("v").setLocationId("loc").build();
|
||||
assertEquals("loc",v.getLocationId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenVehicleIsBuiltWithCoord_itShouldHvTheCorrectCoord(){
|
||||
Vehicle v = VehicleImpl.Builder.newInstance("v").setLocationCoord(Coordinate.newInstance(1, 2)).build();
|
||||
assertEquals(1.0,v.getCoord().getX(),0.01);
|
||||
assertEquals(2.0,v.getCoord().getY(),0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenVehicleIsBuiltAndEarliestStartIsNotSet_itShouldSetTheDefaultOfZero(){
|
||||
Vehicle v = VehicleImpl.Builder.newInstance("v").setLocationCoord(Coordinate.newInstance(1, 2)).build();
|
||||
assertEquals(0.0,v.getEarliestDeparture(),0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenVehicleIsBuiltAndEarliestStartSet_itShouldBeSetCorrectly(){
|
||||
Vehicle v = VehicleImpl.Builder.newInstance("v").setEarliestStart(10.0).setLocationCoord(Coordinate.newInstance(1, 2)).build();
|
||||
assertEquals(10.0,v.getEarliestDeparture(),0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenVehicleIsBuiltAndLatestArrivalIsNotSet_itShouldSetDefaultOfDoubleMaxValue(){
|
||||
Vehicle v = VehicleImpl.Builder.newInstance("v").setLocationCoord(Coordinate.newInstance(1, 2)).build();
|
||||
assertEquals(Double.MAX_VALUE,v.getLatestArrival(),0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenVehicleIsBuiltAndLatestArrivalIsSet_itShouldBeSetCorrectly(){
|
||||
Vehicle v = VehicleImpl.Builder.newInstance("v").setLatestArrival(30.0).setLocationCoord(Coordinate.newInstance(1, 2)).build();
|
||||
assertEquals(30.0,v.getLatestArrival(),0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenNoVehicleIsCreate_itShouldHvTheCorrectId(){
|
||||
Vehicle v = VehicleImpl.createNoVehicle();
|
||||
assertTrue(v instanceof NoVehicle);
|
||||
assertEquals("noVehicle",v.getId());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import org.junit.Test;
|
|||
|
||||
public class VehicleTypeImplTest {
|
||||
|
||||
|
||||
@Test(expected=IllegalStateException.class)
|
||||
public void whenTypeHasNegativeCapacityVal_throwIllegalStateExpception(){
|
||||
@SuppressWarnings("unused")
|
||||
|
|
@ -50,4 +51,80 @@ public class VehicleTypeImplTest {
|
|||
assertEquals(20,type.getCapacityDimensions().get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCallingStaticNewBuilderInstance_itShouldReturnNewBuilderInstance(){
|
||||
VehicleTypeImpl.Builder builder = VehicleTypeImpl.Builder.newInstance("foo", 0);
|
||||
assertNotNull(builder);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenBuildingTypeJustByCallingNewInstance_typeIdMustBeCorrect(){
|
||||
VehicleTypeImpl type = VehicleTypeImpl.Builder.newInstance("foo", 0).build();
|
||||
assertEquals("foo",type.getTypeId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenBuildingTypeJustByCallingNewInstance_capMustBeCorrect(){
|
||||
VehicleTypeImpl type = VehicleTypeImpl.Builder.newInstance("foo", 0).build();
|
||||
assertEquals(0,type.getCapacity());
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException.class)
|
||||
public void whenBuildingTypeWithCapSmallerThanZero_throwIllegalStateException(){
|
||||
@SuppressWarnings("unused")
|
||||
VehicleTypeImpl type = VehicleTypeImpl.Builder.newInstance("foo", -10).build();
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException.class)
|
||||
public void whenBuildingTypeWithNullId_throwIllegalStateException(){
|
||||
@SuppressWarnings("unused")
|
||||
VehicleTypeImpl type = VehicleTypeImpl.Builder.newInstance(null, 10).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSettingMaxVelocity_itShouldBeSetCorrectly(){
|
||||
VehicleTypeImpl type = VehicleTypeImpl.Builder.newInstance("type", 10).setMaxVelocity(10).build();
|
||||
assertEquals(10,type.getMaxVelocity(),0.0);
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException.class)
|
||||
public void whenMaxVelocitySmallerThanZero_itShouldThrowException(){
|
||||
@SuppressWarnings("unused")
|
||||
VehicleTypeImpl type = VehicleTypeImpl.Builder.newInstance("type", 10).setMaxVelocity(-10).build();
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException.class)
|
||||
public void whenFixedCostsSmallerThanZero_itShouldThrowException(){
|
||||
@SuppressWarnings("unused")
|
||||
VehicleTypeImpl type = VehicleTypeImpl.Builder.newInstance("type", 10).setFixedCost(-10).build();
|
||||
}
|
||||
|
||||
public void whenSettingFixedCosts_itShouldBeSetCorrectly(){
|
||||
VehicleTypeImpl type = VehicleTypeImpl.Builder.newInstance("type", 10).setFixedCost(10).build();
|
||||
assertEquals(10.0, type.getVehicleCostParams().fix,0.0);
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException.class)
|
||||
public void whenPerDistanceCostsSmallerThanZero_itShouldThrowException(){
|
||||
@SuppressWarnings("unused")
|
||||
VehicleTypeImpl type = VehicleTypeImpl.Builder.newInstance("type", 10).setCostPerDistance(-10).build();
|
||||
}
|
||||
|
||||
public void whenSettingPerDistanceCosts_itShouldBeSetCorrectly(){
|
||||
VehicleTypeImpl type = VehicleTypeImpl.Builder.newInstance("type", 10).setCostPerDistance(10).build();
|
||||
assertEquals(10.0, type.getVehicleCostParams().perDistanceUnit,0.0);
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException.class)
|
||||
public void whenPerTimeCostsSmallerThanZero_itShouldThrowException(){
|
||||
@SuppressWarnings("unused")
|
||||
VehicleTypeImpl type = VehicleTypeImpl.Builder.newInstance("type", 10).setCostPerTime(-10).build();
|
||||
}
|
||||
|
||||
public void whenSettingPerTimeCosts_itShouldBeSetCorrectly(){
|
||||
VehicleTypeImpl type = VehicleTypeImpl.Builder.newInstance("type", 10).setCostPerTime(10).build();
|
||||
assertEquals(10.0, type.getVehicleCostParams().perDistanceUnit,0.0);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
73
jsprit-examples/input/algorithmConfigWithSchrimpfAcceptance.xml
Executable file
73
jsprit-examples/input/algorithmConfigWithSchrimpfAcceptance.xml
Executable file
|
|
@ -0,0 +1,73 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright (C) 2013 Stefan Schroeder
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
Contributors:
|
||||
Stefan Schroeder - initial API and implementation
|
||||
-->
|
||||
<algorithm xmlns="http://www.w3schools.com"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3schools.com algorithm_schema.xsd">
|
||||
|
||||
<iterations>2000</iterations>
|
||||
|
||||
<construction>
|
||||
<insertion name="bestInsertion"/>
|
||||
</construction>
|
||||
|
||||
<strategy>
|
||||
<memory>1</memory>
|
||||
<searchStrategies>
|
||||
<searchStrategy name="radialRuinAndRecreate">
|
||||
<selector name="selectBest"/>
|
||||
<acceptor name="schrimpfAcceptance">
|
||||
<alpha>0.05</alpha>
|
||||
<warmup>20</warmup>
|
||||
</acceptor>
|
||||
|
||||
<modules>
|
||||
<module name="ruin_and_recreate">
|
||||
<ruin name="randomRuin">
|
||||
<share>0.5</share>
|
||||
</ruin>
|
||||
<insertion name="bestInsertion"/>
|
||||
</module>
|
||||
|
||||
</modules>
|
||||
<probability>0.5</probability>
|
||||
</searchStrategy>
|
||||
|
||||
<searchStrategy name="radialRuinAndRecreate">
|
||||
<selector name="selectBest"/>
|
||||
<acceptor name="schrimpfAcceptance"/>
|
||||
|
||||
<modules>
|
||||
<module name="ruin_and_recreate">
|
||||
<ruin id="1" name="radialRuin">
|
||||
<share>0.3</share>
|
||||
</ruin>
|
||||
<insertion name="bestInsertion"/>
|
||||
</module>
|
||||
|
||||
</modules>
|
||||
<probability>0.5</probability>
|
||||
</searchStrategy>
|
||||
|
||||
</searchStrategies>
|
||||
</strategy>
|
||||
|
||||
|
||||
</algorithm>
|
||||
75
jsprit-examples/input/algorithmConfig_considerFixedCosts.xml
Executable file
75
jsprit-examples/input/algorithmConfig_considerFixedCosts.xml
Executable file
|
|
@ -0,0 +1,75 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright (C) 2013 Stefan Schroeder
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
Contributors:
|
||||
Stefan Schroeder - initial API and implementation
|
||||
-->
|
||||
<algorithm xmlns="http://www.w3schools.com"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3schools.com algorithm_schema.xsd">
|
||||
|
||||
<iterations>2000</iterations>
|
||||
|
||||
<construction>
|
||||
<insertion name="bestInsertion">
|
||||
<considerFixedCosts weight="1.0">true</considerFixedCosts>
|
||||
</insertion>
|
||||
</construction>
|
||||
|
||||
<strategy>
|
||||
<memory>1</memory>
|
||||
<searchStrategies>
|
||||
<searchStrategy name="radialRuinAndRecreate">
|
||||
<selector name="selectBest"/>
|
||||
<acceptor name="schrimpfAcceptance">
|
||||
<alpha>0.05</alpha>
|
||||
<warmup>20</warmup>
|
||||
</acceptor>
|
||||
|
||||
<modules>
|
||||
<module name="ruin_and_recreate">
|
||||
<ruin name="randomRuin">
|
||||
<share>0.5</share>
|
||||
</ruin>
|
||||
<insertion name="bestInsertion"/>
|
||||
</module>
|
||||
|
||||
</modules>
|
||||
<probability>0.5</probability>
|
||||
</searchStrategy>
|
||||
|
||||
<searchStrategy name="radialRuinAndRecreate">
|
||||
<selector name="selectBest"/>
|
||||
<acceptor name="schrimpfAcceptance"/>
|
||||
|
||||
<modules>
|
||||
<module name="ruin_and_recreate">
|
||||
<ruin id="1" name="radialRuin">
|
||||
<share>0.3</share>
|
||||
</ruin>
|
||||
<insertion name="bestInsertion"/>
|
||||
</module>
|
||||
|
||||
</modules>
|
||||
<probability>0.5</probability>
|
||||
</searchStrategy>
|
||||
|
||||
</searchStrategies>
|
||||
</strategy>
|
||||
|
||||
|
||||
</algorithm>
|
||||
76
jsprit-examples/input/algorithmConfig_considerFixedCosts_routeLevel.xml
Executable file
76
jsprit-examples/input/algorithmConfig_considerFixedCosts_routeLevel.xml
Executable file
|
|
@ -0,0 +1,76 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright (C) 2013 Stefan Schroeder
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
Contributors:
|
||||
Stefan Schroeder - initial API and implementation
|
||||
-->
|
||||
<algorithm xmlns="http://www.w3schools.com"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3schools.com algorithm_schema.xsd">
|
||||
|
||||
<iterations>2000</iterations>
|
||||
|
||||
<construction>
|
||||
<insertion name="bestInsertion">
|
||||
<level forwardLooking="3" memory="2">route</level>
|
||||
<considerFixedCosts weight="1.0">true</considerFixedCosts>
|
||||
</insertion>
|
||||
</construction>
|
||||
|
||||
<strategy>
|
||||
<memory>1</memory>
|
||||
<searchStrategies>
|
||||
<searchStrategy name="radialRuinAndRecreate">
|
||||
<selector name="selectBest"/>
|
||||
<acceptor name="schrimpfAcceptance">
|
||||
<alpha>0.05</alpha>
|
||||
<warmup>20</warmup>
|
||||
</acceptor>
|
||||
|
||||
<modules>
|
||||
<module name="ruin_and_recreate">
|
||||
<ruin name="randomRuin">
|
||||
<share>0.5</share>
|
||||
</ruin>
|
||||
<insertion name="bestInsertion"/>
|
||||
</module>
|
||||
|
||||
</modules>
|
||||
<probability>0.5</probability>
|
||||
</searchStrategy>
|
||||
|
||||
<searchStrategy name="radialRuinAndRecreate">
|
||||
<selector name="selectBest"/>
|
||||
<acceptor name="schrimpfAcceptance"/>
|
||||
|
||||
<modules>
|
||||
<module name="ruin_and_recreate">
|
||||
<ruin id="1" name="radialRuin">
|
||||
<share>0.3</share>
|
||||
</ruin>
|
||||
<insertion name="bestInsertion"/>
|
||||
</module>
|
||||
|
||||
</modules>
|
||||
<probability>0.5</probability>
|
||||
</searchStrategy>
|
||||
|
||||
</searchStrategies>
|
||||
</strategy>
|
||||
|
||||
|
||||
</algorithm>
|
||||
67
jsprit-examples/input/cn_14mix.txt
Normal file
67
jsprit-examples/input/cn_14mix.txt
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
50
|
||||
0 40 40 0
|
||||
1 22 22 18
|
||||
2 36 26 26
|
||||
3 21 45 11
|
||||
4 45 35 30
|
||||
5 55 20 21
|
||||
6 33 34 19
|
||||
7 50 50 15
|
||||
8 55 45 16
|
||||
9 26 59 29
|
||||
10 40 66 26
|
||||
11 55 65 37
|
||||
12 35 51 16
|
||||
13 62 35 12
|
||||
14 62 57 31
|
||||
15 62 24 8
|
||||
16 21 36 19
|
||||
17 33 44 20
|
||||
18 9 56 13
|
||||
19 62 48 15
|
||||
20 66 14 22
|
||||
21 44 13 28
|
||||
22 26 13 12
|
||||
23 11 28 6
|
||||
24 7 43 27
|
||||
25 17 64 14
|
||||
26 41 46 18
|
||||
27 55 34 17
|
||||
28 35 16 29
|
||||
29 52 26 13
|
||||
30 43 26 22
|
||||
31 31 76 25
|
||||
32 22 53 28
|
||||
33 26 29 27
|
||||
34 50 40 19
|
||||
35 55 50 10
|
||||
36 54 10 12
|
||||
37 60 15 14
|
||||
38 47 66 24
|
||||
39 30 60 16
|
||||
40 30 50 33
|
||||
41 12 17 15
|
||||
42 15 14 11
|
||||
43 16 19 18
|
||||
44 21 48 17
|
||||
45 50 30 21
|
||||
46 51 42 27
|
||||
47 50 15 19
|
||||
48 48 21 20
|
||||
49 12 38 5
|
||||
50 15 56 22
|
||||
//Vehicles characteristics: volume, fixed cost, variable cost, number available
|
||||
v 1 120 1000 1.0 4
|
||||
v 2 160 1500 1.1 2
|
||||
v 3 300 3500 1.4 1
|
||||
|
||||
160
|
||||
8 300 0 10000 625.679906 + 7*1000 + 1500 =
|
||||
7 26 7 35 19 8 46 34 10530637
|
||||
4 10 38 11 14 10794953
|
||||
8 33 1 43 42 41 23 49 16 10916479
|
||||
6 48 47 36 21 28 22 10931709
|
||||
7 27 13 15 20 37 5 29 10832981
|
||||
6 44 32 50 18 24 3 10862722
|
||||
5 6 2 30 45 4 10469680
|
||||
7 12 39 31 25 9 40 17 15917639
|
||||
|
|
@ -228,6 +228,8 @@ public class BicycleMessenger {
|
|||
problemBuilder.addConstraint(new ThreeTimesLessThanBestDirectRouteConstraint(nearestMessengers, routingCosts, stateManager));
|
||||
problemBuilder.addConstraint(new IgnoreMessengerThatCanNeverMeetTimeRequirements(nearestMessengers, routingCosts));
|
||||
|
||||
problemBuilder.addPenaltyVehicles(10.0,50000);
|
||||
|
||||
//finally build the problem
|
||||
VehicleRoutingProblem bicycleMessengerProblem = problemBuilder.build();
|
||||
|
||||
|
|
@ -347,8 +349,8 @@ public class BicycleMessenger {
|
|||
*
|
||||
* it is important to give it the same typeId as the type you want to shadow
|
||||
*/
|
||||
VehicleType penaltyType = VehicleTypeImpl.Builder.newInstance("messengerType", 15).setFixedCost(50000).setCostPerDistance(4).build();
|
||||
PenaltyVehicleType penaltyVehicleType = new PenaltyVehicleType(penaltyType,4);
|
||||
// VehicleType penaltyType = VehicleTypeImpl.Builder.newInstance("messengerType", 15).setFixedCost(50000).setCostPerDistance(4).build();
|
||||
// PenaltyVehicleType penaltyVehicleType = new PenaltyVehicleType(penaltyType,4);
|
||||
|
||||
while((line = reader.readLine()) != null){
|
||||
if(firstLine) { firstLine = false; continue; }
|
||||
|
|
@ -358,9 +360,9 @@ public class BicycleMessenger {
|
|||
.setReturnToDepot(false).setType(messengerType).build();
|
||||
problemBuilder.addVehicle(vehicle);
|
||||
//build the penalty vehicle
|
||||
Vehicle penaltyVehicle = VehicleImpl.Builder.newInstance(tokens[1]+"_penalty").setLocationCoord(Coordinate.newInstance(Double.parseDouble(tokens[2]), Double.parseDouble(tokens[3])))
|
||||
.setReturnToDepot(false).setType(penaltyVehicleType).build();
|
||||
problemBuilder.addVehicle(penaltyVehicle);
|
||||
// Vehicle penaltyVehicle = VehicleImpl.Builder.newInstance(tokens[1]+"_penalty").setLocationCoord(Coordinate.newInstance(Double.parseDouble(tokens[2]), Double.parseDouble(tokens[3])))
|
||||
// .setReturnToDepot(false).setType(penaltyVehicleType).build();
|
||||
// problemBuilder.addVehicle(penaltyVehicle);
|
||||
}
|
||||
reader.close();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,32 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (C) 2013 Stefan Schroeder
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
******************************************************************************/
|
||||
package jsprit.examples;
|
||||
|
||||
import jsprit.core.problem.VehicleRoutingProblem;
|
||||
import jsprit.core.problem.io.VrpXMLWriter;
|
||||
import jsprit.instance.reader.ChristofidesReader;
|
||||
|
||||
public class CVRPExample {
|
||||
|
||||
public static void main(String[] args) {
|
||||
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
|
||||
new ChristofidesReader(builder).read("input/vrpnc1.txt");
|
||||
VehicleRoutingProblem vrp = builder.build();
|
||||
new VrpXMLWriter(vrp).write("input/vrpnc1-jsprit.xml");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
package jsprit.examples;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import jsprit.analysis.toolbox.AlgorithmSearchProgressChartListener;
|
||||
import jsprit.analysis.toolbox.GraphStreamViewer;
|
||||
import jsprit.analysis.toolbox.Plotter;
|
||||
import jsprit.analysis.toolbox.SolutionPrinter;
|
||||
import jsprit.analysis.toolbox.SolutionPrinter.Print;
|
||||
import jsprit.core.algorithm.VehicleRoutingAlgorithm;
|
||||
import jsprit.core.algorithm.io.VehicleRoutingAlgorithms;
|
||||
import jsprit.core.problem.VehicleRoutingProblem;
|
||||
import jsprit.core.problem.solution.VehicleRoutingProblemSolution;
|
||||
import jsprit.core.util.Solutions;
|
||||
import jsprit.instance.reader.VrphGoldenReader;
|
||||
import jsprit.instance.reader.VrphGoldenReader.VrphType;
|
||||
import jsprit.util.Examples;
|
||||
|
||||
/**
|
||||
* Shows how to benchmark the algorithm on different classical HVRP and FSM instances.
|
||||
*
|
||||
* <p>These instances are from Golden and Taillard and copied from
|
||||
* <a href=http://mistic.heig-vd.ch/taillard/problemes.dir/vrp.dir/vrp.html>.
|
||||
*
|
||||
* <p>You can find best results of different problems, instances and authors here:
|
||||
* <br><a href="http://www2.ic.uff.br/~satoru/conteudo/artigos/PAPER%20PUCA-JHeuristics-2011.pdf">http://www2.ic.uff.br/~satoru/conteudo/artigos/PAPER%20PUCA-JHeuristics-2011.pdf</a>
|
||||
* <br><a href="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.100.2331&rep=rep1&type=pdf">http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.100.2331&rep=rep1&type=pdf</a>
|
||||
*
|
||||
* @author schroeder
|
||||
*
|
||||
*/
|
||||
public class HVRPBenchmarkExample {
|
||||
|
||||
public static void main(String[] args) {
|
||||
Examples.createOutputFolder();
|
||||
VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
|
||||
//read modified Golden-instance, you can find all relevant instances in jsprit-instances/instances/vrph
|
||||
//you can build various problems, see VrphType doc for more details
|
||||
new VrphGoldenReader(vrpBuilder, VrphType.HVRPFD).read("input/cn_14mix.txt");
|
||||
vrpBuilder.addPenaltyVehicles(10.0);
|
||||
VehicleRoutingProblem vrp = vrpBuilder.build();
|
||||
|
||||
//try also input//jsprit-examples/input/algorithmConfig_considerFixedCosts_routeLevel.xml
|
||||
//results might even be a bit better, but it is slower, since it checks insertion on routeLevel
|
||||
//rather than on local level
|
||||
VehicleRoutingAlgorithm vra = VehicleRoutingAlgorithms.readAndCreateAlgorithm(vrp, "input/algorithmConfig_considerFixedCosts.xml");
|
||||
vra.setNuOfIterations(10000);
|
||||
// vra.setPrematureAlgorithmTermination(new IterationWithoutImprovementTermination(500));
|
||||
vra.addListener(new AlgorithmSearchProgressChartListener("output/progress.png"));
|
||||
Collection<VehicleRoutingProblemSolution> solutions = vra.searchSolutions();
|
||||
|
||||
VehicleRoutingProblemSolution best = Solutions.bestOf(solutions);
|
||||
|
||||
SolutionPrinter.print(vrp, best, Print.VERBOSE);
|
||||
|
||||
|
||||
Plotter plotter = new Plotter(vrp,best);
|
||||
plotter.plot("output/cn14.png", "cn14");
|
||||
|
||||
new GraphStreamViewer(vrp, best).setRenderDelay(100).display();
|
||||
}
|
||||
|
||||
}
|
||||
117
jsprit-examples/src/main/java/jsprit/examples/HVRPExample.java
Normal file
117
jsprit-examples/src/main/java/jsprit/examples/HVRPExample.java
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
package jsprit.examples;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import jsprit.analysis.toolbox.GraphStreamViewer;
|
||||
import jsprit.analysis.toolbox.SolutionPrinter;
|
||||
import jsprit.analysis.toolbox.SolutionPrinter.Print;
|
||||
import jsprit.core.algorithm.VehicleRoutingAlgorithm;
|
||||
import jsprit.core.algorithm.io.VehicleRoutingAlgorithms;
|
||||
import jsprit.core.problem.VehicleRoutingProblem;
|
||||
import jsprit.core.problem.VehicleRoutingProblem.FleetSize;
|
||||
import jsprit.core.problem.job.Service;
|
||||
import jsprit.core.problem.solution.VehicleRoutingProblemSolution;
|
||||
import jsprit.core.problem.vehicle.VehicleImpl;
|
||||
import jsprit.core.problem.vehicle.VehicleType;
|
||||
import jsprit.core.problem.vehicle.VehicleTypeImpl;
|
||||
import jsprit.core.util.Coordinate;
|
||||
import jsprit.core.util.Solutions;
|
||||
|
||||
/**
|
||||
* customers (id,x,y,demand)
|
||||
* 1 22 22 18
|
||||
* 2 36 26 26
|
||||
* 3 21 45 11
|
||||
* 4 45 35 30
|
||||
* 5 55 20 21
|
||||
* 6 33 34 19
|
||||
* 7 50 50 15
|
||||
* 8 55 45 16
|
||||
* 9 26 59 29
|
||||
* 10 40 66 26
|
||||
* 11 55 65 37
|
||||
* 12 35 51 16
|
||||
* 13 62 35 12
|
||||
* 14 62 57 31
|
||||
* 15 62 24 8
|
||||
* 16 21 36 19
|
||||
* 17 33 44 20
|
||||
* 18 9 56 13
|
||||
* 19 62 48 15
|
||||
* 20 66 14 22
|
||||
*
|
||||
* vehicles (id,cap,fixed costs, perDistance, #vehicles) at location (40,40)
|
||||
* 1 120 1000 1.0 2
|
||||
* 2 160 1500 1.1 1
|
||||
* 3 300 3500 1.4 1
|
||||
*
|
||||
* @author schroeder
|
||||
*
|
||||
*/
|
||||
public class HVRPExample {
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
|
||||
|
||||
//add customers
|
||||
vrpBuilder.addJob(Service.Builder.newInstance("1", 18).setCoord(Coordinate.newInstance(22, 22)).build());
|
||||
vrpBuilder.addJob(Service.Builder.newInstance("2", 26).setCoord(Coordinate.newInstance(36, 26)).build());
|
||||
vrpBuilder.addJob(Service.Builder.newInstance("3", 11).setCoord(Coordinate.newInstance(21, 45)).build());
|
||||
vrpBuilder.addJob(Service.Builder.newInstance("4", 30).setCoord(Coordinate.newInstance(45, 35)).build());
|
||||
vrpBuilder.addJob(Service.Builder.newInstance("5", 21).setCoord(Coordinate.newInstance(55, 20)).build());
|
||||
vrpBuilder.addJob(Service.Builder.newInstance("6", 19).setCoord(Coordinate.newInstance(33, 34)).build());
|
||||
vrpBuilder.addJob(Service.Builder.newInstance("7", 15).setCoord(Coordinate.newInstance(50, 50)).build());
|
||||
vrpBuilder.addJob(Service.Builder.newInstance("8", 16).setCoord(Coordinate.newInstance(55, 45)).build());
|
||||
vrpBuilder.addJob(Service.Builder.newInstance("9", 29).setCoord(Coordinate.newInstance(26, 59)).build());
|
||||
vrpBuilder.addJob(Service.Builder.newInstance("10", 26).setCoord(Coordinate.newInstance(40, 66)).build());
|
||||
vrpBuilder.addJob(Service.Builder.newInstance("11", 37).setCoord(Coordinate.newInstance(55, 56)).build());
|
||||
vrpBuilder.addJob(Service.Builder.newInstance("12", 16).setCoord(Coordinate.newInstance(35, 51)).build());
|
||||
vrpBuilder.addJob(Service.Builder.newInstance("13", 12).setCoord(Coordinate.newInstance(62, 35)).build());
|
||||
vrpBuilder.addJob(Service.Builder.newInstance("14", 31).setCoord(Coordinate.newInstance(62, 57)).build());
|
||||
vrpBuilder.addJob(Service.Builder.newInstance("15", 8).setCoord(Coordinate.newInstance(62, 24)).build());
|
||||
vrpBuilder.addJob(Service.Builder.newInstance("16", 19).setCoord(Coordinate.newInstance(21, 36)).build());
|
||||
vrpBuilder.addJob(Service.Builder.newInstance("17", 20).setCoord(Coordinate.newInstance(33, 44)).build());
|
||||
vrpBuilder.addJob(Service.Builder.newInstance("18", 13).setCoord(Coordinate.newInstance(9, 56)).build());
|
||||
vrpBuilder.addJob(Service.Builder.newInstance("19", 15).setCoord(Coordinate.newInstance(62, 48)).build());
|
||||
vrpBuilder.addJob(Service.Builder.newInstance("20", 22).setCoord(Coordinate.newInstance(66, 14)).build());
|
||||
|
||||
|
||||
//add vehicle - finite fleet
|
||||
//2xtype1
|
||||
VehicleType type1 = VehicleTypeImpl.Builder.newInstance("type_1", 120).setCostPerDistance(1.0).build();
|
||||
VehicleImpl vehicle1_1 = VehicleImpl.Builder.newInstance("1_1").setLocationCoord(Coordinate.newInstance(40, 40)).setType(type1).build();
|
||||
vrpBuilder.addVehicle(vehicle1_1);
|
||||
VehicleImpl vehicle1_2 = VehicleImpl.Builder.newInstance("1_2").setLocationCoord(Coordinate.newInstance(40, 40)).setType(type1).build();
|
||||
vrpBuilder.addVehicle(vehicle1_2);
|
||||
//1xtype2
|
||||
VehicleType type2 = VehicleTypeImpl.Builder.newInstance("type_2", 160).setCostPerDistance(1.1).build();
|
||||
VehicleImpl vehicle2_1 = VehicleImpl.Builder.newInstance("2_1").setLocationCoord(Coordinate.newInstance(40, 40)).setType(type2).build();
|
||||
vrpBuilder.addVehicle(vehicle2_1);
|
||||
//1xtype3
|
||||
VehicleType type3 = VehicleTypeImpl.Builder.newInstance("type_3", 300).setCostPerDistance(1.3).build();
|
||||
VehicleImpl vehicle3_1 = VehicleImpl.Builder.newInstance("3_1").setLocationCoord(Coordinate.newInstance(40, 40)).setType(type3).build();
|
||||
vrpBuilder.addVehicle(vehicle3_1);
|
||||
|
||||
//add penaltyVehicles to allow invalid solutions temporarily
|
||||
vrpBuilder.addPenaltyVehicles(5, 1000);
|
||||
|
||||
//set fleetsize finite
|
||||
vrpBuilder.setFleetSize(FleetSize.FINITE);
|
||||
|
||||
//build problem
|
||||
VehicleRoutingProblem vrp = vrpBuilder.build();
|
||||
|
||||
VehicleRoutingAlgorithm vra = VehicleRoutingAlgorithms.readAndCreateAlgorithm(vrp, "input/algorithmConfigWithSchrimpfAcceptance.xml");
|
||||
Collection<VehicleRoutingProblemSolution> solutions = vra.searchSolutions();
|
||||
|
||||
VehicleRoutingProblemSolution best = Solutions.bestOf(solutions);
|
||||
|
||||
SolutionPrinter.print(vrp, best, Print.VERBOSE);
|
||||
|
||||
new GraphStreamViewer(vrp, best).setRenderDelay(100).display();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
17
jsprit-examples/src/main/java/jsprit/util/Examples.java
Normal file
17
jsprit-examples/src/main/java/jsprit/util/Examples.java
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
package jsprit.util;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class Examples {
|
||||
|
||||
public static void createOutputFolder(){
|
||||
File dir = new File("output");
|
||||
// if the directory does not exist, create it
|
||||
if (!dir.exists()){
|
||||
System.out.println("creating directory ./output");
|
||||
boolean result = dir.mkdir();
|
||||
if(result) System.out.println("./output created");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
1
jsprit-instances/instances/vrph/README
Normal file
1
jsprit-instances/instances/vrph/README
Normal file
|
|
@ -0,0 +1 @@
|
|||
use VrpGolderReader to read these files
|
||||
29
jsprit-instances/instances/vrph/c20_3mix.txt
Normal file
29
jsprit-instances/instances/vrph/c20_3mix.txt
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
20
|
||||
0 30 40 0
|
||||
1 37 52 7
|
||||
2 49 49 30
|
||||
3 52 64 16
|
||||
4 20 26 9
|
||||
5 40 30 21
|
||||
6 21 47 15
|
||||
7 17 63 19
|
||||
8 31 62 23
|
||||
9 52 33 11
|
||||
10 51 21 5
|
||||
11 42 41 19
|
||||
12 31 32 29
|
||||
13 5 25 23
|
||||
14 12 42 21
|
||||
15 36 16 10
|
||||
16 52 41 15
|
||||
17 27 23 3
|
||||
18 17 33 41
|
||||
19 13 13 9
|
||||
20 57 58 28
|
||||
//Vehicles characteristics: type, volume, fixed cost
|
||||
5
|
||||
v 1 20 20
|
||||
v 2 30 35
|
||||
v 3 40 50
|
||||
v 4 70 120
|
||||
v 5 120 225
|
||||
27
jsprit-instances/instances/vrph/c20_4mix.txt
Normal file
27
jsprit-instances/instances/vrph/c20_4mix.txt
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
20
|
||||
0 30 40 0
|
||||
1 37 52 7
|
||||
2 49 49 30
|
||||
3 52 64 16
|
||||
4 20 26 9
|
||||
5 40 30 21
|
||||
6 21 47 15
|
||||
7 17 63 19
|
||||
8 31 62 23
|
||||
9 52 33 11
|
||||
10 51 21 5
|
||||
11 42 41 19
|
||||
12 31 32 29
|
||||
13 5 25 23
|
||||
14 12 42 21
|
||||
15 36 16 10
|
||||
16 52 41 15
|
||||
17 27 23 3
|
||||
18 17 33 41
|
||||
19 13 13 9
|
||||
20 57 58 28
|
||||
//Vehicles characteristics: type, volume, fixed cost
|
||||
3
|
||||
v 1 60 1000
|
||||
v 2 80 1500
|
||||
v 3 150 3000
|
||||
29
jsprit-instances/instances/vrph/c20_5mix.txt
Normal file
29
jsprit-instances/instances/vrph/c20_5mix.txt
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
20
|
||||
0 30 40 0
|
||||
1 37 52 7
|
||||
2 49 49 30
|
||||
3 52 64 16
|
||||
4 20 26 9
|
||||
5 40 30 21
|
||||
6 21 47 15
|
||||
7 17 63 19
|
||||
8 31 62 23
|
||||
9 52 33 11
|
||||
10 51 21 5
|
||||
11 42 41 19
|
||||
12 31 32 29
|
||||
13 5 25 23
|
||||
14 12 42 21
|
||||
15 36 16 10
|
||||
16 52 41 15
|
||||
17 27 23 3
|
||||
18 17 33 41
|
||||
19 13 13 9
|
||||
20 57 58 28
|
||||
//Vehicles characteristics: type, volume, fixed cost
|
||||
5
|
||||
v 1 20 20
|
||||
v 2 30 35
|
||||
v 3 40 50
|
||||
v 4 70 120
|
||||
v 5 120 225
|
||||
27
jsprit-instances/instances/vrph/c20_6mix.txt
Normal file
27
jsprit-instances/instances/vrph/c20_6mix.txt
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
20
|
||||
0 30 40 0
|
||||
1 37 52 7
|
||||
2 49 49 30
|
||||
3 52 64 16
|
||||
4 20 26 9
|
||||
5 40 30 21
|
||||
6 21 47 15
|
||||
7 17 63 19
|
||||
8 31 62 23
|
||||
9 52 33 11
|
||||
10 51 21 5
|
||||
11 42 41 19
|
||||
12 31 32 29
|
||||
13 5 25 23
|
||||
14 12 42 21
|
||||
15 36 16 10
|
||||
16 52 41 15
|
||||
17 27 23 3
|
||||
18 17 33 41
|
||||
19 13 13 9
|
||||
20 57 58 28
|
||||
//Vehicles characteristics: type, volume, fixed cost
|
||||
3
|
||||
v 1 60 1000
|
||||
v 2 80 1500
|
||||
v 3 150 3000
|
||||
73
jsprit-instances/instances/vrph/cn_13mix.txt
Normal file
73
jsprit-instances/instances/vrph/cn_13mix.txt
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
50
|
||||
0 40 40 0
|
||||
1 22 22 18
|
||||
2 36 26 26
|
||||
3 21 45 11
|
||||
4 45 35 30
|
||||
5 55 20 21
|
||||
6 33 34 19
|
||||
7 50 50 15
|
||||
8 55 45 16
|
||||
9 26 59 29
|
||||
10 40 66 26
|
||||
11 55 65 37
|
||||
12 35 51 16
|
||||
13 62 35 12
|
||||
14 62 57 31
|
||||
15 62 24 8
|
||||
16 21 36 19
|
||||
17 33 44 20
|
||||
18 9 56 13
|
||||
19 62 48 15
|
||||
20 66 14 22
|
||||
21 44 13 28
|
||||
22 26 13 12
|
||||
23 11 28 6
|
||||
24 7 43 27
|
||||
25 17 64 14
|
||||
26 41 46 18
|
||||
27 55 34 17
|
||||
28 35 16 29
|
||||
29 52 26 13
|
||||
30 43 26 22
|
||||
31 31 76 25
|
||||
32 22 53 28
|
||||
33 26 29 27
|
||||
34 50 40 19
|
||||
35 55 50 10
|
||||
36 54 10 12
|
||||
37 60 15 14
|
||||
38 47 66 24
|
||||
39 30 60 16
|
||||
40 30 50 33
|
||||
41 12 17 15
|
||||
42 15 14 11
|
||||
43 16 19 18
|
||||
44 21 48 17
|
||||
45 50 30 21
|
||||
46 51 42 27
|
||||
47 50 15 19
|
||||
48 48 21 20
|
||||
49 12 38 5
|
||||
50 15 56 22
|
||||
//Vehicles characteristics: type, volume, fixed cost, variable cost, number available
|
||||
6
|
||||
v 1 20 20 1.0 4
|
||||
v 2 30 35 1.1 2
|
||||
v 3 40 50 1.2 4
|
||||
v 4 70 120 1.7 4
|
||||
v 5 120 225 2.5 2
|
||||
v 6 200 400 3.2 1
|
||||
|
||||
|
||||
best solution with fixed costs: 588.784723 + 20 + 3*35 + 2*50 + 4*400 = 2413.78
|
||||
2 27 13 807876
|
||||
1 26 321656
|
||||
2 17 12 774254
|
||||
2 34 8 828825
|
||||
1 46 573606
|
||||
1 4 491422
|
||||
9 39 31 10 38 11 14 19 35 7 5129601
|
||||
11 2 28 22 1 43 42 41 23 16 33 6 5102713
|
||||
10 40 32 9 25 50 18 24 49 3 44 5096803
|
||||
11 30 48 21 47 36 37 20 15 5 29 45 5011089
|
||||
67
jsprit-instances/instances/vrph/cn_14mix.txt
Normal file
67
jsprit-instances/instances/vrph/cn_14mix.txt
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
50
|
||||
0 40 40 0
|
||||
1 22 22 18
|
||||
2 36 26 26
|
||||
3 21 45 11
|
||||
4 45 35 30
|
||||
5 55 20 21
|
||||
6 33 34 19
|
||||
7 50 50 15
|
||||
8 55 45 16
|
||||
9 26 59 29
|
||||
10 40 66 26
|
||||
11 55 65 37
|
||||
12 35 51 16
|
||||
13 62 35 12
|
||||
14 62 57 31
|
||||
15 62 24 8
|
||||
16 21 36 19
|
||||
17 33 44 20
|
||||
18 9 56 13
|
||||
19 62 48 15
|
||||
20 66 14 22
|
||||
21 44 13 28
|
||||
22 26 13 12
|
||||
23 11 28 6
|
||||
24 7 43 27
|
||||
25 17 64 14
|
||||
26 41 46 18
|
||||
27 55 34 17
|
||||
28 35 16 29
|
||||
29 52 26 13
|
||||
30 43 26 22
|
||||
31 31 76 25
|
||||
32 22 53 28
|
||||
33 26 29 27
|
||||
34 50 40 19
|
||||
35 55 50 10
|
||||
36 54 10 12
|
||||
37 60 15 14
|
||||
38 47 66 24
|
||||
39 30 60 16
|
||||
40 30 50 33
|
||||
41 12 17 15
|
||||
42 15 14 11
|
||||
43 16 19 18
|
||||
44 21 48 17
|
||||
45 50 30 21
|
||||
46 51 42 27
|
||||
47 50 15 19
|
||||
48 48 21 20
|
||||
49 12 38 5
|
||||
50 15 56 22
|
||||
//Vehicles characteristics: volume, fixed cost, variable cost, number available
|
||||
v 1 120 1000 1.0 4
|
||||
v 2 160 1500 1.1 2
|
||||
v 3 300 3500 1.4 1
|
||||
|
||||
160
|
||||
8 300 0 10000 625.679906 + 7*1000 + 1500 =
|
||||
7 26 7 35 19 8 46 34 10530637
|
||||
4 10 38 11 14 10794953
|
||||
8 33 1 43 42 41 23 49 16 10916479
|
||||
6 48 47 36 21 28 22 10931709
|
||||
7 27 13 15 20 37 5 29 10832981
|
||||
6 44 32 50 18 24 3 10862722
|
||||
5 6 2 30 45 4 10469680
|
||||
7 12 39 31 25 9 40 17 15917639
|
||||
73
jsprit-instances/instances/vrph/cn_15mix.txt
Normal file
73
jsprit-instances/instances/vrph/cn_15mix.txt
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
50
|
||||
0 30 40 0
|
||||
1 37 52 7
|
||||
2 49 49 30
|
||||
3 52 64 16
|
||||
4 20 26 9
|
||||
5 40 30 21
|
||||
6 21 47 15
|
||||
7 17 63 19
|
||||
8 31 62 23
|
||||
9 52 33 11
|
||||
10 51 21 5
|
||||
11 42 41 19
|
||||
12 31 32 29
|
||||
13 5 25 23
|
||||
14 12 42 21
|
||||
15 36 16 10
|
||||
16 52 41 15
|
||||
17 27 23 3
|
||||
18 17 33 41
|
||||
19 13 13 9
|
||||
20 57 58 28
|
||||
21 62 42 8
|
||||
22 42 57 8
|
||||
23 16 57 16
|
||||
24 8 52 10
|
||||
25 7 38 28
|
||||
26 27 68 7
|
||||
27 30 48 15
|
||||
28 43 67 14
|
||||
29 58 48 6
|
||||
30 58 27 19
|
||||
31 37 69 11
|
||||
32 38 46 12
|
||||
33 46 10 23
|
||||
34 61 33 26
|
||||
35 62 63 17
|
||||
36 63 69 6
|
||||
37 32 22 9
|
||||
38 45 35 15
|
||||
39 59 15 14
|
||||
40 5 6 7
|
||||
41 10 17 27
|
||||
42 21 10 13
|
||||
43 5 64 11
|
||||
44 30 15 16
|
||||
45 39 10 10
|
||||
46 32 39 5
|
||||
47 25 32 25
|
||||
48 25 55 17
|
||||
49 48 28 18
|
||||
50 56 37 10
|
||||
//Vehicles characteristics: volume, fixed cost, variable cost, number available
|
||||
//See E. D. Taillard, "A heuristic column generation method for the heterogeneous fleet vrp"
|
||||
//RAIRO Rech. Op<4F>r. 33 (1) 1999, pp 1-14)
|
||||
//see http://ina2.eivd.ch/collaborateurs/etd/articles.dir/vrphen.pdf
|
||||
v 1 50 100 1.0 4
|
||||
v 2 100 250 1.6 3
|
||||
v 3 160 450 2.0 2
|
||||
|
||||
12 160 0 9999999 798.063541 + 8*100 + 4*250 = 2598.06
|
||||
4 24 43 7 26 1888114
|
||||
3 11 16 38 1470725
|
||||
2 25 14 1476007
|
||||
3 6 23 48 1476130
|
||||
3 28 31 8 1675334
|
||||
3 1 2 32 1476635
|
||||
2 4 18 1395853
|
||||
2 47 27 1341971
|
||||
7 12 37 15 45 33 39 10 3412795
|
||||
7 13 41 40 19 42 44 17 3559482
|
||||
6 5 49 30 34 9 46 3212631
|
||||
8 22 3 36 35 20 29 21 50 3594959
|
||||
70
jsprit-instances/instances/vrph/cn_16mix.txt
Normal file
70
jsprit-instances/instances/vrph/cn_16mix.txt
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
50
|
||||
0 30 40 0
|
||||
1 37 52 7
|
||||
2 49 49 30
|
||||
3 52 64 16
|
||||
4 20 26 9
|
||||
5 40 30 21
|
||||
6 21 47 15
|
||||
7 17 63 19
|
||||
8 31 62 23
|
||||
9 52 33 11
|
||||
10 51 21 5
|
||||
11 42 41 19
|
||||
12 31 32 29
|
||||
13 5 25 23
|
||||
14 12 42 21
|
||||
15 36 16 10
|
||||
16 52 41 15
|
||||
17 27 23 3
|
||||
18 17 33 41
|
||||
19 13 13 9
|
||||
20 57 58 28
|
||||
21 62 42 8
|
||||
22 42 57 8
|
||||
23 16 57 16
|
||||
24 8 52 10
|
||||
25 7 38 28
|
||||
26 27 68 7
|
||||
27 30 48 15
|
||||
28 43 67 14
|
||||
29 58 48 6
|
||||
30 58 27 19
|
||||
31 37 69 11
|
||||
32 38 46 12
|
||||
33 46 10 23
|
||||
34 61 33 26
|
||||
35 62 63 17
|
||||
36 63 69 6
|
||||
37 32 22 9
|
||||
38 45 35 15
|
||||
39 59 15 14
|
||||
40 5 6 7
|
||||
41 10 17 27
|
||||
42 21 10 13
|
||||
43 5 64 11
|
||||
44 30 15 16
|
||||
45 39 10 10
|
||||
46 32 39 5
|
||||
47 25 32 25
|
||||
48 25 55 17
|
||||
49 48 28 18
|
||||
50 56 37 10
|
||||
|
||||
v 1 40 100 1.0 2
|
||||
v 2 80 200 1.6 4
|
||||
v 3 140 400 2.1 3
|
||||
|
||||
10 140 0 9999999 741.499345 + 10*200 = 2741.50
|
||||
3 18 4 47 2396248
|
||||
6 15 45 33 39 10 49 2916243
|
||||
5 12 17 44 37 5 2591911
|
||||
4 38 16 2 11 2562466
|
||||
5 24 43 7 23 48 2805845
|
||||
6 29 20 35 36 3 1 2975090
|
||||
5 13 41 40 19 42 3011668
|
||||
6 50 21 34 30 9 46 2813483
|
||||
6 8 26 31 28 22 32 2773629
|
||||
4 27 6 14 25 2568409
|
||||
|
||||
|
||||
94
jsprit-instances/instances/vrph/cn_17mix.txt
Normal file
94
jsprit-instances/instances/vrph/cn_17mix.txt
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
75
|
||||
0 40 40 0
|
||||
1 22 22 18
|
||||
2 36 26 26
|
||||
3 21 45 11
|
||||
4 45 35 30
|
||||
5 55 20 21
|
||||
6 33 34 19
|
||||
7 50 50 15
|
||||
8 55 45 16
|
||||
9 26 59 29
|
||||
10 40 66 26
|
||||
11 55 65 37
|
||||
12 35 51 16
|
||||
13 62 35 12
|
||||
14 62 57 31
|
||||
15 62 24 8
|
||||
16 21 36 19
|
||||
17 33 44 20
|
||||
18 9 56 13
|
||||
19 62 48 15
|
||||
20 66 14 22
|
||||
21 44 13 28
|
||||
22 26 13 12
|
||||
23 11 28 6
|
||||
24 7 43 27
|
||||
25 17 64 14
|
||||
26 41 46 18
|
||||
27 55 34 17
|
||||
28 35 16 29
|
||||
29 52 26 13
|
||||
30 43 26 22
|
||||
31 31 76 25
|
||||
32 22 53 28
|
||||
33 26 29 27
|
||||
34 50 40 19
|
||||
35 55 50 10
|
||||
36 54 10 12
|
||||
37 60 15 14
|
||||
38 47 66 24
|
||||
39 30 60 16
|
||||
40 30 50 33
|
||||
41 12 17 15
|
||||
42 15 14 11
|
||||
43 16 19 18
|
||||
44 21 48 17
|
||||
45 50 30 21
|
||||
46 51 42 27
|
||||
47 50 15 19
|
||||
48 48 21 20
|
||||
49 12 38 5
|
||||
50 15 56 22
|
||||
51 29 39 12
|
||||
52 54 38 19
|
||||
53 55 57 22
|
||||
54 67 41 16
|
||||
55 10 70 7
|
||||
56 6 25 26
|
||||
57 65 27 14
|
||||
58 40 60 21
|
||||
59 70 64 24
|
||||
60 64 4 13
|
||||
61 36 6 15
|
||||
62 30 20 18
|
||||
63 20 30 11
|
||||
64 15 5 28
|
||||
65 50 70 9
|
||||
66 57 72 37
|
||||
67 45 42 30
|
||||
68 38 33 10
|
||||
69 50 4 8
|
||||
70 66 8 11
|
||||
71 59 5 3
|
||||
72 35 60 1
|
||||
73 27 24 6
|
||||
74 40 20 10
|
||||
75 40 37 20
|
||||
//Vehicles characteristics: volume, fixed cost, variable cost, number available
|
||||
//See E. D. Taillard, "A heuristic column generation method for the heterogeneous fleet vrp"
|
||||
//RAIRO Rech. Op<4F>r. 33 (1) 1999, pp 1-14)
|
||||
//see http://ina2.eivd.ch/collaborateurs/etd/articles.dir/vrphen.pdf50 25 1.0 4
|
||||
v 1 120 80 1.2 4
|
||||
v 2 200 150 1.5 2
|
||||
v 3 350 320 1.8 1
|
||||
|
||||
7 350 0 1000000 703.124497 + 7 * 150 = 1753.12
|
||||
14 27 57 15 37 20 70 60 71 69 36 47 5 29 45 2685412
|
||||
8 7 53 14 59 11 66 65 38 2518938
|
||||
11 51 16 49 24 18 50 25 55 31 10 58 2837925
|
||||
10 26 12 72 39 9 32 44 3 40 17 2223923
|
||||
12 6 33 63 23 56 41 43 42 64 22 1 73 2669773
|
||||
10 67 34 46 8 35 19 54 13 52 4 2218010
|
||||
10 68 2 62 28 61 21 74 48 30 75 2377261
|
||||
|
||||
124
jsprit-instances/instances/vrph/cn_18mix.txt
Normal file
124
jsprit-instances/instances/vrph/cn_18mix.txt
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
75
|
||||
0 40 40 0
|
||||
1 22 22 18
|
||||
2 36 26 26
|
||||
3 21 45 11
|
||||
4 45 35 30
|
||||
5 55 20 21
|
||||
6 33 34 19
|
||||
7 50 50 15
|
||||
8 55 45 16
|
||||
9 26 59 29
|
||||
10 40 66 26
|
||||
11 55 65 37
|
||||
12 35 51 16
|
||||
13 62 35 12
|
||||
14 62 57 31
|
||||
15 62 24 8
|
||||
16 21 36 19
|
||||
17 33 44 20
|
||||
18 9 56 13
|
||||
19 62 48 15
|
||||
20 66 14 22
|
||||
21 44 13 28
|
||||
22 26 13 12
|
||||
23 11 28 6
|
||||
24 7 43 27
|
||||
25 17 64 14
|
||||
26 41 46 18
|
||||
27 55 34 17
|
||||
28 35 16 29
|
||||
29 52 26 13
|
||||
30 43 26 22
|
||||
31 31 76 25
|
||||
32 22 53 28
|
||||
33 26 29 27
|
||||
34 50 40 19
|
||||
35 55 50 10
|
||||
36 54 10 12
|
||||
37 60 15 14
|
||||
38 47 66 24
|
||||
39 30 60 16
|
||||
40 30 50 33
|
||||
41 12 17 15
|
||||
42 15 14 11
|
||||
43 16 19 18
|
||||
44 21 48 17
|
||||
45 50 30 21
|
||||
46 51 42 27
|
||||
47 50 15 19
|
||||
48 48 21 20
|
||||
49 12 38 5
|
||||
50 15 56 22
|
||||
51 29 39 12
|
||||
52 54 38 19
|
||||
53 55 57 22
|
||||
54 67 41 16
|
||||
55 10 70 7
|
||||
56 6 25 26
|
||||
57 65 27 14
|
||||
58 40 60 21
|
||||
59 70 64 24
|
||||
60 64 4 13
|
||||
61 36 6 15
|
||||
62 30 20 18
|
||||
63 20 30 11
|
||||
64 15 5 28
|
||||
65 50 70 9
|
||||
66 57 72 37
|
||||
67 45 42 30
|
||||
68 38 33 10
|
||||
69 50 4 8
|
||||
70 66 8 11
|
||||
71 59 5 3
|
||||
72 35 60 1
|
||||
73 27 24 6
|
||||
74 40 20 10
|
||||
75 40 37 20
|
||||
//Vehicles characteristics: volume, fixed cost, variable cost, number available
|
||||
//See E. D. Taillard, "A heuristic column generation method for the heterogeneous fleet vrp"
|
||||
//RAIRO Rech. Op<4F>r. 33 (1) 1999, pp 1-14)
|
||||
//see http://ina2.eivd.ch/collaborateurs/etd/articles.dir/vrphen.pdf
|
||||
v 1 20 10 1.0 4
|
||||
v 2 50 35 1.3 4
|
||||
v 3 100 100 1.9 2
|
||||
v 4 150 180 2.4 2
|
||||
v 5 250 400 2.9 1
|
||||
v 6 400 800 3.2 1
|
||||
|
||||
|
||||
16 400 0 1000000
|
||||
2 4 75 504563
|
||||
2 40 12 663241
|
||||
2 34 46 584164
|
||||
2 6 33 706263
|
||||
2 26 67 521249
|
||||
4 59 66 65 38 1928889
|
||||
5 30 48 47 21 74 1621004
|
||||
8 36 69 71 60 70 20 37 29 2030669
|
||||
6 8 35 14 19 54 13 1786844
|
||||
6 32 25 55 18 50 3 1957187
|
||||
6 45 5 15 57 27 52 1680991
|
||||
6 17 44 24 49 16 51 1714575
|
||||
5 9 39 31 10 72 1856344
|
||||
4 58 11 53 7 1665558
|
||||
5 2 28 61 22 62 1772896
|
||||
10 63 23 56 41 64 42 43 1 73 68 2874657
|
||||
|
||||
2 40 12 663241
|
||||
2 2 30 708780
|
||||
2 34 46 584164
|
||||
2 6 33 706263
|
||||
2 26 67 521249
|
||||
4 59 66 65 38 1928889
|
||||
8 61 69 36 71 60 70 20 37 2163283
|
||||
6 8 35 14 19 54 13 1786844
|
||||
7 63 23 56 41 43 1 73 1845922
|
||||
6 32 25 55 18 50 3 1957187
|
||||
6 45 5 15 57 27 52 1680991
|
||||
6 17 44 24 49 16 51 1714575
|
||||
5 9 39 31 10 72 1856344
|
||||
4 58 11 53 7 1665558
|
||||
5 28 22 64 42 62 1951198
|
||||
2 4 75 504563
|
||||
6 68 74 21 47 48 29 1659867
|
||||
126
jsprit-instances/instances/vrph/cn_19mix.txt
Normal file
126
jsprit-instances/instances/vrph/cn_19mix.txt
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
100
|
||||
0 35 35 0
|
||||
1 41 49 10
|
||||
2 35 17 7
|
||||
3 55 45 13
|
||||
4 55 20 19
|
||||
5 15 30 26
|
||||
6 25 30 3
|
||||
7 20 50 5
|
||||
8 10 43 9
|
||||
9 55 60 16
|
||||
10 30 60 16
|
||||
11 20 65 12
|
||||
12 50 35 19
|
||||
13 30 25 23
|
||||
14 15 10 20
|
||||
15 30 5 8
|
||||
16 10 20 19
|
||||
17 5 30 2
|
||||
18 20 40 12
|
||||
19 15 60 17
|
||||
20 45 65 9
|
||||
21 45 20 11
|
||||
22 45 10 18
|
||||
23 55 5 29
|
||||
24 65 35 3
|
||||
25 65 20 6
|
||||
26 45 30 17
|
||||
27 35 40 16
|
||||
28 41 37 16
|
||||
29 64 42 9
|
||||
30 40 60 21
|
||||
31 31 52 27
|
||||
32 35 69 23
|
||||
33 53 52 11
|
||||
34 65 55 14
|
||||
35 63 65 8
|
||||
36 2 60 5
|
||||
37 20 20 8
|
||||
38 5 5 16
|
||||
39 60 12 31
|
||||
40 40 25 9
|
||||
41 42 7 5
|
||||
42 24 12 5
|
||||
43 23 3 7
|
||||
44 11 14 18
|
||||
45 6 38 16
|
||||
46 2 48 1
|
||||
47 8 56 27
|
||||
48 13 52 36
|
||||
49 6 68 30
|
||||
50 47 47 13
|
||||
51 49 58 10
|
||||
52 27 43 9
|
||||
53 37 31 14
|
||||
54 57 29 18
|
||||
55 63 23 2
|
||||
56 53 12 6
|
||||
57 32 12 7
|
||||
58 36 26 18
|
||||
59 21 24 28
|
||||
60 17 34 3
|
||||
61 12 24 13
|
||||
62 24 58 19
|
||||
63 27 69 10
|
||||
64 15 77 9
|
||||
65 62 77 20
|
||||
66 49 73 25
|
||||
67 67 5 25
|
||||
68 56 39 36
|
||||
69 37 47 6
|
||||
70 37 56 5
|
||||
71 57 68 15
|
||||
72 47 16 25
|
||||
73 44 17 9
|
||||
74 46 13 8
|
||||
75 49 11 18
|
||||
76 49 42 13
|
||||
77 53 43 14
|
||||
78 61 52 3
|
||||
79 57 48 23
|
||||
80 56 37 6
|
||||
81 55 54 26
|
||||
82 15 47 16
|
||||
83 14 37 11
|
||||
84 11 31 7
|
||||
85 16 22 41
|
||||
86 4 18 35
|
||||
87 28 18 26
|
||||
88 26 52 9
|
||||
89 26 35 15
|
||||
90 31 67 3
|
||||
91 15 19 1
|
||||
92 22 22 2
|
||||
93 18 24 22
|
||||
94 26 27 27
|
||||
95 25 24 20
|
||||
96 22 27 11
|
||||
97 25 21 12
|
||||
98 19 21 10
|
||||
99 20 26 9
|
||||
100 18 18 17
|
||||
//Vehicles characteristics: volume, fixed cost, variable cost, number available
|
||||
//See E. D. Taillard, "A heuristic column generation method for the heterogeneous fleet vrp"
|
||||
//RAIRO Rech. Op<4F>r. 33 (1) 1999, pp 1-14)
|
||||
//see http://ina2.eivd.ch/collaborateurs/etd/articles.dir/vrphen.pdf
|
||||
v 1 100 500 1.0 4
|
||||
v 2 200 1200 1.4 3
|
||||
v 3 300 2100 1.7 3
|
||||
|
||||
15 200 0 1000000
|
||||
5 12 80 68 76 28 546700
|
||||
6 77 3 79 81 33 50 560066
|
||||
7 1 30 20 66 32 70 69 591171
|
||||
9 51 9 71 65 35 34 78 29 24 626544
|
||||
6 26 54 4 72 21 40 564109
|
||||
8 53 73 74 75 22 41 2 58 566885
|
||||
6 56 23 67 39 25 55 601888
|
||||
4 59 85 93 99 546338
|
||||
7 88 62 11 63 90 10 31 578753
|
||||
7 8 46 47 36 49 64 19 623582
|
||||
6 27 52 7 48 82 18 560521
|
||||
4 94 95 87 13 540372
|
||||
9 57 15 43 42 14 38 44 100 92 610131
|
||||
9 89 60 83 45 17 84 5 96 6 571667
|
||||
7 61 86 16 91 98 37 97 575109
|
||||
128
jsprit-instances/instances/vrph/cn_20mix.txt
Normal file
128
jsprit-instances/instances/vrph/cn_20mix.txt
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
100
|
||||
0 35 35 0
|
||||
1 41 49 10
|
||||
2 35 17 7
|
||||
3 55 45 13
|
||||
4 55 20 19
|
||||
5 15 30 26
|
||||
6 25 30 3
|
||||
7 20 50 5
|
||||
8 10 43 9
|
||||
9 55 60 16
|
||||
10 30 60 16
|
||||
11 20 65 12
|
||||
12 50 35 19
|
||||
13 30 25 23
|
||||
14 15 10 20
|
||||
15 30 5 8
|
||||
16 10 20 19
|
||||
17 5 30 2
|
||||
18 20 40 12
|
||||
19 15 60 17
|
||||
20 45 65 9
|
||||
21 45 20 11
|
||||
22 45 10 18
|
||||
23 55 5 29
|
||||
24 65 35 3
|
||||
25 65 20 6
|
||||
26 45 30 17
|
||||
27 35 40 16
|
||||
28 41 37 16
|
||||
29 64 42 9
|
||||
30 40 60 21
|
||||
31 31 52 27
|
||||
32 35 69 23
|
||||
33 53 52 11
|
||||
34 65 55 14
|
||||
35 63 65 8
|
||||
36 2 60 5
|
||||
37 20 20 8
|
||||
38 5 5 16
|
||||
39 60 12 31
|
||||
40 40 25 9
|
||||
41 42 7 5
|
||||
42 24 12 5
|
||||
43 23 3 7
|
||||
44 11 14 18
|
||||
45 6 38 16
|
||||
46 2 48 1
|
||||
47 8 56 27
|
||||
48 13 52 36
|
||||
49 6 68 30
|
||||
50 47 47 13
|
||||
51 49 58 10
|
||||
52 27 43 9
|
||||
53 37 31 14
|
||||
54 57 29 18
|
||||
55 63 23 2
|
||||
56 53 12 6
|
||||
57 32 12 7
|
||||
58 36 26 18
|
||||
59 21 24 28
|
||||
60 17 34 3
|
||||
61 12 24 13
|
||||
62 24 58 19
|
||||
63 27 69 10
|
||||
64 15 77 9
|
||||
65 62 77 20
|
||||
66 49 73 25
|
||||
67 67 5 25
|
||||
68 56 39 36
|
||||
69 37 47 6
|
||||
70 37 56 5
|
||||
71 57 68 15
|
||||
72 47 16 25
|
||||
73 44 17 9
|
||||
74 46 13 8
|
||||
75 49 11 18
|
||||
76 49 42 13
|
||||
77 53 43 14
|
||||
78 61 52 3
|
||||
79 57 48 23
|
||||
80 56 37 6
|
||||
81 55 54 26
|
||||
82 15 47 16
|
||||
83 14 37 11
|
||||
84 11 31 7
|
||||
85 16 22 41
|
||||
86 4 18 35
|
||||
87 28 18 26
|
||||
88 26 52 9
|
||||
89 26 35 15
|
||||
90 31 67 3
|
||||
91 15 19 1
|
||||
92 22 22 2
|
||||
93 18 24 22
|
||||
94 26 27 27
|
||||
95 25 24 20
|
||||
96 22 27 11
|
||||
97 25 21 12
|
||||
98 19 21 10
|
||||
99 20 26 9
|
||||
100 18 18 17
|
||||
//Vehicles characteristics: volume, fixed cost, variable cost, number available
|
||||
//See E. D. Taillard, "A heuristic column generation method for the heterogeneous fleet vrp"
|
||||
//RAIRO Rech. Op<4F>r. 33 (1) 1999, pp 1-14)
|
||||
//see http://ina2.eivd.ch/collaborateurs/etd/articles.dir/vrphen.pdf
|
||||
v 1 60 100 1.0 6
|
||||
v 2 140 300 1.7 4
|
||||
v 3 200 500 2.0 3
|
||||
|
||||
17 200 0 100000 1190.858809 + 11*100 + 6*300 = 4090.86
|
||||
2 12 68 143589
|
||||
4 76 3 77 28 144929
|
||||
6 79 78 34 29 24 80 186635
|
||||
7 18 83 8 45 17 84 60 175014
|
||||
4 26 72 73 40 148608
|
||||
5 21 74 75 22 41 165933
|
||||
3 87 97 95 140494
|
||||
3 13 58 53 126834
|
||||
4 50 33 81 1 157707
|
||||
6 42 14 43 15 57 2 183736
|
||||
3 27 89 94 135338
|
||||
8 52 7 48 47 19 11 62 88 383651
|
||||
10 31 10 32 90 63 64 49 36 46 82 429222
|
||||
10 51 9 35 71 65 66 20 30 70 69 415471
|
||||
9 5 61 16 86 38 44 91 98 92 394398
|
||||
8 59 37 100 85 93 99 96 6 352542
|
||||
8 4 56 23 67 39 25 55 54 406754
|
||||
|
|
@ -0,0 +1,176 @@
|
|||
package jsprit.instance.reader;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
|
||||
import jsprit.core.problem.VehicleRoutingProblem;
|
||||
import jsprit.core.problem.VehicleRoutingProblem.Builder;
|
||||
import jsprit.core.problem.VehicleRoutingProblem.FleetSize;
|
||||
import jsprit.core.problem.io.VrpXMLWriter;
|
||||
import jsprit.core.problem.job.Service;
|
||||
import jsprit.core.problem.vehicle.Vehicle;
|
||||
import jsprit.core.problem.vehicle.VehicleImpl;
|
||||
import jsprit.core.problem.vehicle.VehicleTypeImpl;
|
||||
import jsprit.core.util.Coordinate;
|
||||
|
||||
/**
|
||||
* Reads modified files from Taillard's website
|
||||
* http://mistic.heig-vd.ch/taillard/problemes.dir/vrp.dir/vrp.html. You can find the modified version here:
|
||||
* jsprit-instances/instances/vrph.
|
||||
*
|
||||
* <p>See {@link VrphType} what kind of problems can be generated
|
||||
*
|
||||
* <p>Note that c20_3-c20_6 do not have variable costs and a limited nuVehicle, thus they can only be used for FSMF.
|
||||
*
|
||||
* @author schroeder
|
||||
*
|
||||
*/
|
||||
public class VrphGoldenReader {
|
||||
|
||||
/**
|
||||
*
|
||||
* <b>FSMD</b> - Fleet Size and Mix with Dependent costs
|
||||
* <p><b>FSMF</b> - Fleet Size and Mix with Fixed costs
|
||||
* <p><b>FSMFD</b> - Fleet Size and Mix with Fixed and Dependent costs
|
||||
* <p><b>HVRPD</b> - Heterogeneous Vehicle Routing Problem with Dependent costs and finite (limited) fleet
|
||||
* <p><b>HVRPFD</b> - Heterogeneous Vehicle Routing Problem with Fixed and Dependent costs and finite (limited) fleet
|
||||
*
|
||||
* @author schroeder
|
||||
*
|
||||
*/
|
||||
public enum VrphType {
|
||||
FSMD,
|
||||
HVRPD,
|
||||
FSMF,
|
||||
FSMFD,
|
||||
HVRPFD
|
||||
}
|
||||
|
||||
private final VehicleRoutingProblem.Builder vrpBuilder;
|
||||
|
||||
private final VrphType vrphType;
|
||||
|
||||
public VrphGoldenReader(Builder vrpBuilder, VrphType vrphType) {
|
||||
super();
|
||||
this.vrpBuilder = vrpBuilder;
|
||||
this.vrphType = vrphType;
|
||||
}
|
||||
|
||||
public void read(String filename){
|
||||
BufferedReader reader = getReader(filename);
|
||||
String line = null;
|
||||
boolean firstline = true;
|
||||
Coordinate depotCoord = null;
|
||||
int customerCount=0;
|
||||
Integer nuOfCustomer = 0;
|
||||
while((line=readLine(reader))!=null){
|
||||
String trimedLine = line.trim();
|
||||
if(trimedLine.startsWith("//")) continue;
|
||||
String[] tokens = trimedLine.split("\\s+");
|
||||
if(firstline){
|
||||
nuOfCustomer=Integer.parseInt(tokens[0]);
|
||||
customerCount=0;
|
||||
firstline=false;
|
||||
}
|
||||
else if(customerCount<=nuOfCustomer) {
|
||||
if(customerCount == 0){
|
||||
depotCoord = Coordinate.newInstance(Double.parseDouble(tokens[1]), Double.parseDouble(tokens[2]));
|
||||
}
|
||||
else{
|
||||
Service.Builder serviceBuilder = Service.Builder.newInstance(tokens[0], Integer.parseInt(tokens[3]));
|
||||
serviceBuilder.setCoord(Coordinate.newInstance(Double.parseDouble(tokens[1]), Double.parseDouble(tokens[2])));
|
||||
vrpBuilder.addJob(serviceBuilder.build());
|
||||
}
|
||||
customerCount++;
|
||||
}
|
||||
else if(trimedLine.startsWith("v")){
|
||||
VehicleTypeImpl.Builder typeBuilder = VehicleTypeImpl.Builder.newInstance("type_"+tokens[1], Integer.parseInt(tokens[2]));
|
||||
int nuOfVehicles = 1;
|
||||
if(vrphType.equals(VrphType.FSMF)){
|
||||
typeBuilder.setFixedCost(Double.parseDouble(tokens[3]));
|
||||
}
|
||||
else if(vrphType.equals(VrphType.FSMFD)){
|
||||
typeBuilder.setFixedCost(Double.parseDouble(tokens[3]));
|
||||
if(tokens.length > 4){
|
||||
typeBuilder.setCostPerDistance(Double.parseDouble(tokens[4]));
|
||||
}
|
||||
else throw new IllegalStateException("option " + vrphType + " cannot be applied with this instance");
|
||||
}
|
||||
else if(vrphType.equals(VrphType.FSMD)){
|
||||
if(tokens.length > 4){
|
||||
typeBuilder.setCostPerDistance(Double.parseDouble(tokens[4]));
|
||||
}
|
||||
else throw new IllegalStateException("option " + vrphType + " cannot be applied with this instance");
|
||||
}
|
||||
else if(vrphType.equals(VrphType.HVRPD)){
|
||||
if(tokens.length > 4){
|
||||
typeBuilder.setCostPerDistance(Double.parseDouble(tokens[4]));
|
||||
nuOfVehicles = Integer.parseInt(tokens[5]);
|
||||
vrpBuilder.setFleetSize(FleetSize.FINITE);
|
||||
}
|
||||
else throw new IllegalStateException("option " + vrphType + " cannot be applied with this instance");
|
||||
}
|
||||
else if (vrphType.equals(VrphType.HVRPFD)){
|
||||
if(tokens.length > 4){
|
||||
typeBuilder.setFixedCost(Double.parseDouble(tokens[3]));
|
||||
typeBuilder.setCostPerDistance(Double.parseDouble(tokens[4]));
|
||||
nuOfVehicles = Integer.parseInt(tokens[5]);
|
||||
vrpBuilder.setFleetSize(FleetSize.FINITE);
|
||||
}
|
||||
else throw new IllegalStateException("option " + vrphType + " cannot be applied with this instance");
|
||||
}
|
||||
for(int i=0;i<nuOfVehicles;i++){
|
||||
VehicleTypeImpl type = typeBuilder.build();
|
||||
Vehicle vehicle = VehicleImpl.Builder.newInstance("vehicle_"+tokens[1]+"_"+i)
|
||||
.setLocationCoord(depotCoord).setType(type).build();
|
||||
vrpBuilder.addVehicle(vehicle);
|
||||
}
|
||||
}
|
||||
}
|
||||
closeReader(reader);
|
||||
}
|
||||
|
||||
private void closeReader(BufferedReader reader) {
|
||||
try {
|
||||
reader.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
private String readLine(BufferedReader reader) {
|
||||
String readLine = null;
|
||||
try {
|
||||
readLine = reader.readLine();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
return readLine;
|
||||
}
|
||||
|
||||
private BufferedReader getReader(String filename) {
|
||||
BufferedReader bufferedReader = null;
|
||||
try {
|
||||
bufferedReader = new BufferedReader(new FileReader(new File(filename)));
|
||||
return bufferedReader;
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
return bufferedReader;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
|
||||
VrphGoldenReader goldenReader = new VrphGoldenReader(vrpBuilder, VrphType.FSMD);
|
||||
goldenReader.read("instances/vrph/orig/cn_13mix.txt");
|
||||
VehicleRoutingProblem vrp = vrpBuilder.build();
|
||||
new VrpXMLWriter(vrp).write("instances/vrph/cn_13mix_VRPH_INFINITE.xml");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,303 @@
|
|||
package jsprit.instance.reader;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import jsprit.core.problem.VehicleRoutingProblem;
|
||||
import jsprit.core.problem.job.Job;
|
||||
import jsprit.core.problem.job.Service;
|
||||
import jsprit.core.problem.vehicle.Vehicle;
|
||||
import jsprit.core.util.Coordinate;
|
||||
import jsprit.instance.reader.VrphGoldenReader.VrphType;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class GoldenReaderTest {
|
||||
|
||||
@Test
|
||||
public void whenReadingInstance_itShouldReadCorrectNuOfVehicles(){
|
||||
VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
|
||||
new VrphGoldenReader(vrpBuilder, VrphType.HVRPD)
|
||||
.read(this.getClass().getClassLoader().getResource("cn_13mix.txt").getPath());
|
||||
VehicleRoutingProblem vrp = vrpBuilder.build();
|
||||
assertEquals(17,vrp.getVehicles().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenReadingInstance_itShouldReadCorrectNuOfType1Vehicles(){
|
||||
VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
|
||||
new VrphGoldenReader(vrpBuilder, VrphType.HVRPD)
|
||||
.read(this.getClass().getClassLoader().getResource("cn_13mix.txt").getPath());
|
||||
VehicleRoutingProblem vrp = vrpBuilder.build();
|
||||
int nuOfType1Vehicles = 0;
|
||||
for(Vehicle v : vrp.getVehicles()){
|
||||
if(v.getType().getTypeId().equals("type_1")){
|
||||
nuOfType1Vehicles++;
|
||||
}
|
||||
}
|
||||
assertEquals(4,nuOfType1Vehicles);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenReadingInstance_theSumOfType1VehicleShouldHvTheCorrectCapacity(){
|
||||
VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
|
||||
new VrphGoldenReader(vrpBuilder, VrphType.HVRPD)
|
||||
.read(this.getClass().getClassLoader().getResource("cn_13mix.txt").getPath());
|
||||
VehicleRoutingProblem vrp = vrpBuilder.build();
|
||||
int sumOfType1Cap = 0;
|
||||
for(Vehicle v : vrp.getVehicles()){
|
||||
if(v.getType().getTypeId().equals("type_1")){
|
||||
sumOfType1Cap+=v.getCapacity();
|
||||
}
|
||||
}
|
||||
assertEquals(80,sumOfType1Cap);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenReadingInstance_itShouldReadCorrectNuOfType2Vehicles(){
|
||||
VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
|
||||
new VrphGoldenReader(vrpBuilder, VrphType.HVRPD)
|
||||
.read(this.getClass().getClassLoader().getResource("cn_13mix.txt").getPath());
|
||||
VehicleRoutingProblem vrp = vrpBuilder.build();
|
||||
int nuOfType1Vehicles = 0;
|
||||
for(Vehicle v : vrp.getVehicles()){
|
||||
if(v.getType().getTypeId().equals("type_2")){
|
||||
nuOfType1Vehicles++;
|
||||
}
|
||||
}
|
||||
assertEquals(2,nuOfType1Vehicles);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenReadingInstance_theSumOfType2VehicleShouldHvTheCorrectCapacity(){
|
||||
VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
|
||||
new VrphGoldenReader(vrpBuilder, VrphType.HVRPD)
|
||||
.read(this.getClass().getClassLoader().getResource("cn_13mix.txt").getPath());
|
||||
VehicleRoutingProblem vrp = vrpBuilder.build();
|
||||
int sumOfType1Cap = 0;
|
||||
for(Vehicle v : vrp.getVehicles()){
|
||||
if(v.getType().getTypeId().equals("type_2")){
|
||||
sumOfType1Cap+=v.getCapacity();
|
||||
}
|
||||
}
|
||||
assertEquals(60,sumOfType1Cap);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenReadingInstance_itShouldReadCorrectNuOfType3Vehicles(){
|
||||
VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
|
||||
new VrphGoldenReader(vrpBuilder, VrphType.HVRPD)
|
||||
.read(this.getClass().getClassLoader().getResource("cn_13mix.txt").getPath());
|
||||
VehicleRoutingProblem vrp = vrpBuilder.build();
|
||||
int nuOfType1Vehicles = 0;
|
||||
for(Vehicle v : vrp.getVehicles()){
|
||||
if(v.getType().getTypeId().equals("type_3")){
|
||||
nuOfType1Vehicles++;
|
||||
}
|
||||
}
|
||||
assertEquals(4,nuOfType1Vehicles);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenReadingInstance_theSumOfType3VehicleShouldHvTheCorrectCapacity(){
|
||||
VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
|
||||
new VrphGoldenReader(vrpBuilder, VrphType.HVRPD)
|
||||
.read(this.getClass().getClassLoader().getResource("cn_13mix.txt").getPath());
|
||||
VehicleRoutingProblem vrp = vrpBuilder.build();
|
||||
int sumOfType1Cap = 0;
|
||||
for(Vehicle v : vrp.getVehicles()){
|
||||
if(v.getType().getTypeId().equals("type_3")){
|
||||
sumOfType1Cap+=v.getCapacity();
|
||||
}
|
||||
}
|
||||
assertEquals(160,sumOfType1Cap);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenReadingInstance_itShouldReadCorrectNuOfType4Vehicles(){
|
||||
VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
|
||||
new VrphGoldenReader(vrpBuilder, VrphType.HVRPD)
|
||||
.read(this.getClass().getClassLoader().getResource("cn_13mix.txt").getPath());
|
||||
VehicleRoutingProblem vrp = vrpBuilder.build();
|
||||
int nuOfType1Vehicles = 0;
|
||||
for(Vehicle v : vrp.getVehicles()){
|
||||
if(v.getType().getTypeId().equals("type_4")){
|
||||
nuOfType1Vehicles++;
|
||||
}
|
||||
}
|
||||
assertEquals(4,nuOfType1Vehicles);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenReadingInstance_theSumOfType4VehicleShouldHvTheCorrectCapacity(){
|
||||
VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
|
||||
new VrphGoldenReader(vrpBuilder, VrphType.HVRPD)
|
||||
.read(this.getClass().getClassLoader().getResource("cn_13mix.txt").getPath());
|
||||
VehicleRoutingProblem vrp = vrpBuilder.build();
|
||||
int sumOfType1Cap = 0;
|
||||
for(Vehicle v : vrp.getVehicles()){
|
||||
if(v.getType().getTypeId().equals("type_4")){
|
||||
sumOfType1Cap+=v.getCapacity();
|
||||
}
|
||||
}
|
||||
assertEquals(280,sumOfType1Cap);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenReadingInstance_itShouldReadCorrectNuOfType5Vehicles(){
|
||||
VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
|
||||
new VrphGoldenReader(vrpBuilder, VrphType.HVRPD)
|
||||
.read(this.getClass().getClassLoader().getResource("cn_13mix.txt").getPath());
|
||||
VehicleRoutingProblem vrp = vrpBuilder.build();
|
||||
int nuOfType1Vehicles = 0;
|
||||
for(Vehicle v : vrp.getVehicles()){
|
||||
if(v.getType().getTypeId().equals("type_5")){
|
||||
nuOfType1Vehicles++;
|
||||
}
|
||||
}
|
||||
assertEquals(2,nuOfType1Vehicles);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenReadingInstance_theSumOfType5VehicleShouldHvTheCorrectCapacity(){
|
||||
VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
|
||||
new VrphGoldenReader(vrpBuilder, VrphType.HVRPD)
|
||||
.read(this.getClass().getClassLoader().getResource("cn_13mix.txt").getPath());
|
||||
VehicleRoutingProblem vrp = vrpBuilder.build();
|
||||
int sumOfType1Cap = 0;
|
||||
for(Vehicle v : vrp.getVehicles()){
|
||||
if(v.getType().getTypeId().equals("type_5")){
|
||||
sumOfType1Cap+=v.getCapacity();
|
||||
}
|
||||
}
|
||||
assertEquals(240,sumOfType1Cap);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenReadingInstance_itShouldReadCorrectNuOfType6Vehicles(){
|
||||
VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
|
||||
new VrphGoldenReader(vrpBuilder, VrphType.HVRPD)
|
||||
.read(this.getClass().getClassLoader().getResource("cn_13mix.txt").getPath());
|
||||
VehicleRoutingProblem vrp = vrpBuilder.build();
|
||||
int nuOfType1Vehicles = 0;
|
||||
for(Vehicle v : vrp.getVehicles()){
|
||||
if(v.getType().getTypeId().equals("type_6")){
|
||||
nuOfType1Vehicles++;
|
||||
}
|
||||
}
|
||||
assertEquals(1,nuOfType1Vehicles);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenReadingInstance_theSumOfType6VehicleShouldHvTheCorrectCapacity(){
|
||||
VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
|
||||
new VrphGoldenReader(vrpBuilder, VrphType.HVRPD)
|
||||
.read(this.getClass().getClassLoader().getResource("cn_13mix.txt").getPath());
|
||||
VehicleRoutingProblem vrp = vrpBuilder.build();
|
||||
int sumOfType1Cap = 0;
|
||||
for(Vehicle v : vrp.getVehicles()){
|
||||
if(v.getType().getTypeId().equals("type_6")){
|
||||
sumOfType1Cap+=v.getCapacity();
|
||||
}
|
||||
}
|
||||
assertEquals(200,sumOfType1Cap);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenReadingInstance_vehicleShouldHvTheCorrectCoord(){
|
||||
VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
|
||||
new VrphGoldenReader(vrpBuilder, VrphType.HVRPD)
|
||||
.read(this.getClass().getClassLoader().getResource("cn_13mix.txt").getPath());
|
||||
VehicleRoutingProblem vrp = vrpBuilder.build();
|
||||
for(Vehicle v : vrp.getVehicles()){
|
||||
if(v.getCoord().getX() != 40.0){
|
||||
assertFalse(true);
|
||||
}
|
||||
if(v.getCoord().getY() != 40.0){
|
||||
assertFalse(true);
|
||||
}
|
||||
}
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenReadingInstance_service1MustHaveCorrectDemand(){
|
||||
VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
|
||||
new VrphGoldenReader(vrpBuilder, VrphType.HVRPD)
|
||||
.read(this.getClass().getClassLoader().getResource("cn_13mix.txt").getPath());
|
||||
VehicleRoutingProblem vrp = vrpBuilder.build();
|
||||
Job job = getJob("1",vrp);
|
||||
assertEquals(18,job.getCapacityDemand());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenReadingInstance_service1MustHaveCorrectCoordinate(){
|
||||
VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
|
||||
new VrphGoldenReader(vrpBuilder, VrphType.HVRPD)
|
||||
.read(this.getClass().getClassLoader().getResource("cn_13mix.txt").getPath());
|
||||
VehicleRoutingProblem vrp = vrpBuilder.build();
|
||||
Coordinate coord = getCoord("1",vrp);
|
||||
assertEquals(22.0,coord.getX(),0.01);
|
||||
assertEquals(22.0,coord.getY(),0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenReadingInstance_service15MustHaveCorrectCoordinate(){
|
||||
VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
|
||||
new VrphGoldenReader(vrpBuilder, VrphType.HVRPD)
|
||||
.read(this.getClass().getClassLoader().getResource("cn_13mix.txt").getPath());
|
||||
VehicleRoutingProblem vrp = vrpBuilder.build();
|
||||
Coordinate coord = getCoord("15",vrp);
|
||||
assertEquals(62.0,coord.getX(),0.01);
|
||||
assertEquals(24.0,coord.getY(),0.01);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void whenReadingInstance_service50MustHaveCorrectCoordinate(){
|
||||
VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
|
||||
new VrphGoldenReader(vrpBuilder, VrphType.HVRPD)
|
||||
.read(this.getClass().getClassLoader().getResource("cn_13mix.txt").getPath());
|
||||
VehicleRoutingProblem vrp = vrpBuilder.build();
|
||||
Coordinate coord = getCoord("50",vrp);
|
||||
assertEquals(15.0,coord.getX(),0.01);
|
||||
assertEquals(56.0,coord.getY(),0.01);
|
||||
}
|
||||
|
||||
private Coordinate getCoord(String string, VehicleRoutingProblem vrp) {
|
||||
Job j = getJob(string,vrp);
|
||||
return ((Service)j).getCoord();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenReadingInstance_service4MustHaveCorrectDemand(){
|
||||
VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
|
||||
new VrphGoldenReader(vrpBuilder, VrphType.HVRPD)
|
||||
.read(this.getClass().getClassLoader().getResource("cn_13mix.txt").getPath());
|
||||
VehicleRoutingProblem vrp = vrpBuilder.build();
|
||||
Job job = getJob("4",vrp);
|
||||
assertEquals(30,job.getCapacityDemand());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenReadingInstance_service50MustHaveCorrectDemand(){
|
||||
VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
|
||||
new VrphGoldenReader(vrpBuilder, VrphType.HVRPD)
|
||||
.read(this.getClass().getClassLoader().getResource("cn_13mix.txt").getPath());
|
||||
VehicleRoutingProblem vrp = vrpBuilder.build();
|
||||
Job job = getJob("50",vrp);
|
||||
assertEquals(22,job.getCapacityDemand());
|
||||
}
|
||||
|
||||
private Job getJob(String string, VehicleRoutingProblem vrp) {
|
||||
for(Job j : vrp.getJobs().values()){
|
||||
if(j.getId().equals(string)){
|
||||
return j;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
73
jsprit-instances/src/test/resources/cn_13mix.txt
Normal file
73
jsprit-instances/src/test/resources/cn_13mix.txt
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
50
|
||||
0 40 40 0
|
||||
1 22 22 18
|
||||
2 36 26 26
|
||||
3 21 45 11
|
||||
4 45 35 30
|
||||
5 55 20 21
|
||||
6 33 34 19
|
||||
7 50 50 15
|
||||
8 55 45 16
|
||||
9 26 59 29
|
||||
10 40 66 26
|
||||
11 55 65 37
|
||||
12 35 51 16
|
||||
13 62 35 12
|
||||
14 62 57 31
|
||||
15 62 24 8
|
||||
16 21 36 19
|
||||
17 33 44 20
|
||||
18 9 56 13
|
||||
19 62 48 15
|
||||
20 66 14 22
|
||||
21 44 13 28
|
||||
22 26 13 12
|
||||
23 11 28 6
|
||||
24 7 43 27
|
||||
25 17 64 14
|
||||
26 41 46 18
|
||||
27 55 34 17
|
||||
28 35 16 29
|
||||
29 52 26 13
|
||||
30 43 26 22
|
||||
31 31 76 25
|
||||
32 22 53 28
|
||||
33 26 29 27
|
||||
34 50 40 19
|
||||
35 55 50 10
|
||||
36 54 10 12
|
||||
37 60 15 14
|
||||
38 47 66 24
|
||||
39 30 60 16
|
||||
40 30 50 33
|
||||
41 12 17 15
|
||||
42 15 14 11
|
||||
43 16 19 18
|
||||
44 21 48 17
|
||||
45 50 30 21
|
||||
46 51 42 27
|
||||
47 50 15 19
|
||||
48 48 21 20
|
||||
49 12 38 5
|
||||
50 15 56 22
|
||||
//Vehicles characteristics: type, volume, fixed cost, variable cost, number available
|
||||
6
|
||||
v 1 20 20 1.0 4
|
||||
v 2 30 35 1.1 2
|
||||
v 3 40 50 1.2 4
|
||||
v 4 70 120 1.7 4
|
||||
v 5 120 225 2.5 2
|
||||
v 6 200 400 3.2 1
|
||||
|
||||
|
||||
best solution with fixed costs: 588.784723 + 20 + 3*35 + 2*50 + 4*400 = 2413.78
|
||||
2 27 13 807876
|
||||
1 26 321656
|
||||
2 17 12 774254
|
||||
2 34 8 828825
|
||||
1 46 573606
|
||||
1 4 491422
|
||||
9 39 31 10 38 11 14 19 35 7 5129601
|
||||
11 2 28 22 1 43 42 41 23 16 33 6 5102713
|
||||
10 40 32 9 25 50 18 24 49 3 44 5096803
|
||||
11 30 48 21 47 36 37 20 15 5 29 45 5011089
|
||||
Loading…
Add table
Add a link
Reference in a new issue