mirror of
https://github.com/graphhopper/jsprit.git
synced 2020-01-24 07:45:05 +01:00
merged skills
This commit is contained in:
parent
9c4bd498c4
commit
c04d3acd51
23 changed files with 279 additions and 343 deletions
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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){
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -94,17 +93,15 @@ public class StateManager implements RouteAndActivityStateGetter, IterationStart
|
|||
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -43,4 +44,5 @@ public interface Job extends HasId, HasIndex {
|
|||
*/
|
||||
public Capacity getSize();
|
||||
|
||||
Skills getRequiredSkills();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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){
|
||||
|
|
@ -68,18 +69,9 @@ public class Service extends AbstractJob {
|
|||
|
||||
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
|
||||
|
|
@ -301,4 +301,9 @@ public class Service extends AbstractJob {
|
|||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Skills getRequiredSkills() {
|
||||
return skills;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
@ -72,29 +73,20 @@ public class Shipment extends AbstractJob{
|
|||
|
||||
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;
|
||||
|
||||
private final Skills skills;
|
||||
|
||||
/**
|
||||
* Constructs the shipment.
|
||||
*
|
||||
* @param builder
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,25 +176,30 @@ 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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"));
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
||||
|
|
|
|||
|
|
@ -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.*;
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue