1
0
Fork 0
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:
oblonski 2014-01-16 15:15:16 -05:00
commit 2993202d49
35 changed files with 2623 additions and 64 deletions

View file

@ -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.
*

View file

@ -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);
}

View file

@ -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() {

View file

@ -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();
}

View file

@ -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)

View file

@ -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);
}
}

View file

@ -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();
}
}

View file

@ -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;

View file

@ -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());
}
}

View file

@ -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);
}
}