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

merged skills

This commit is contained in:
oblonski 2014-07-29 11:35:40 +02:00
parent 9c4bd498c4
commit c04d3acd51
23 changed files with 279 additions and 343 deletions

View file

@ -359,11 +359,11 @@ public class VehicleRoutingAlgorithms {
private VehicleRoutingAlgorithms(){}
/**
* Creates a {@link VehicleRoutingAlgorithm} from a AlgorithConfig based on the input vrp.
* Creates a {@link jsprit.core.algorithm.VehicleRoutingAlgorithm} from a AlgorithConfig based on the input vrp.
*
* @param vrp
* @param algorithmConfig
* @return {@link VehicleRoutingAlgorithm}
* @param vrp the routing problem
* @param algorithmConfig the algorithm config
* @return {@link jsprit.core.algorithm.VehicleRoutingAlgorithm}
*/
public static VehicleRoutingAlgorithm createAlgorithm(final VehicleRoutingProblem vrp, final AlgorithmConfig algorithmConfig){
return createAlgo(vrp,algorithmConfig.getXMLConfiguration(),0, null);
@ -372,9 +372,9 @@ public class VehicleRoutingAlgorithms {
/**
* Read and creates a {@link VehicleRoutingAlgorithm} from an url.
*
* @param vrp
* @param configURL
* @return {@link VehicleRoutingProblem}
* @param vrp the routing problem
* @param configURL config url
* @return {@link jsprit.core.algorithm.VehicleRoutingAlgorithm}
*/
public static VehicleRoutingAlgorithm readAndCreateAlgorithm(final VehicleRoutingProblem vrp, final URL configURL){
AlgorithmConfig algorithmConfig = new AlgorithmConfig();
@ -384,11 +384,11 @@ public class VehicleRoutingAlgorithms {
}
/**
* Read and creates {@link VehicleRoutingAlgorithm} from config-file.
* Read and creates {@link jsprit.core.problem.VehicleRoutingProblem} from config-file.
*
* @param vrp
* @param configFileName
* @return
* @param vrp the routing problem
* @param configFileName the config filename (and location)
* @return {@link jsprit.core.algorithm.VehicleRoutingAlgorithm}
*/
public static VehicleRoutingAlgorithm readAndCreateAlgorithm(final VehicleRoutingProblem vrp, final String configFileName){
AlgorithmConfig algorithmConfig = new AlgorithmConfig();
@ -461,7 +461,7 @@ public class VehicleRoutingAlgorithms {
}
stateManager.updateLoadStates();
stateManager.updateTimeWindowStates();
stateManager.updateSkillStates();
// stateManager.updateSkillStates();
stateManager.addStateUpdater(new UpdateEndLocationIfRouteIsOpen());
stateManager.addStateUpdater(new OpenRouteStateVerifier());
stateManager.addStateUpdater(new UpdateActivityTimes(vrp.getTransportCosts()));
@ -481,9 +481,6 @@ public class VehicleRoutingAlgorithms {
public static VehicleRoutingAlgorithm readAndCreateAlgorithm(final VehicleRoutingProblem vrp, AlgorithmConfig config,
int nuOfThreads, SolutionCostCalculator solutionCostCalculator, final StateManager stateManager, ConstraintManager constraintManager, boolean addDefaultCostCalculators) {
// AlgorithmConfig algorithmConfig = new AlgorithmConfig();
// AlgorithmConfigXmlReader xmlReader = new AlgorithmConfigXmlReader(algorithmConfig);
// xmlReader.read(config);
return readAndCreateAlgorithm(vrp, config.getXMLConfiguration(),nuOfThreads, solutionCostCalculator, stateManager, constraintManager, addDefaultCostCalculators);
}
@ -881,49 +878,12 @@ public class VehicleRoutingAlgorithms {
RuinAndRecreateModule rrModule = new RuinAndRecreateModule("ruin_and_recreate", final_insertion, ruin);
return rrModule;
}
if(moduleName.equals("gendreau")){
throw new UnsupportedOperationException("gendreau is not supported yet");
// int iterations = moduleConfig.getInt("iterations");
// double share = moduleConfig.getDouble("share");
// String ruinName = moduleConfig.getString("ruin[@name]");
// if(ruinName == null) throw new IllegalStateException("gendreau.ruin[@name] is missing. set it to \"radialRuin\" or \"randomRuin\"");
// String ruinId = moduleConfig.getString("ruin[@id]");
// if(ruinId == null) ruinId = "noId";
// ModKey ruinKey = makeKey(ruinName,ruinId);
// RuinStrategyKey stratKey = new RuinStrategyKey(ruinKey);
// RuinStrategy ruin = definedClasses.get(stratKey);
// if(ruin == null){
// ruin = new RadialRuinStrategyFactory(0.3, new AvgJobDistance(vrp.getTransportCosts())).createStrategy(vrp);
// definedClasses.put(stratKey, ruin);
// }
//
// String insertionName = moduleConfig.getString("insertion[@name]");
// if(insertionName == null) throw new IllegalStateException("gendreau.insertion[@name] is missing. set it to \"regretInsertion\" or \"bestInsertion\"");
// String insertionId = moduleConfig.getString("insertion[@id]");
// if(insertionId == null) insertionId = "noId";
// ModKey insertionKey = makeKey(insertionName,insertionId);
// InsertionStrategyKey insertionStrategyKey = new InsertionStrategyKey(insertionKey);
// InsertionStrategy insertion = definedClasses.get(insertionStrategyKey);
// if(insertion == null){
// List<HierarchicalConfiguration> insertionConfigs = moduleConfig.configurationsAt("insertion");
// if(insertionConfigs.size() != 1) throw new IllegalStateException("this should be 1");
// List<PrioritizedVRAListener> prioListeners = new ArrayList<PrioritizedVRAListener>();
// insertion = createInsertionStrategy(insertionConfigs.get(0), vrp, vehicleFleetManager, routeStates, prioListeners, executorService, nuOfThreads, constraintManager);
// algorithmListeners.addAll(prioListeners);
// }
// Gendreau gendreau = new Gendreau(vrp, ruin, insertion, vehicleFleetManager);
// gendreau.setShareOfJobsToRuin(share);
// gendreau.setNuOfIterations(iterations);
// definedClasses.put(strategyModuleKey, gendreau);
// return gendreau;
}
throw new NullPointerException("no module found with moduleName=" + moduleName +
"\n\tcheck config whether the correct names are used" +
"\n\tcurrently there are following modules available: " +
"\n\tbestInsertion" +
"\n\trandomRuin" +
"\n\tradialRuin" +
"\n\tgendreauPostOpt");
"\n\tradialRuin");
}
private static RuinStrategy getRadialRuin(final VehicleRoutingProblem vrp, final StateManager routeStates, TypedMap definedClasses, ModKey modKey, double shareToRuin, JobDistance jobDistance) {

View file

@ -43,5 +43,5 @@ public class InternalStates {
public final static StateId PAST_MAXLOAD = new StateFactory.StateIdImpl("past_max_load", 9);
public static final StateId SKILLS = new StateFactory.StateIdImpl("skills", 10);
}

View file

@ -9,7 +9,7 @@ import java.util.List;
class StateFactory {
final static List<String> reservedIds = Arrays.asList("max_load", "load", "costs", "load_at_beginning", "load_at_end", "duration", "latest_operation_start_time", "earliest_operation_start_time"
, "future_max_load", "past_max_load");
, "future_max_load", "past_max_load", "skills");
static StateId createId(String name){

View file

@ -22,7 +22,6 @@ import jsprit.core.algorithm.ruin.listener.RuinListener;
import jsprit.core.algorithm.ruin.listener.RuinListeners;
import jsprit.core.problem.Capacity;
import jsprit.core.problem.VehicleRoutingProblem;
import jsprit.core.problem.cost.VehicleRoutingTransportCosts;
import jsprit.core.problem.job.Job;
import jsprit.core.problem.solution.VehicleRoutingProblemSolution;
import jsprit.core.problem.solution.route.ReverseRouteActivityVisitor;
@ -93,18 +92,16 @@ public class StateManager implements RouteAndActivityStateGetter, IterationStart
private Map<StateId,Object> defaultRouteStates_ = new HashMap<StateId,Object>();
private Map<StateId,Object> defaultActivityStates_ = new HashMap<StateId,Object>();
private VehicleRoutingTransportCosts routingCosts;
private boolean updateLoad = false;
private boolean updateTWs = false;
private int stateIndexCounter = 10;
private int stateIndexCounter = 21;
private Map<String,StateId> createdStateIds = new HashMap<String, StateId>();
private int initialNuStates = 20;
private int initialNuStates = 30;
private int nuActivities;
@ -176,7 +173,6 @@ public class StateManager implements RouteAndActivityStateGetter, IterationStart
* @param vehicleRoutingProblem the corresponding VehicleRoutingProblem
*/
public StateManager(VehicleRoutingProblem vehicleRoutingProblem){
this.routingCosts = vehicleRoutingProblem.getTransportCosts();
this.vrp = vehicleRoutingProblem;
nuActivities = Math.max(10, vrp.getNuActivities() + 1);
nuVehicleTypeKeys = Math.max(3, getNuVehicleTypes(vrp) + 2);
@ -706,5 +702,12 @@ public class StateManager implements RouteAndActivityStateGetter, IterationStart
return updateTWs;
}
/**
* Updates skill states.
*/
public void updateSkillStates() {
addActivityVisitor(new UpdateSkills(this));
}
}

View file

@ -4,10 +4,9 @@ import jsprit.core.problem.Skills;
import jsprit.core.problem.solution.route.VehicleRoute;
import jsprit.core.problem.solution.route.activity.ActivityVisitor;
import jsprit.core.problem.solution.route.activity.TourActivity;
import jsprit.core.problem.solution.route.state.StateFactory;
/**
* Created by schroeder on 01.07.14.
* Update to update required skills on route
*/
public class UpdateSkills implements StateUpdater, ActivityVisitor{
@ -38,6 +37,6 @@ public class UpdateSkills implements StateUpdater, ActivityVisitor{
@Override
public void finish() {
Skills skills = skillBuilder.build();
statesManager.putTypedInternalRouteState(route, StateFactory.SKILLS, Skills.class, skills);
statesManager.putTypedInternalRouteState(route, InternalStates.SKILLS, skills);
}
}

View file

@ -6,7 +6,7 @@ import java.util.HashSet;
import java.util.Set;
/**
* Created by schroeder on 01.07.14.
* Skill container managing skills
*/
public class Skills {
@ -15,7 +15,7 @@ public class Skills {
/**
* Returns new instance of skill-builder.
*
* @return
* @return builder
*/
public static Builder newInstance(){
return new Builder();
@ -26,19 +26,30 @@ public class Skills {
/**
* Adds skill. Skill is transformed into lowerCase.
*
* @param skill
* @return
* @param skill skill to be added
* @return builder
*/
public Builder addSkill(String skill){
skills.add(skill.toLowerCase());
return this;
}
/**
* Adds a collection of skills.
*
* @param skills collection of skills to be added
* @return builder
*/
public Builder addAllSkills(Collection<String> skills){
for(String skill : skills) this.skills.add(skill);
return this;
}
/**
* Builds the skill container and returns it.
*
* @return skills
*/
public Skills build(){
return new Skills(this);
}
@ -54,7 +65,7 @@ public class Skills {
/**
* Returns an unmodifiable set of skills. All skills are inLowerCase.
*
* @return
* @return set of skills in this containter
*/
public Set<String> values(){
return Collections.unmodifiableSet(skills);
@ -63,8 +74,8 @@ public class Skills {
/**
* Not case sensitive.
*
* @param skill
* @return
* @param skill which is checked whether it is in skill container or not
* @return true if skill is included, false otherwise
*/
public boolean containsSkill(String skill){
return skills.contains(skill.toLowerCase());

View file

@ -1,9 +1,9 @@
package jsprit.core.problem.constraint;
import jsprit.core.algorithm.state.InternalStates;
import jsprit.core.problem.Skills;
import jsprit.core.problem.misc.JobInsertionContext;
import jsprit.core.problem.solution.route.state.RouteAndActivityStateGetter;
import jsprit.core.problem.solution.route.state.StateFactory;
/**
* SkillConstraint that ensures that only vehicles with according skills can serve route and job to be inserted.
@ -11,6 +11,8 @@ import jsprit.core.problem.solution.route.state.StateFactory;
*/
public class HardSkillConstraint implements HardRouteStateLevelConstraint{
private static final Skills defaultSkills = Skills.Builder.newInstance().build();
private RouteAndActivityStateGetter states;
public HardSkillConstraint(RouteAndActivityStateGetter states) {
@ -24,7 +26,8 @@ public class HardSkillConstraint implements HardRouteStateLevelConstraint{
return false;
}
}
Skills requiredSkillsForRoute = states.getRouteState(insertionContext.getRoute(), StateFactory.SKILLS, Skills.class);
Skills requiredSkillsForRoute = states.getRouteState(insertionContext.getRoute(), InternalStates.SKILLS, Skills.class);
if(requiredSkillsForRoute == null) requiredSkillsForRoute = defaultSkills;
for(String skill : requiredSkillsForRoute.values()){
if(!insertionContext.getNewVehicle().getSkills().containsSkill(skill)){
return false;

View file

@ -30,24 +30,13 @@ public class Delivery extends Service{
/**
* Returns a new instance of builder that builds a delivery.
*
* @param id
* @param id the id of the delivery
* @return the builder
*/
public static Builder newInstance(String id){
return new Builder(id);
}
/**
* Constructs the builder
*
* @param id
* @param size
* @throws IllegalArgumentException if size < 0 or id is null
*/
Builder(String id, int size) {
super(id, size);
}
Builder(String id) {
super(id);
}
@ -56,7 +45,7 @@ public class Delivery extends Service{
* Builds Delivery.
*
* @return delivery
* @throw IllegalStateException if neither locationId nor coord is set
* @throws IllegalStateException if neither locationId nor coord is set
*/
public Delivery build(){
if(locationId == null) {
@ -65,16 +54,12 @@ public class Delivery extends Service{
}
this.setType("delivery");
super.capacity = super.capacityBuilder.build();
super.skills = super.skillBuilder.build();
return new Delivery(this);
}
}
/**
* Constructs Delivery.
*
* @param builder
*/
Delivery(Builder builder) {
super(builder);

View file

@ -20,6 +20,7 @@ package jsprit.core.problem.job;
import jsprit.core.problem.Capacity;
import jsprit.core.problem.HasId;
import jsprit.core.problem.HasIndex;
import jsprit.core.problem.Skills;
/**
* Basic interface for all jobs.
@ -42,5 +43,6 @@ public interface Job extends HasId, HasIndex {
* @return Capacity
*/
public Capacity getSize();
Skills getRequiredSkills();
}

View file

@ -30,24 +30,13 @@ public class Pickup extends Service {
/**
* Returns a new instance of builder that builds a pickup.
*
* @param id
* @param id the id of the pickup
* @return the builder
*/
public static Builder newInstance(String id){
return new Builder(id);
}
/**
* Constructs the builder.
*
* @param id
* @param size
* @throws IllegalArgumentException if size < 0 or id is null
*/
Builder(String id, int size) {
super(id, size);
}
Builder(String id) {
super(id);
}
@ -58,7 +47,7 @@ public class Pickup extends Service {
*<p>Pickup type is "pickup"
*
* @return pickup
* @throw IllegalStateException if neither locationId nor coordinate has been set
* @throws IllegalStateException if neither locationId nor coordinate has been set
*/
public Pickup build(){
if(locationId == null) {
@ -67,16 +56,12 @@ public class Pickup extends Service {
}
this.setType("pickup");
super.capacity = super.capacityBuilder.build();
super.skills = super.skillBuilder.build();
return new Pickup(this);
}
}
/**
* Constructs the Pickup
*
* @param builder
*/
Pickup(Builder builder) {
super(builder);
}

View file

@ -18,6 +18,7 @@ package jsprit.core.problem.job;
import jsprit.core.problem.AbstractJob;
import jsprit.core.problem.Capacity;
import jsprit.core.problem.Skills;
import jsprit.core.problem.solution.route.activity.TimeWindow;
import jsprit.core.util.Coordinate;
@ -45,7 +46,7 @@ public class Service extends AbstractJob {
/**
* Returns a new instance of builder that builds a service.
*
* @param id
* @param id the id of the service
* @return the builder
*/
public static Builder newInstance(String id){
@ -67,20 +68,11 @@ public class Service extends AbstractJob {
protected Capacity.Builder capacityBuilder = Capacity.Builder.newInstance();
protected Capacity capacity;
/**
* Constructs the builder.
*
* @param id
* @param size
* @throws IllegalArgumentException if size < 0 or id is null
*/
Builder(String id, int size) {
if(size < 0) throw new IllegalArgumentException("size must be greater than or equal to zero");
if(id == null) throw new IllegalArgumentException("id must not be null");
this.id = id;
}
protected Skills.Builder skillBuilder = Skills.Builder.newInstance();
protected Skills skills;
Builder(String id){
this.id = id;
}
@ -90,7 +82,7 @@ public class Service extends AbstractJob {
*
* <p>Currently there are {@link Service}, {@link Pickup} and {@link Delivery}.
*
* @param name
* @param name the name of service
* @return the builder
*/
protected Builder setType(String name){
@ -101,7 +93,7 @@ public class Service extends AbstractJob {
/**
* Sets the location-id of this service.
*
* @param locationId
* @param locationId the location id of the service
* @return builder
*/
public Builder setLocationId(String locationId){
@ -112,7 +104,7 @@ public class Service extends AbstractJob {
/**
* Sets the coordinate of this service.
*
* @param coord
* @param coord the coordinate of service
* @return builder
*/
public Builder setCoord(Coordinate coord){
@ -126,7 +118,7 @@ public class Service extends AbstractJob {
* <p>It is understood as time that a service or its implied activity takes at the service-location, for instance
* to unload goods.
*
* @param serviceTime
* @param serviceTime the service time / duration of service to be set
* @return builder
* @throws IllegalArgumentException if serviceTime < 0
*/
@ -139,8 +131,8 @@ public class Service extends AbstractJob {
/**
* Adds capacity dimension.
*
* @param dimensionIndex
* @param dimensionValue
* @param dimensionIndex the dimension index of the capacity value
* @param dimensionValue the capacity value
* @return the builder
* @throws IllegalArgumentException if dimensionValue < 0
*/
@ -155,9 +147,9 @@ public class Service extends AbstractJob {
*
* <p>The time-window indicates the time period a service/activity/operation is allowed to start.
*
* @param tw
* @param tw the time-window to be set
* @return builder
* @throw IllegalArgumentException if timeWindow is null
* @throws IllegalArgumentException if timeWindow is null
*/
public Builder setTimeWindow(TimeWindow tw){
if(tw == null) throw new IllegalArgumentException("time-window arg must not be null");
@ -178,10 +170,15 @@ public class Service extends AbstractJob {
}
this.setType("service");
capacity = capacityBuilder.build();
skills = skillBuilder.build();
return new Service(this);
}
}
public Builder addSkill(String skill) {
skillBuilder.addSkill(skill);
return this;
}
}
private final String id;
@ -198,6 +195,8 @@ public class Service extends AbstractJob {
private final Capacity size;
private final Skills skills;
Service(Builder builder){
id = builder.id;
locationId = builder.locationId;
@ -206,6 +205,7 @@ public class Service extends AbstractJob {
timeWindow = builder.timeWindow;
type = builder.type;
size = builder.capacity;
skills = builder.skills;
}
@Override
@ -300,5 +300,10 @@ public class Service extends AbstractJob {
public Capacity getSize() {
return size;
}
@Override
public Skills getRequiredSkills() {
return skills;
}
}

View file

@ -20,6 +20,7 @@ package jsprit.core.problem.job;
import jsprit.core.problem.AbstractJob;
import jsprit.core.problem.Capacity;
import jsprit.core.problem.Skills;
import jsprit.core.problem.solution.route.activity.TimeWindow;
import jsprit.core.util.Coordinate;
@ -71,30 +72,21 @@ public class Shipment extends AbstractJob{
private Capacity.Builder capacityBuilder = Capacity.Builder.newInstance();
private Capacity capacity;
/**
private Skills.Builder skillBuilder = Skills.Builder.newInstance();
private Skills skills;
/**
* Returns new instance of this builder.
*
* @param id
* @return
* @param id the id of the shipment which must be a unique identifier among all jobs
* @return the builder
*/
public static Builder newInstance(String id){
return new Builder(id);
}
/**
* Constructs the builder
*
* @param id
* @param size
* @throws IllegalArgumentException if size < 0 or id is null
*/
Builder(String id, int size) {
if(size < 0) throw new IllegalArgumentException("size must be greater than or equal to zero");
if(id == null) throw new IllegalArgumentException("id must not be null");
this.id = id;
}
Builder(String id){
if(id == null) throw new IllegalArgumentException("id must not be null");
this.id = id;
@ -103,20 +95,20 @@ public class Shipment extends AbstractJob{
/**
* Sets pickup-location.
*
* @param pickupLocation
* @param pickupLocationId the location id of shipment's pickup
* @return builder
* @throws IllegalArgumentException if location is null
*/
public Builder setPickupLocation(String pickupLocation){
if(pickupLocation == null) throw new IllegalArgumentException("location must not be null");
this.pickupLocation = pickupLocation;
public Builder setPickupLocation(String pickupLocationId){
if(pickupLocationId == null) throw new IllegalArgumentException("location must not be null");
this.pickupLocation = pickupLocationId;
return this;
}
/**
* Sets pickup-coordinate.
*
* @param pickupCoord
* @param pickupCoord the coordinate of shipment's pickup location
* @return builder
* @throws IllegalArgumentException if pickupCoord is null
*/
@ -131,7 +123,7 @@ public class Shipment extends AbstractJob{
*
* <p>ServiceTime is intended to be the time the implied activity takes at the pickup-location.
*
* @param serviceTime
* @param serviceTime the service time / duration the pickup of the associated shipment takes
* @return builder
* @throws IllegalArgumentException if servicTime < 0.0
*/
@ -143,11 +135,11 @@ public class Shipment extends AbstractJob{
/**
* Sets the timeWindow for the pickup, i.e. the time-period in which a pickup operation is
* allowed to start.
* allowed to START.
*
* <p>By default timeWindow is [0.0, Double.MAX_VALUE}
*
* @param timeWindow
* @param timeWindow the time window within the pickup operation/activity can START
* @return builder
* @throws IllegalArgumentException if timeWindow is null
*/
@ -160,7 +152,7 @@ public class Shipment extends AbstractJob{
/**
* Sets the delivery-location.
*
* @param deliveryLocation
* @param deliveryLocation the delivery location id
* @return builder
* @throws IllegalArgumentException if location is null
*/
@ -173,7 +165,7 @@ public class Shipment extends AbstractJob{
/**
* Sets delivery-coord.
*
* @param deliveryCoord
* @param deliveryCoord the coordinate of shipment's delivery location
* @return builder
* @throws IllegalArgumentException if coord is null;
*/
@ -188,7 +180,7 @@ public class Shipment extends AbstractJob{
*
* <p>ServiceTime is intended to be the time the implied activity takes at the delivery-location.
*
* @param deliveryServiceTime
* @param deliveryServiceTime the service time / duration of shipment's delivery
* @return builder
* @throws IllegalArgumentException if serviceTime < 0.0
*/
@ -204,7 +196,7 @@ public class Shipment extends AbstractJob{
*
* <p>By default timeWindow is [0.0, Double.MAX_VALUE}
*
* @param timeWindow
* @param timeWindow the time window within the associated delivery is allowed to START
* @return builder
* @throws IllegalArgumentException if timeWindow is null
*/
@ -217,8 +209,8 @@ public class Shipment extends AbstractJob{
/**
* Adds capacity dimension.
*
* @param dimensionIndex
* @param dimensionValue
* @param dimensionIndex the dimension index of the corresponding capacity value
* @param dimensionValue the capacity value
* @return builder
* @throws IllegalArgumentException if dimVal < 0
*/
@ -246,11 +238,16 @@ public class Shipment extends AbstractJob{
deliveryLocation = deliveryCoord.toString();
}
capacity = capacityBuilder.build();
skills = skillBuilder.build();
return new Shipment(this);
}
}
public Builder addSkill(String skill) {
skillBuilder.addSkill(skill);
return this;
}
}
private final String id;
@ -272,12 +269,8 @@ public class Shipment extends AbstractJob{
private final Capacity capacity;
/**
* Constructs the shipment.
*
* @param builder
*/
private final Skills skills;
Shipment(Builder builder){
this.id = builder.id;
this.pickupLocation = builder.pickupLocation;
@ -289,6 +282,7 @@ public class Shipment extends AbstractJob{
this.deliveryServiceTime = builder.deliveryServiceTime;
this.deliveryTimeWindow = builder.deliveryTimeWindow;
this.capacity = builder.capacity;
this.skills = builder.skills;
}
@Override
@ -405,5 +399,10 @@ public class Shipment extends AbstractJob{
return capacity;
}
@Override
public Skills getRequiredSkills() {
return skills;
}
}

View file

@ -18,6 +18,7 @@ package jsprit.core.problem.vehicle;
import jsprit.core.problem.HasId;
import jsprit.core.problem.HasIndex;
import jsprit.core.problem.Skills;
import jsprit.core.util.Coordinate;
/**
@ -86,4 +87,6 @@ public interface Vehicle extends HasId, HasIndex {
public abstract Coordinate getEndLocationCoordinate();
public abstract VehicleTypeKey getVehicleTypeIdentifier();
public abstract Skills getSkills();
}

View file

@ -17,6 +17,7 @@
package jsprit.core.problem.vehicle;
import jsprit.core.problem.AbstractVehicle;
import jsprit.core.problem.Skills;
import jsprit.core.util.Coordinate;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@ -32,7 +33,9 @@ import org.apache.logging.log4j.Logger;
public class VehicleImpl extends AbstractVehicle{
/**
/**
* Extension of {@link VehicleImpl} representing an unspecified vehicle with the id 'noVehicle'
* (to avoid null).
*
@ -58,30 +61,36 @@ public class VehicleImpl extends AbstractVehicle{
*
*/
public static class Builder {
static Logger log = LogManager.getLogger(Builder.class.getName());
private String id;
static final Logger log = LogManager.getLogger(Builder.class.getName());
private String id;
private String locationId;
private Coordinate locationCoord;
private double earliestStart = 0.0;
private double latestArrival = Double.MAX_VALUE;
private String startLocationId;
private Coordinate startLocationCoord;
private String endLocationId;
private Coordinate endLocationCoord;
private boolean returnToDepot = true;
private VehicleType type = VehicleTypeImpl.Builder.newInstance("default").build();
/**
* Constructs the builder with the vehicleId.
*
* @param id
*/
private Builder(String id) {
private Skills.Builder skillBuilder = Skills.Builder.newInstance();
private Skills skills;
private Builder(String id) {
super();
this.id = id;
}
@ -89,7 +98,7 @@ public class VehicleImpl extends AbstractVehicle{
/**
* Sets the {@link VehicleType}.<br>
*
* @param type
* @param type the type to be set
* @throws IllegalStateException if type is null
* @return this builder
*/
@ -108,7 +117,7 @@ public class VehicleImpl extends AbstractVehicle{
*
* <p>If returnToDepot is false, the end-location of the vehicle is endogenous.
*
* @param returnToDepot
* @param returnToDepot true if vehicle need to return to depot, otherwise false
* @return this builder
*/
public Builder setReturnToDepot(boolean returnToDepot){
@ -119,7 +128,7 @@ public class VehicleImpl extends AbstractVehicle{
/**
* Sets the start-location of this vehicle.
*
* @param startLocationId
* @param startLocationId the location id of vehicle's start
* @return this builder
* @throws IllegalArgumentException if startLocationId is null
*/
@ -133,7 +142,7 @@ public class VehicleImpl extends AbstractVehicle{
/**
* Sets the start-coordinate of this vehicle.
*
* @param coord
* @param coord the coordinate of vehicle's start location
* @return this builder
*/
public Builder setStartLocationCoordinate(Coordinate coord){
@ -145,7 +154,7 @@ public class VehicleImpl extends AbstractVehicle{
/**
* Sets the end-locationId of this vehicle.
*
* @param endLocationId
* @param endLocationId the location id of vehicle's end
* @return this builder
*/
public Builder setEndLocationId(String endLocationId){
@ -156,7 +165,7 @@ public class VehicleImpl extends AbstractVehicle{
/**
* Sets the end-coordinate of this vehicle.
*
* @param coord
* @param coord the coordinate of vehicle's end location
* @return this builder
*/
public Builder setEndLocationCoordinate(Coordinate coord){
@ -167,24 +176,29 @@ public class VehicleImpl extends AbstractVehicle{
/**
* Sets earliest-start of vehicle which should be the lower bound of the vehicle's departure times.
*
* @param start
* @param earliest_startTime the earliest start time / departure time of the vehicle at its start location
* @return this builder
*/
public Builder setEarliestStart(double start){
this.earliestStart = start;
public Builder setEarliestStart(double earliest_startTime){
this.earliestStart = earliest_startTime;
return this;
}
/**
* Sets the latest arrival at vehicle's end-location which is the upper bound of the vehicle's arrival times.
*
* @param arr
* @param latest_arrTime the latest arrival time of the vehicle at its end location
* @return this builder
*/
public Builder setLatestArrival(double arr){
this.latestArrival = arr;
public Builder setLatestArrival(double latest_arrTime){
this.latestArrival = latest_arrTime;
return this;
}
public Builder addSkill(String skill){
skillBuilder.addSkill(skill);
return this;
}
/**
* Builds and returns the vehicle.
@ -217,15 +231,16 @@ public class VehicleImpl extends AbstractVehicle{
endLocationId = startLocationId;
endLocationCoord = startLocationCoord;
}
if( !startLocationId.equals(endLocationId) && returnToDepot == false) throw new IllegalStateException("this must not be. you specified both endLocationId and open-routes. this is contradictory. <br>" +
if( !startLocationId.equals(endLocationId) && !returnToDepot) throw new IllegalStateException("this must not be. you specified both endLocationId and open-routes. this is contradictory. <br>" +
"if you set endLocation, returnToDepot must be true. if returnToDepot is false, endLocationCoord must not be specified.");
return new VehicleImpl(this);
skills = skillBuilder.build();
return new VehicleImpl(this);
}
/**
* Returns new instance of vehicle builder.
*
* @param vehicleId
* @param vehicleId the id of the vehicle which must be a unique identifier among all vehicles
* @return vehicle builder
*/
public static Builder newInstance(String vehicleId){ return new Builder(vehicleId); }
@ -265,6 +280,8 @@ public class VehicleImpl extends AbstractVehicle{
private final String startLocationId;
private Skills skills;
private VehicleImpl(Builder builder){
id = builder.id;
type = builder.type;
@ -278,6 +295,7 @@ public class VehicleImpl extends AbstractVehicle{
endLocationId = builder.endLocationId;
endLocationCoord = builder.endLocationCoord;
setVehicleIdentifier(new VehicleTypeKey(type.getTypeId(),startLocationId,endLocationId,earliestDeparture,latestArrival));
skills = builder.skills;
}
/**
@ -334,9 +352,14 @@ public class VehicleImpl extends AbstractVehicle{
return this.endLocationCoord;
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public Skills getSkills() {
return skills;
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;

View file

@ -159,7 +159,7 @@ public class StateManagerTest {
public void whenCreatingNewState_itShouldHaveAnIndex(){
StateManager stateManager = new StateManager(mock(VehicleRoutingProblem.class));
StateId stateId = stateManager.createStateId("foo-state");
assertEquals(10,stateId.getIndex());
assertEquals(21,stateId.getIndex());
}
@Test
@ -167,8 +167,8 @@ public class StateManagerTest {
StateManager stateManager = new StateManager(mock(VehicleRoutingProblem.class));
StateId fooState = stateManager.createStateId("foo-state");
StateId foofooState = stateManager.createStateId("foo-foo-state");
assertEquals(10,fooState.getIndex());
assertEquals(11,foofooState.getIndex());
assertEquals(21,fooState.getIndex());
assertEquals(22,foofooState.getIndex());
}
@Test
@ -176,8 +176,8 @@ public class StateManagerTest {
StateManager stateManager = new StateManager(mock(VehicleRoutingProblem.class));
StateId fooState = stateManager.createStateId("foo-state");
StateId foofooState = stateManager.createStateId("foo-state");
assertEquals(10, fooState.getIndex());
assertEquals(10, foofooState.getIndex());
assertEquals(21, fooState.getIndex());
assertEquals(21, foofooState.getIndex());
}
@Test

View file

@ -1,27 +1,23 @@
package jsprit.core.algorithm.state;
import jsprit.core.problem.Skills;
import jsprit.core.problem.cost.VehicleRoutingTransportCosts;
import jsprit.core.problem.VehicleRoutingProblem;
import jsprit.core.problem.job.Service;
import jsprit.core.problem.solution.route.VehicleRoute;
import jsprit.core.problem.solution.route.state.StateFactory;
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 junit.framework.Assert;
import org.junit.Before;
import org.junit.Test;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
/**
* Created by schroeder on 01.07.14.
* Tests skill updater
*/
public class UpdateRequiredSkillsTest {
@ -31,24 +27,23 @@ public class UpdateRequiredSkillsTest {
@Before
public void doBefore(){
Vehicle vehicle = mock(Vehicle.class);
Service service = mock(Service.class);
Service service2 = mock(Service.class);
Service service3 = mock(Service.class);
when(service.getRequiredSkills()).thenReturn(Skills.Builder.newInstance().addSkill("skill1").build());
when(service2.getRequiredSkills()).thenReturn(Skills.Builder.newInstance().addSkill("skill1").addSkill("skill2")
.addSkill("skill3").build());
when(service3.getRequiredSkills()).thenReturn(Skills.Builder.newInstance().addSkill("skill4")
.addSkill("skill5").build());
route = VehicleRoute.Builder.newInstance(vehicle).addService(service).addService(service2).addService(service3).build();
stateManager = new StateManager(mock(VehicleRoutingTransportCosts.class));
stateManager.addStateUpdater(new UpdateSkills(stateManager));
VehicleType type = VehicleTypeImpl.Builder.newInstance("t").build();
VehicleImpl vehicle = VehicleImpl.Builder.newInstance("v").setStartLocationId("start").setType(type).build();
Service service = Service.Builder.newInstance("s").setLocationId("loc").addSkill("skill1").build();
Service service2 = Service.Builder.newInstance("s2").setLocationId("loc").addSkill("skill1").addSkill("skill2").addSkill("skill3").build();
Service service3 = Service.Builder.newInstance("s3").setLocationId("loc").addSkill("skill4").addSkill("skill5").build();
VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance().addVehicle(vehicle).addJob(service)
.addJob(service2).addJob(service3).build();
route = VehicleRoute.Builder.newInstance(vehicle).setJobActivityFactory(vrp.getJobActivityFactory()).addService(service).addService(service2).addService(service3).build();
stateManager = new StateManager(vrp);
stateManager.updateSkillStates();
stateManager.informInsertionStarts(Arrays.asList(route),null);
}
@Test
public void whenUpdatingRoute_skillsAtRouteLevelShouldContainAllSkills(){
stateManager.update(route);
Skills skills = stateManager.getRouteState(route, StateFactory.SKILLS, Skills.class);
Skills skills = stateManager.getRouteState(route, InternalStates.SKILLS, Skills.class);
assertNotNull(skills);
Assert.assertEquals(5,skills.values().size());
assertTrue(skills.containsSkill("skill1"));

View file

@ -1,13 +1,13 @@
package jsprit.core.problem.constraint;
import jsprit.core.algorithm.state.StateManager;
import jsprit.core.algorithm.state.UpdateSkills;
import jsprit.core.problem.Skills;
import jsprit.core.problem.cost.VehicleRoutingTransportCosts;
import jsprit.core.problem.VehicleRoutingProblem;
import jsprit.core.problem.job.Service;
import jsprit.core.problem.misc.JobInsertionContext;
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.problem.vehicle.VehicleTypeImpl;
import org.junit.Before;
import org.junit.Test;
@ -15,115 +15,72 @@ import java.util.Arrays;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class SkillConstraintTest {
private HardRouteStateLevelConstraint skillConstraint;
private StateManager stateManager;
private VehicleRoute route;
private Vehicle vehicle;
private VehicleImpl vehicle;
private VehicleImpl vehicle2;
private VehicleRoutingProblem vrp;
@Before
public void doBefore(){
vehicle = mock(Vehicle.class);
Service service = mock(Service.class);
Service service2 = mock(Service.class);
Service service3 = mock(Service.class);
when(service.getRequiredSkills()).thenReturn(Skills.Builder.newInstance().addSkill("skill1").build());
when(service2.getRequiredSkills()).thenReturn(Skills.Builder.newInstance().addSkill("skill1").addSkill("skill2")
.addSkill("skill3").build());
when(service3.getRequiredSkills()).thenReturn(Skills.Builder.newInstance().addSkill("skill4")
.addSkill("skill5").build());
route = VehicleRoute.Builder.newInstance(vehicle).addService(service).addService(service2).addService(service3).build();
stateManager = new StateManager(mock(VehicleRoutingTransportCosts.class));
stateManager.addStateUpdater(new UpdateSkills(stateManager));
stateManager.update(route);
VehicleType type = VehicleTypeImpl.Builder.newInstance("t").build();
vehicle = VehicleImpl.Builder.newInstance("v").addSkill("skill1").addSkill("skill2").addSkill("skill3").addSkill("skill4").setStartLocationId("start").setType(type).build();
vehicle2 = VehicleImpl.Builder.newInstance("v").addSkill("skill4").addSkill("skill5").setStartLocationId("start").setType(type).build();
Service service = Service.Builder.newInstance("s").setLocationId("loc").addSkill("skill1").build();
Service service2 = Service.Builder.newInstance("s2").setLocationId("loc").addSkill("skill1").addSkill("skill2").addSkill("skill3").build();
Service service3 = Service.Builder.newInstance("s3").setLocationId("loc").addSkill("skill4").addSkill("skill5").build();
Service service4 = Service.Builder.newInstance("s4").setLocationId("loc").addSkill("skill1").build();
vrp = VehicleRoutingProblem.Builder.newInstance().addVehicle(vehicle).addVehicle(vehicle2).addJob(service)
.addJob(service2).addJob(service3).addJob(service4).build();
route = VehicleRoute.Builder.newInstance(vehicle).setJobActivityFactory(vrp.getJobActivityFactory()).addService(service).addService(service2).build();
StateManager stateManager = new StateManager(vrp);
stateManager.updateSkillStates();
stateManager.informInsertionStarts(Arrays.asList(route),null);
skillConstraint = new HardSkillConstraint(stateManager);
}
@Test
public void whenJobToBeInsertedRequiresSkillsThatVehicleDoesNotHave_itShouldReturnFalse(){
Service s4 = mock(Service.class);
when(s4.getRequiredSkills()).thenReturn(Skills.Builder.newInstance().addSkill("skill5").build());
when(vehicle.getSkills()).thenReturn(Skills.Builder.newInstance()
.addAllSkills(Arrays.asList("skill1","skill2","skill3","skill4")).build());
JobInsertionContext insertionContext = new JobInsertionContext(route,s4,vehicle,route.getDriver(),0.);
assertFalse(skillConstraint.fulfilled(insertionContext));
}
@Test
public void whenJobToBeInsertedRequiresSkillsThatVehicle2DoesNotHave_itShouldReturnFalse(){
Service s4 = mock(Service.class);
when(s4.getRequiredSkills()).thenReturn(Skills.Builder.newInstance().addSkill("skill5").build());
Vehicle vehicle2 = mock(Vehicle.class);
when(vehicle2.getSkills()).thenReturn(Skills.Builder.newInstance()
.addAllSkills(Arrays.asList("skill1","skill2","skill3","skill4")).build());
JobInsertionContext insertionContext = new JobInsertionContext(route,s4,vehicle2,route.getDriver(),0.);
public void whenJobToBeInsertedRequiresSkillsThatNewVehicleDoesNotHave_itShouldReturnFalse(){
JobInsertionContext insertionContext = new JobInsertionContext(route,vrp.getJobs().get("s3"),vehicle,route.getDriver(),0.);
assertFalse(skillConstraint.fulfilled(insertionContext));
}
@Test
public void whenJobToBeInsertedRequiresSkillsThatVehicleHave_itShouldReturnTrue(){
Service s4 = mock(Service.class);
when(s4.getRequiredSkills()).thenReturn(Skills.Builder.newInstance().addSkill("skill4").build());
when(vehicle.getSkills()).thenReturn(Skills.Builder.newInstance()
.addAllSkills(Arrays.asList("skill1","skill2","skill3","skill4","skill5")).build());
JobInsertionContext insertionContext = new JobInsertionContext(route,s4,vehicle,route.getDriver(),0.);
assertTrue(skillConstraint.fulfilled(insertionContext));
}
@Test
public void whenJobToBeInsertedRequiresSkillsThatVehicle2Have_itShouldReturnTrue(){
Service s4 = mock(Service.class);
when(s4.getRequiredSkills()).thenReturn(Skills.Builder.newInstance().addSkill("skill4").build());
Vehicle vehicle2 = mock(Vehicle.class);
when(vehicle2.getSkills()).thenReturn(Skills.Builder.newInstance()
.addAllSkills(Arrays.asList("skill1","skill2","skill3","skill4","skill5")).build());
JobInsertionContext insertionContext = new JobInsertionContext(route,s4,vehicle2,route.getDriver(),0.);
JobInsertionContext insertionContext = new JobInsertionContext(route,vrp.getJobs().get("s4"),vehicle,route.getDriver(),0.);
assertTrue(skillConstraint.fulfilled(insertionContext));
}
@Test
public void whenRouteToBeOvertakenRequiresSkillsThatVehicleDoesNotHave_itShouldReturnFalse(){
Service s4 = mock(Service.class);
when(s4.getRequiredSkills()).thenReturn(Skills.Builder.newInstance().addSkill("skill4").build());
when(vehicle.getSkills()).thenReturn(Skills.Builder.newInstance()
.addAllSkills(Arrays.asList("skill1","skill2","skill6","skill4")).build());
JobInsertionContext insertionContext = new JobInsertionContext(route,s4,vehicle,route.getDriver(),0.);
JobInsertionContext insertionContext = new JobInsertionContext(route,vrp.getJobs().get("s3"),vehicle2,route.getDriver(),0.);
assertFalse(skillConstraint.fulfilled(insertionContext));
}
@Test
public void whenRouteToBeOvertakenRequiresSkillsThatVehicleDoesNotHave2_itShouldReturnFalse(){
JobInsertionContext insertionContext = new JobInsertionContext(route,vrp.getJobs().get("s4"),vehicle2,route.getDriver(),0.);
assertFalse(skillConstraint.fulfilled(insertionContext));
}
@Test
public void whenRouteToBeOvertakenRequiresSkillsThatVehicleDoesHave_itShouldReturnTrue(){
Service s4 = mock(Service.class);
when(s4.getRequiredSkills()).thenReturn(Skills.Builder.newInstance().addSkill("skill4").build());
when(vehicle.getSkills()).thenReturn(Skills.Builder.newInstance()
.addAllSkills(Arrays.asList("skill1","skill2","skill3","skill4","skill5")).build());
JobInsertionContext insertionContext = new JobInsertionContext(route,s4,vehicle,route.getDriver(),0.);
JobInsertionContext insertionContext = new JobInsertionContext(route,vrp.getJobs().get("s4"),vehicle,route.getDriver(),0.);
assertTrue(skillConstraint.fulfilled(insertionContext));
}
@Test
public void whenNoSkillsAreRequired_itShouldReturnTrue(){
Service s4 = mock(Service.class);
when(s4.getRequiredSkills()).thenReturn(Skills.Builder.newInstance().build());
when(vehicle.getSkills()).thenReturn(Skills.Builder.newInstance().build());
JobInsertionContext insertionContext = new JobInsertionContext(VehicleRoute.emptyRoute(),s4,vehicle,route.getDriver(),0.);
assertTrue(skillConstraint.fulfilled(insertionContext));
}
@Test
public void whenSkillsIsRequiredWhichVehicleDoesNotHave_itShouldReturnFalse(){
Service s4 = mock(Service.class);
when(s4.getRequiredSkills()).thenReturn(Skills.Builder.newInstance().addSkill("skill1").build());
when(vehicle.getSkills()).thenReturn(Skills.Builder.newInstance().build());
JobInsertionContext insertionContext = new JobInsertionContext(VehicleRoute.emptyRoute(),s4,vehicle,route.getDriver(),0.);
assertFalse(skillConstraint.fulfilled(insertionContext));
}
}

View file

@ -18,12 +18,10 @@
******************************************************************************/
package jsprit.core.problem.job;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import static org.junit.Assert.*;
public class DeliveryTest {
@Test(expected=IllegalStateException.class)

View file

@ -18,12 +18,10 @@
******************************************************************************/
package jsprit.core.problem.job;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import static org.junit.Assert.*;
public class PickupTest {
@Test(expected=IllegalStateException.class)

View file

@ -16,16 +16,14 @@
******************************************************************************/
package jsprit.core.problem.job;
import jsprit.core.problem.solution.route.activity.TimeWindow;
import jsprit.core.util.Coordinate;
import org.junit.Test;
import java.util.HashSet;
import java.util.Set;
import jsprit.core.problem.solution.route.activity.TimeWindow;
import jsprit.core.util.Coordinate;
import org.junit.Test;
import static org.junit.Assert.*;
import static org.junit.Assert.assertFalse;
public class ServiceTest {

View file

@ -20,7 +20,6 @@ package jsprit.core.problem.job;
import jsprit.core.problem.solution.route.activity.TimeWindow;
import jsprit.core.util.Coordinate;
import org.junit.Test;
import static org.junit.Assert.*;

View file

@ -19,14 +19,12 @@
package jsprit.core.problem.vehicle;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import jsprit.core.problem.vehicle.VehicleImpl.NoVehicle;
import jsprit.core.util.Coordinate;
import org.junit.Test;
import static org.junit.Assert.*;
public class VehicleImplTest {

View file

@ -21,12 +21,14 @@ import jsprit.analysis.toolbox.GraphStreamViewer.Label;
import jsprit.analysis.toolbox.SolutionPrinter;
import jsprit.analysis.toolbox.SolutionPrinter.Print;
import jsprit.core.algorithm.VehicleRoutingAlgorithm;
import jsprit.core.algorithm.box.SchrimpfFactory;
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.io.VrpXMLWriter;
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.VehicleImpl.Builder;
import jsprit.core.problem.vehicle.VehicleType;
import jsprit.core.problem.vehicle.VehicleTypeImpl;
@ -66,13 +68,13 @@ public class SimpleExampleWithSkills {
Builder vehicleBuilder = Builder.newInstance("vehicle");
vehicleBuilder.setStartLocationCoordinate(Coordinate.newInstance(10, 10));
vehicleBuilder.setType(vehicleType);
Vehicle vehicle = vehicleBuilder.build();
VehicleImpl vehicle = vehicleBuilder.build();
Builder vehicle2Builder = Builder.newInstance("vehicle2");
vehicle2Builder.setStartLocationCoordinate(Coordinate.newInstance(1, 1));
vehicle2Builder.setType(vehicleType);
vehicle2Builder.addSkill("drill");
Vehicle vehicle2 = vehicle2Builder.build();
VehicleImpl vehicle2 = vehicle2Builder.build();
/*
* build services at the required locations, each with a capacity-demand of 1.
@ -94,7 +96,20 @@ public class SimpleExampleWithSkills {
/*
* get the algorithm out-of-the-box.
*/
VehicleRoutingAlgorithm algorithm = new SchrimpfFactory().createAlgorithm(problem);
VehicleRoutingAlgorithmBuilder vraBuilder = new VehicleRoutingAlgorithmBuilder(problem,"input/algorithmConfig.xml");
vraBuilder.addCoreConstraints();
vraBuilder.addDefaultCostCalculators();
//activate skill state update and constraints - it is NOT default
StateManager stateManager = new StateManager(problem);
stateManager.updateSkillStates();
ConstraintManager constraintManager = new ConstraintManager(problem,stateManager);
constraintManager.addSkillsConstraint();
vraBuilder.setStateAndConstraintManager(stateManager,constraintManager);
VehicleRoutingAlgorithm algorithm = vraBuilder.build();
/*
* and search a solution