mirror of
https://github.com/graphhopper/jsprit.git
synced 2020-01-24 07:45:05 +01:00
added skills
This commit is contained in:
parent
b991793aba
commit
ea7407d936
12 changed files with 1705 additions and 76 deletions
|
|
@ -81,7 +81,20 @@ public class Skills {
|
||||||
return skills.contains(skill.toLowerCase());
|
return skills.contains(skill.toLowerCase());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
|
Skills skills1 = (Skills) o;
|
||||||
|
|
||||||
|
if (skills != null ? !skills.equals(skills1.skills) : skills1.skills != null) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return skills != null ? skills.hashCode() : 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -417,7 +417,7 @@ public class VehicleRoutingProblem {
|
||||||
Set<VehicleTypeKey> vehicleTypeKeys = new HashSet<VehicleTypeKey>();
|
Set<VehicleTypeKey> vehicleTypeKeys = new HashSet<VehicleTypeKey>();
|
||||||
List<Vehicle> uniqueVehicles = new ArrayList<Vehicle>();
|
List<Vehicle> uniqueVehicles = new ArrayList<Vehicle>();
|
||||||
for(Vehicle v : this.uniqueVehicles){
|
for(Vehicle v : this.uniqueVehicles){
|
||||||
VehicleTypeKey key = new VehicleTypeKey(v.getType().getTypeId(),v.getStartLocationId(),v.getEndLocationId(),v.getEarliestDeparture(),v.getLatestArrival());
|
VehicleTypeKey key = new VehicleTypeKey(v.getType().getTypeId(),v.getStartLocationId(),v.getEndLocationId(),v.getEarliestDeparture(),v.getLatestArrival(), v.getSkills());
|
||||||
if(!vehicleTypeKeys.contains(key)){
|
if(!vehicleTypeKeys.contains(key)){
|
||||||
uniqueVehicles.add(v);
|
uniqueVehicles.add(v);
|
||||||
vehicleTypeKeys.add(key);
|
vehicleTypeKeys.add(key);
|
||||||
|
|
@ -439,6 +439,7 @@ public class VehicleRoutingProblem {
|
||||||
VehicleImpl penVehicle = VehicleImpl.Builder.newInstance(vehicleId).setEarliestStart(v.getEarliestDeparture())
|
VehicleImpl penVehicle = VehicleImpl.Builder.newInstance(vehicleId).setEarliestStart(v.getEarliestDeparture())
|
||||||
.setLatestArrival(v.getLatestArrival()).setStartLocationCoordinate(v.getStartLocationCoordinate()).setStartLocationId(v.getStartLocationId())
|
.setLatestArrival(v.getLatestArrival()).setStartLocationCoordinate(v.getStartLocationCoordinate()).setStartLocationId(v.getStartLocationId())
|
||||||
.setEndLocationId(v.getEndLocationId()).setEndLocationCoordinate(v.getEndLocationCoordinate())
|
.setEndLocationId(v.getEndLocationId()).setEndLocationCoordinate(v.getEndLocationCoordinate())
|
||||||
|
.addSkills(v.getSkills())
|
||||||
.setReturnToDepot(v.isReturnToDepot()).setType(penType).build();
|
.setReturnToDepot(v.isReturnToDepot()).setType(penType).build();
|
||||||
addVehicle(penVehicle);
|
addVehicle(penVehicle);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ class InfiniteVehicles implements VehicleFleetManager{
|
||||||
|
|
||||||
private void extractTypes(Collection<Vehicle> vehicles) {
|
private void extractTypes(Collection<Vehicle> vehicles) {
|
||||||
for(Vehicle v : vehicles){
|
for(Vehicle v : vehicles){
|
||||||
VehicleTypeKey typeKey = new VehicleTypeKey(v.getType().getTypeId(), v.getStartLocationId(),v.getEndLocationId(), v.getEarliestDeparture(), v.getLatestArrival());
|
VehicleTypeKey typeKey = new VehicleTypeKey(v.getType().getTypeId(), v.getStartLocationId(),v.getEndLocationId(), v.getEarliestDeparture(), v.getLatestArrival(), v.getSkills());
|
||||||
types.put(typeKey,v);
|
types.put(typeKey,v);
|
||||||
sortedTypes.add(typeKey);
|
sortedTypes.add(typeKey);
|
||||||
|
|
||||||
|
|
@ -81,7 +81,7 @@ class InfiniteVehicles implements VehicleFleetManager{
|
||||||
@Override
|
@Override
|
||||||
public Collection<Vehicle> getAvailableVehicles(Vehicle withoutThisType) {
|
public Collection<Vehicle> getAvailableVehicles(Vehicle withoutThisType) {
|
||||||
Collection<Vehicle> vehicles = new ArrayList<Vehicle>();
|
Collection<Vehicle> vehicles = new ArrayList<Vehicle>();
|
||||||
VehicleTypeKey thisKey = new VehicleTypeKey(withoutThisType.getType().getTypeId(), withoutThisType.getStartLocationId(), withoutThisType.getEndLocationId(), withoutThisType.getEarliestDeparture(), withoutThisType.getLatestArrival());
|
VehicleTypeKey thisKey = new VehicleTypeKey(withoutThisType.getType().getTypeId(), withoutThisType.getStartLocationId(), withoutThisType.getEndLocationId(), withoutThisType.getEarliestDeparture(), withoutThisType.getLatestArrival(), withoutThisType.getSkills());
|
||||||
for(VehicleTypeKey key : types.keySet()){
|
for(VehicleTypeKey key : types.keySet()){
|
||||||
if(!key.equals(thisKey)){
|
if(!key.equals(thisKey)){
|
||||||
vehicles.add(types.get(key));
|
vehicles.add(types.get(key));
|
||||||
|
|
|
||||||
|
|
@ -122,11 +122,11 @@ class VehicleFleetManagerImpl implements VehicleFleetManager {
|
||||||
}
|
}
|
||||||
String typeId = v.getType().getTypeId();
|
String typeId = v.getType().getTypeId();
|
||||||
if(v.getType() instanceof PenaltyVehicleType){
|
if(v.getType() instanceof PenaltyVehicleType){
|
||||||
VehicleTypeKey typeKey = new VehicleTypeKey(typeId, v.getStartLocationId(), v.getEndLocationId(), v.getEarliestDeparture(), v.getLatestArrival());
|
VehicleTypeKey typeKey = new VehicleTypeKey(typeId, v.getStartLocationId(), v.getEndLocationId(), v.getEarliestDeparture(), v.getLatestArrival(), v.getSkills());
|
||||||
penaltyVehicles.put(typeKey, v);
|
penaltyVehicles.put(typeKey, v);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
VehicleTypeKey typeKey = new VehicleTypeKey(v.getType().getTypeId(), v.getStartLocationId(), v.getEndLocationId(), v.getEarliestDeparture(), v.getLatestArrival());
|
VehicleTypeKey typeKey = new VehicleTypeKey(v.getType().getTypeId(), v.getStartLocationId(), v.getEndLocationId(), v.getEarliestDeparture(), v.getLatestArrival(), v.getSkills());
|
||||||
if(!typeMapOfAvailableVehicles.containsKey(typeKey)){
|
if(!typeMapOfAvailableVehicles.containsKey(typeKey)){
|
||||||
typeMapOfAvailableVehicles.put(typeKey, new TypeContainer());
|
typeMapOfAvailableVehicles.put(typeKey, new TypeContainer());
|
||||||
}
|
}
|
||||||
|
|
@ -137,7 +137,7 @@ class VehicleFleetManagerImpl implements VehicleFleetManager {
|
||||||
private void removeVehicle(Vehicle v){
|
private void removeVehicle(Vehicle v){
|
||||||
//it might be better to introduce a class PenaltyVehicle
|
//it might be better to introduce a class PenaltyVehicle
|
||||||
if(!(v.getType() instanceof PenaltyVehicleType)){
|
if(!(v.getType() instanceof PenaltyVehicleType)){
|
||||||
VehicleTypeKey key = new VehicleTypeKey(v.getType().getTypeId(), v.getStartLocationId(), v.getEndLocationId(), v.getEarliestDeparture(), v.getLatestArrival());
|
VehicleTypeKey key = new VehicleTypeKey(v.getType().getTypeId(), v.getStartLocationId(), v.getEndLocationId(), v.getEarliestDeparture(), v.getLatestArrival(), v.getSkills());
|
||||||
if(typeMapOfAvailableVehicles.containsKey(key)){
|
if(typeMapOfAvailableVehicles.containsKey(key)){
|
||||||
typeMapOfAvailableVehicles.get(key).remove(v);
|
typeMapOfAvailableVehicles.get(key).remove(v);
|
||||||
}
|
}
|
||||||
|
|
@ -170,7 +170,7 @@ class VehicleFleetManagerImpl implements VehicleFleetManager {
|
||||||
@Override
|
@Override
|
||||||
public Collection<Vehicle> getAvailableVehicles(Vehicle withoutThisType) {
|
public Collection<Vehicle> getAvailableVehicles(Vehicle withoutThisType) {
|
||||||
List<Vehicle> vehicles = new ArrayList<Vehicle>();
|
List<Vehicle> vehicles = new ArrayList<Vehicle>();
|
||||||
VehicleTypeKey thisKey = new VehicleTypeKey(withoutThisType.getType().getTypeId(), withoutThisType.getStartLocationId(), withoutThisType.getEndLocationId(), withoutThisType.getEarliestDeparture(), withoutThisType.getLatestArrival());
|
VehicleTypeKey thisKey = new VehicleTypeKey(withoutThisType.getType().getTypeId(), withoutThisType.getStartLocationId(), withoutThisType.getEndLocationId(), withoutThisType.getEarliestDeparture(), withoutThisType.getLatestArrival(), withoutThisType.getSkills());
|
||||||
for(VehicleTypeKey key : typeMapOfAvailableVehicles.keySet()){
|
for(VehicleTypeKey key : typeMapOfAvailableVehicles.keySet()){
|
||||||
if(key.equals(thisKey)) continue;
|
if(key.equals(thisKey)) continue;
|
||||||
if(!typeMapOfAvailableVehicles.get(key).isEmpty()){
|
if(!typeMapOfAvailableVehicles.get(key).isEmpty()){
|
||||||
|
|
|
||||||
|
|
@ -245,6 +245,10 @@ public class VehicleImpl extends AbstractVehicle{
|
||||||
*/
|
*/
|
||||||
public static Builder newInstance(String vehicleId){ return new Builder(vehicleId); }
|
public static Builder newInstance(String vehicleId){ return new Builder(vehicleId); }
|
||||||
|
|
||||||
|
public Builder addSkills(Skills skills) {
|
||||||
|
this.skillBuilder.addAllSkills(skills.values());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -294,8 +298,8 @@ public class VehicleImpl extends AbstractVehicle{
|
||||||
startLocationCoord = builder.startLocationCoord;
|
startLocationCoord = builder.startLocationCoord;
|
||||||
endLocationId = builder.endLocationId;
|
endLocationId = builder.endLocationId;
|
||||||
endLocationCoord = builder.endLocationCoord;
|
endLocationCoord = builder.endLocationCoord;
|
||||||
setVehicleIdentifier(new VehicleTypeKey(type.getTypeId(),startLocationId,endLocationId,earliestDeparture,latestArrival));
|
|
||||||
skills = builder.skills;
|
skills = builder.skills;
|
||||||
|
setVehicleIdentifier(new VehicleTypeKey(type.getTypeId(),startLocationId,endLocationId,earliestDeparture,latestArrival,skills));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
package jsprit.core.problem.vehicle;
|
package jsprit.core.problem.vehicle;
|
||||||
|
|
||||||
import jsprit.core.problem.AbstractVehicle;
|
import jsprit.core.problem.AbstractVehicle;
|
||||||
|
import jsprit.core.problem.Skills;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Key to identify similar vehicles
|
* Key to identify similar vehicles
|
||||||
|
|
@ -35,66 +36,50 @@ public class VehicleTypeKey extends AbstractVehicle.AbstractTypeKey{
|
||||||
public final String endLocationId;
|
public final String endLocationId;
|
||||||
public final double earliestStart;
|
public final double earliestStart;
|
||||||
public final double latestEnd;
|
public final double latestEnd;
|
||||||
|
public final Skills skills;
|
||||||
|
|
||||||
public VehicleTypeKey(String typeId, String startLocationId, String endLocationId, double earliestStart, double latestEnd) {
|
public VehicleTypeKey(String typeId, String startLocationId, String endLocationId, double earliestStart, double latestEnd, Skills skills) {
|
||||||
super();
|
super();
|
||||||
this.type = typeId;
|
this.type = typeId;
|
||||||
this.startLocationId = startLocationId;
|
this.startLocationId = startLocationId;
|
||||||
this.endLocationId = endLocationId;
|
this.endLocationId = endLocationId;
|
||||||
this.earliestStart = earliestStart;
|
this.earliestStart = earliestStart;
|
||||||
this.latestEnd = latestEnd;
|
this.latestEnd = latestEnd;
|
||||||
|
this.skills = skills;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (!(o instanceof VehicleTypeKey)) return false;
|
||||||
|
|
||||||
|
VehicleTypeKey that = (VehicleTypeKey) o;
|
||||||
|
|
||||||
|
if (Double.compare(that.earliestStart, earliestStart) != 0) return false;
|
||||||
|
if (Double.compare(that.latestEnd, latestEnd) != 0) return false;
|
||||||
|
if (!endLocationId.equals(that.endLocationId)) return false;
|
||||||
|
if (!skills.equals(that.skills)) return false;
|
||||||
|
if (!startLocationId.equals(that.startLocationId)) return false;
|
||||||
|
if (!type.equals(that.type)) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
final int prime = 31;
|
int result;
|
||||||
int result = 1;
|
|
||||||
long temp;
|
long temp;
|
||||||
|
result = type.hashCode();
|
||||||
|
result = 31 * result + startLocationId.hashCode();
|
||||||
|
result = 31 * result + endLocationId.hashCode();
|
||||||
temp = Double.doubleToLongBits(earliestStart);
|
temp = Double.doubleToLongBits(earliestStart);
|
||||||
result = prime * result + (int) (temp ^ (temp >>> 32));
|
result = 31 * result + (int) (temp ^ (temp >>> 32));
|
||||||
result = prime * result
|
|
||||||
+ ((endLocationId == null) ? 0 : endLocationId.hashCode());
|
|
||||||
temp = Double.doubleToLongBits(latestEnd);
|
temp = Double.doubleToLongBits(latestEnd);
|
||||||
result = prime * result + (int) (temp ^ (temp >>> 32));
|
result = 31 * result + (int) (temp ^ (temp >>> 32));
|
||||||
result = prime * result
|
result = 31 * result + skills.hashCode();
|
||||||
+ ((startLocationId == null) ? 0 : startLocationId.hashCode());
|
|
||||||
result = prime * result + ((type == null) ? 0 : type.hashCode());
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (this == obj)
|
|
||||||
return true;
|
|
||||||
if (obj == null)
|
|
||||||
return false;
|
|
||||||
if (getClass() != obj.getClass())
|
|
||||||
return false;
|
|
||||||
VehicleTypeKey other = (VehicleTypeKey) obj;
|
|
||||||
if (Double.doubleToLongBits(earliestStart) != Double
|
|
||||||
.doubleToLongBits(other.earliestStart))
|
|
||||||
return false;
|
|
||||||
if (endLocationId == null) {
|
|
||||||
if (other.endLocationId != null)
|
|
||||||
return false;
|
|
||||||
} else if (!endLocationId.equals(other.endLocationId))
|
|
||||||
return false;
|
|
||||||
if (Double.doubleToLongBits(latestEnd) != Double
|
|
||||||
.doubleToLongBits(other.latestEnd))
|
|
||||||
return false;
|
|
||||||
if (startLocationId == null) {
|
|
||||||
if (other.startLocationId != null)
|
|
||||||
return false;
|
|
||||||
} else if (!startLocationId.equals(other.startLocationId))
|
|
||||||
return false;
|
|
||||||
if (type == null) {
|
|
||||||
if (other.type != null)
|
|
||||||
return false;
|
|
||||||
} else if (!type.equals(other.type))
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuilder stringBuilder = new StringBuilder();
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,10 @@ package jsprit.core.algorithm.recreate;
|
||||||
import jsprit.core.algorithm.ExampleActivityCostFunction;
|
import jsprit.core.algorithm.ExampleActivityCostFunction;
|
||||||
import jsprit.core.algorithm.state.StateManager;
|
import jsprit.core.algorithm.state.StateManager;
|
||||||
import jsprit.core.algorithm.state.UpdateVariableCosts;
|
import jsprit.core.algorithm.state.UpdateVariableCosts;
|
||||||
import jsprit.core.problem.*;
|
import jsprit.core.problem.AbstractActivity;
|
||||||
|
import jsprit.core.problem.AbstractVehicle;
|
||||||
|
import jsprit.core.problem.JobActivityFactory;
|
||||||
|
import jsprit.core.problem.VehicleRoutingProblem;
|
||||||
import jsprit.core.problem.constraint.ConstraintManager;
|
import jsprit.core.problem.constraint.ConstraintManager;
|
||||||
import jsprit.core.problem.cost.AbstractForwardVehicleRoutingTransportCosts;
|
import jsprit.core.problem.cost.AbstractForwardVehicleRoutingTransportCosts;
|
||||||
import jsprit.core.problem.cost.VehicleRoutingTransportCosts;
|
import jsprit.core.problem.cost.VehicleRoutingTransportCosts;
|
||||||
|
|
@ -33,6 +36,7 @@ import jsprit.core.problem.solution.route.activity.TimeWindow;
|
||||||
import jsprit.core.problem.vehicle.Vehicle;
|
import jsprit.core.problem.vehicle.Vehicle;
|
||||||
import jsprit.core.problem.vehicle.VehicleImpl;
|
import jsprit.core.problem.vehicle.VehicleImpl;
|
||||||
import jsprit.core.problem.vehicle.VehicleType;
|
import jsprit.core.problem.vehicle.VehicleType;
|
||||||
|
import jsprit.core.problem.vehicle.VehicleTypeImpl;
|
||||||
import jsprit.core.util.CostFactory;
|
import jsprit.core.util.CostFactory;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
@ -44,7 +48,6 @@ import java.util.List;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -76,11 +79,8 @@ public class TestCalculatesServiceInsertionOnRouteLevel {
|
||||||
|
|
||||||
|
|
||||||
costs = mock(VehicleRoutingTransportCosts.class);
|
costs = mock(VehicleRoutingTransportCosts.class);
|
||||||
vehicle = mock(AbstractVehicle.class);
|
|
||||||
VehicleType type = mock(VehicleType.class);
|
|
||||||
|
|
||||||
when(type.getCapacityDimensions()).thenReturn(Capacity.Builder.newInstance().addDimension(0, 1000).build());
|
|
||||||
|
|
||||||
|
VehicleType type = VehicleTypeImpl.Builder.newInstance("t").addCapacityDimension(0,1000).build();
|
||||||
vehicle = VehicleImpl.Builder.newInstance("v1").setType(type).setStartLocationId("0,0").setLatestArrival(100.).build();
|
vehicle = VehicleImpl.Builder.newInstance("v1").setType(type).setStartLocationId("0,0").setLatestArrival(100.).build();
|
||||||
newVehicle = VehicleImpl.Builder.newInstance("v2").setType(type).setStartLocationId("0,0").setLatestArrival(100.).build();
|
newVehicle = VehicleImpl.Builder.newInstance("v2").setType(type).setStartLocationId("0,0").setLatestArrival(100.).build();
|
||||||
driver = DriverImpl.noDriver();
|
driver = DriverImpl.noDriver();
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,98 @@
|
||||||
|
package jsprit.core.algorithm.state;
|
||||||
|
|
||||||
|
import jsprit.core.algorithm.VehicleRoutingAlgorithm;
|
||||||
|
import jsprit.core.algorithm.VehicleRoutingAlgorithmBuilder;
|
||||||
|
import jsprit.core.algorithm.recreate.NoSolutionFoundException;
|
||||||
|
import jsprit.core.problem.Skills;
|
||||||
|
import jsprit.core.problem.VehicleRoutingProblem;
|
||||||
|
import jsprit.core.problem.constraint.ConstraintManager;
|
||||||
|
import jsprit.core.problem.io.VrpXMLReader;
|
||||||
|
import jsprit.core.problem.job.Job;
|
||||||
|
import jsprit.core.problem.job.Service;
|
||||||
|
import jsprit.core.problem.solution.VehicleRoutingProblemSolution;
|
||||||
|
import jsprit.core.problem.solution.route.VehicleRoute;
|
||||||
|
import jsprit.core.problem.vehicle.Vehicle;
|
||||||
|
import jsprit.core.problem.vehicle.VehicleImpl;
|
||||||
|
import jsprit.core.problem.vehicle.VehicleType;
|
||||||
|
import jsprit.core.util.Solutions;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* to test skills with penalty vehicles
|
||||||
|
*/
|
||||||
|
public class SolomonSkills_IT {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void itShouldMakeCorrectAssignmentAccordingToSkills(){
|
||||||
|
VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
|
||||||
|
new VrpXMLReader(vrpBuilder).read("src/test/resources/solomon_c101.xml");
|
||||||
|
VehicleRoutingProblem vrp = vrpBuilder.build();
|
||||||
|
|
||||||
|
//y >= 50 skill1 otherwise skill2
|
||||||
|
//two vehicles: v1 - skill1 #5; v2 - skill2 #6
|
||||||
|
Vehicle solomonVehicle = vrp.getVehicles().iterator().next();
|
||||||
|
VehicleType newType = solomonVehicle.getType();
|
||||||
|
VehicleRoutingProblem.Builder skillProblemBuilder = VehicleRoutingProblem.Builder.newInstance();
|
||||||
|
for(int i=0;i<6;i++) {
|
||||||
|
VehicleImpl skill1Vehicle = VehicleImpl.Builder.newInstance("skill1_vehicle_"+i).addSkill("skill1")
|
||||||
|
.setStartLocationCoordinate(solomonVehicle.getStartLocationCoordinate()).setStartLocationId(solomonVehicle.getStartLocationId())
|
||||||
|
.setEarliestStart(solomonVehicle.getEarliestDeparture())
|
||||||
|
.setType(newType).build();
|
||||||
|
VehicleImpl skill2Vehicle = VehicleImpl.Builder.newInstance("skill2_vehicle_"+i).addSkill("skill2")
|
||||||
|
.setStartLocationCoordinate(solomonVehicle.getStartLocationCoordinate()).setStartLocationId(solomonVehicle.getStartLocationId())
|
||||||
|
.setEarliestStart(solomonVehicle.getEarliestDeparture())
|
||||||
|
.setType(newType).build();
|
||||||
|
skillProblemBuilder.addVehicle(skill1Vehicle).addVehicle(skill2Vehicle);
|
||||||
|
}
|
||||||
|
for(Job job : vrp.getJobs().values()){
|
||||||
|
Service service = (Service) job;
|
||||||
|
Service.Builder skillServiceBuilder = Service.Builder.newInstance(service.getId()).setServiceTime(service.getServiceDuration())
|
||||||
|
.setCoord(service.getCoord()).setLocationId(service.getLocationId()).setTimeWindow(service.getTimeWindow())
|
||||||
|
.addSizeDimension(0,service.getSize().get(0));
|
||||||
|
if(service.getCoord().getY()<50) skillServiceBuilder.addSkill("skill2");
|
||||||
|
else skillServiceBuilder.addSkill("skill1");
|
||||||
|
skillProblemBuilder.addJob(skillServiceBuilder.build());
|
||||||
|
}
|
||||||
|
skillProblemBuilder.addPenaltyVehicles(3.);
|
||||||
|
skillProblemBuilder.setFleetSize(VehicleRoutingProblem.FleetSize.FINITE);
|
||||||
|
VehicleRoutingProblem skillProblem = skillProblemBuilder.build();
|
||||||
|
|
||||||
|
VehicleRoutingAlgorithmBuilder vraBuilder = new VehicleRoutingAlgorithmBuilder(skillProblem,"src/test/resources/algorithmConfig.xml");
|
||||||
|
vraBuilder.addCoreConstraints();
|
||||||
|
vraBuilder.addDefaultCostCalculators();
|
||||||
|
|
||||||
|
StateManager stateManager = new StateManager(skillProblem);
|
||||||
|
stateManager.updateSkillStates();
|
||||||
|
|
||||||
|
ConstraintManager constraintManager = new ConstraintManager(skillProblem,stateManager);
|
||||||
|
constraintManager.addSkillsConstraint();
|
||||||
|
|
||||||
|
VehicleRoutingAlgorithm vra = vraBuilder.build();
|
||||||
|
vra.setNuOfIterations(500);
|
||||||
|
|
||||||
|
try {
|
||||||
|
Collection<VehicleRoutingProblemSolution> solutions = vra.searchSolutions();
|
||||||
|
VehicleRoutingProblemSolution solution = Solutions.bestOf(solutions);
|
||||||
|
assertEquals(828.94, solution.getCost(), 0.01);
|
||||||
|
for(VehicleRoute route : solution.getRoutes()){
|
||||||
|
Skills vehicleSkill = route.getVehicle().getSkills();
|
||||||
|
for(Job job : route.getTourActivities().getJobs()){
|
||||||
|
for(String skill : job.getRequiredSkills().values()){
|
||||||
|
if(!vehicleSkill.containsSkill(skill)){
|
||||||
|
assertFalse(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertTrue(true);
|
||||||
|
}
|
||||||
|
catch (NoSolutionFoundException e){
|
||||||
|
System.out.println(e.toString());
|
||||||
|
assertFalse(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -94,8 +94,8 @@ public class VehicleRoutingProblemTest {
|
||||||
public void whenBuildingWithFourVehiclesAndTwoTypes_vrpShouldContainTheCorrectNuOfTypes(){
|
public void whenBuildingWithFourVehiclesAndTwoTypes_vrpShouldContainTheCorrectNuOfTypes(){
|
||||||
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
|
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
|
||||||
|
|
||||||
VehicleTypeImpl type1 = mock(VehicleTypeImpl.class);
|
VehicleTypeImpl type1 = VehicleTypeImpl.Builder.newInstance("type1").build();
|
||||||
VehicleTypeImpl type2 = mock(VehicleTypeImpl.class);
|
VehicleTypeImpl type2 = VehicleTypeImpl.Builder.newInstance("type2").build();
|
||||||
|
|
||||||
VehicleImpl v1 = VehicleImpl.Builder.newInstance("v1").setStartLocationId("yo").setType(type1).build();
|
VehicleImpl v1 = VehicleImpl.Builder.newInstance("v1").setStartLocationId("yo").setType(type1).build();
|
||||||
VehicleImpl v2 = VehicleImpl.Builder.newInstance("v2").setStartLocationId("yo").setType(type1).build();
|
VehicleImpl v2 = VehicleImpl.Builder.newInstance("v2").setStartLocationId("yo").setType(type1).build();
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@ import org.junit.Test;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* unit tests to test vehicle dependent time-windows
|
* unit tests to test vehicle dependent time-windows
|
||||||
|
|
@ -52,22 +51,23 @@ public class VehicleDependentTimeWindowTest {
|
||||||
routingCosts = CostFactory.createEuclideanCosts();
|
routingCosts = CostFactory.createEuclideanCosts();
|
||||||
vrpBuilder.setRoutingCost(routingCosts);
|
vrpBuilder.setRoutingCost(routingCosts);
|
||||||
|
|
||||||
vehicle = VehicleImpl.Builder.newInstance("v").setType(mock(VehicleType.class)).setStartLocationId("0,0")
|
VehicleType type = VehicleTypeImpl.Builder.newInstance("type").build();
|
||||||
|
vehicle = VehicleImpl.Builder.newInstance("v").setType(type).setStartLocationId("0,0")
|
||||||
.setEarliestStart(0.).setLatestArrival(100.).build();
|
.setEarliestStart(0.).setLatestArrival(100.).build();
|
||||||
|
|
||||||
v2 = VehicleImpl.Builder.newInstance("v2").setType(mock(VehicleType.class)).setStartLocationId("0,0")
|
v2 = VehicleImpl.Builder.newInstance("v2").setType(type).setStartLocationId("0,0")
|
||||||
.setEarliestStart(0.).setLatestArrival(60.).build();
|
.setEarliestStart(0.).setLatestArrival(60.).build();
|
||||||
|
|
||||||
v3 = VehicleImpl.Builder.newInstance("v3").setType(mock(VehicleType.class)).setStartLocationId("0,0")
|
v3 = VehicleImpl.Builder.newInstance("v3").setType(type).setStartLocationId("0,0")
|
||||||
.setEarliestStart(0.).setLatestArrival(50.).build();
|
.setEarliestStart(0.).setLatestArrival(50.).build();
|
||||||
|
|
||||||
v4 = VehicleImpl.Builder.newInstance("v4").setType(mock(VehicleType.class)).setStartLocationId("0,0")
|
v4 = VehicleImpl.Builder.newInstance("v4").setType(type).setStartLocationId("0,0")
|
||||||
.setEarliestStart(0.).setLatestArrival(10.).build();
|
.setEarliestStart(0.).setLatestArrival(10.).build();
|
||||||
|
|
||||||
v5 = VehicleImpl.Builder.newInstance("v5").setType(mock(VehicleType.class)).setStartLocationId("0,0")
|
v5 = VehicleImpl.Builder.newInstance("v5").setType(type).setStartLocationId("0,0")
|
||||||
.setEarliestStart(60.).setLatestArrival(100.).build();
|
.setEarliestStart(60.).setLatestArrival(100.).build();
|
||||||
|
|
||||||
v6 = VehicleImpl.Builder.newInstance("v6").setType(mock(VehicleType.class)).setStartLocationId("0,0")
|
v6 = VehicleImpl.Builder.newInstance("v6").setType(type).setStartLocationId("0,0")
|
||||||
.setEndLocationId("40,0").setEarliestStart(0.).setLatestArrival(40.).build();
|
.setEndLocationId("40,0").setEarliestStart(0.).setLatestArrival(40.).build();
|
||||||
|
|
||||||
vrpBuilder.addVehicle(vehicle).addVehicle(v2).addVehicle(v3).addVehicle(v4).addVehicle(v5).addVehicle(v6);
|
vrpBuilder.addVehicle(vehicle).addVehicle(v2).addVehicle(v3).addVehicle(v4).addVehicle(v5).addVehicle(v6);
|
||||||
|
|
|
||||||
1441
jsprit-core/src/test/resources/solomon_c101.xml
Normal file
1441
jsprit-core/src/test/resources/solomon_c101.xml
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,87 @@
|
||||||
|
package jsprit.examples;
|
||||||
|
|
||||||
|
|
||||||
|
import jsprit.analysis.toolbox.Plotter;
|
||||||
|
import jsprit.analysis.toolbox.SolutionPrinter;
|
||||||
|
import jsprit.core.algorithm.VehicleRoutingAlgorithm;
|
||||||
|
import jsprit.core.algorithm.VehicleRoutingAlgorithmBuilder;
|
||||||
|
import jsprit.core.algorithm.state.StateManager;
|
||||||
|
import jsprit.core.problem.VehicleRoutingProblem;
|
||||||
|
import jsprit.core.problem.constraint.ConstraintManager;
|
||||||
|
import jsprit.core.problem.job.Job;
|
||||||
|
import jsprit.core.problem.job.Service;
|
||||||
|
import jsprit.core.problem.solution.VehicleRoutingProblemSolution;
|
||||||
|
import jsprit.core.problem.vehicle.Vehicle;
|
||||||
|
import jsprit.core.problem.vehicle.VehicleImpl;
|
||||||
|
import jsprit.core.problem.vehicle.VehicleType;
|
||||||
|
import jsprit.core.util.Solutions;
|
||||||
|
import jsprit.instance.reader.SolomonReader;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
public class SolomonWithSkillsExample {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
|
||||||
|
new SolomonReader(vrpBuilder).read("input/C101_solomon.txt");
|
||||||
|
VehicleRoutingProblem vrp = vrpBuilder.build();
|
||||||
|
|
||||||
|
//y >= 50 skill1 otherwise skill2
|
||||||
|
//two vehicles: v1 - skill1 #5; v2 - skill2 #6
|
||||||
|
Vehicle solomonVehicle = vrp.getVehicles().iterator().next();
|
||||||
|
VehicleType newType = solomonVehicle.getType();
|
||||||
|
VehicleRoutingProblem.Builder skillProblemBuilder = VehicleRoutingProblem.Builder.newInstance();
|
||||||
|
for(int i=0;i<5;i++) {
|
||||||
|
VehicleImpl skill1Vehicle = VehicleImpl.Builder.newInstance("skill1_vehicle_"+i).addSkill("skill1")
|
||||||
|
.setStartLocationCoordinate(solomonVehicle.getStartLocationCoordinate()).setStartLocationId(solomonVehicle.getStartLocationId())
|
||||||
|
.setEarliestStart(solomonVehicle.getEarliestDeparture())
|
||||||
|
.setType(newType).build();
|
||||||
|
VehicleImpl skill2Vehicle = VehicleImpl.Builder.newInstance("skill2_vehicle_"+i).addSkill("skill2")
|
||||||
|
.setStartLocationCoordinate(solomonVehicle.getStartLocationCoordinate()).setStartLocationId(solomonVehicle.getStartLocationId())
|
||||||
|
.setEarliestStart(solomonVehicle.getEarliestDeparture())
|
||||||
|
.setType(newType).build();
|
||||||
|
skillProblemBuilder.addVehicle(skill1Vehicle).addVehicle(skill2Vehicle);
|
||||||
|
}
|
||||||
|
for(Job job : vrp.getJobs().values()){
|
||||||
|
Service service = (Service) job;
|
||||||
|
Service.Builder skillServiceBuilder;
|
||||||
|
if(service.getCoord().getY()<50.){
|
||||||
|
skillServiceBuilder = Service.Builder.newInstance(service.getId()+"_skill2").setServiceTime(service.getServiceDuration())
|
||||||
|
.setCoord(service.getCoord()).setLocationId(service.getLocationId()).setTimeWindow(service.getTimeWindow())
|
||||||
|
.addSizeDimension(0,service.getSize().get(0));
|
||||||
|
skillServiceBuilder.addSkill("skill2");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
skillServiceBuilder = Service.Builder.newInstance(service.getId()+"_skill1").setServiceTime(service.getServiceDuration())
|
||||||
|
.setCoord(service.getCoord()).setLocationId(service.getLocationId()).setTimeWindow(service.getTimeWindow())
|
||||||
|
.addSizeDimension(0,service.getSize().get(0));
|
||||||
|
skillServiceBuilder.addSkill("skill1");
|
||||||
|
}
|
||||||
|
skillProblemBuilder.addJob(skillServiceBuilder.build());
|
||||||
|
}
|
||||||
|
skillProblemBuilder.addPenaltyVehicles(3.,100.);
|
||||||
|
skillProblemBuilder.setFleetSize(VehicleRoutingProblem.FleetSize.FINITE);
|
||||||
|
VehicleRoutingProblem skillProblem = skillProblemBuilder.build();
|
||||||
|
|
||||||
|
VehicleRoutingAlgorithmBuilder vraBuilder = new VehicleRoutingAlgorithmBuilder(skillProblem,"input/algorithmConfig_solomon.xml");
|
||||||
|
vraBuilder.addCoreConstraints();
|
||||||
|
vraBuilder.addDefaultCostCalculators();
|
||||||
|
|
||||||
|
StateManager stateManager = new StateManager(skillProblem);
|
||||||
|
stateManager.updateSkillStates();
|
||||||
|
|
||||||
|
ConstraintManager constraintManager = new ConstraintManager(skillProblem,stateManager);
|
||||||
|
constraintManager.addSkillsConstraint();
|
||||||
|
|
||||||
|
VehicleRoutingAlgorithm vra = vraBuilder.build();
|
||||||
|
// vra.setNuOfIterations(500);
|
||||||
|
|
||||||
|
|
||||||
|
Collection<VehicleRoutingProblemSolution> solutions = vra.searchSolutions();
|
||||||
|
VehicleRoutingProblemSolution solution = Solutions.bestOf(solutions);
|
||||||
|
|
||||||
|
SolutionPrinter.print(skillProblem, solution, SolutionPrinter.Print.VERBOSE);
|
||||||
|
|
||||||
|
new Plotter(skillProblem,solution).plot("output/skill_solution","solomon_with_skills");
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue