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:28:18 +02:00
commit 9c4bd498c4
17 changed files with 676 additions and 32 deletions

View file

@ -58,8 +58,8 @@ public class VehicleRoutingAlgorithmBuilder {
/** /**
* Constructs the builder with the problem and an algorithmConfigFile. Latter is to configure and specify the ruin-and-recreate meta-heuristic. * Constructs the builder with the problem and an algorithmConfigFile. Latter is to configure and specify the ruin-and-recreate meta-heuristic.
* *
* @param problem * @param problem to solve
* @param algorithmConfig * @param algorithmConfig config file of VehicleRoutingAlgorithm
*/ */
public VehicleRoutingAlgorithmBuilder(VehicleRoutingProblem problem, String algorithmConfig) { public VehicleRoutingAlgorithmBuilder(VehicleRoutingProblem problem, String algorithmConfig) {
this.vrp=problem; this.vrp=problem;
@ -70,8 +70,8 @@ public class VehicleRoutingAlgorithmBuilder {
/** /**
* Constructs the builder with the problem and an algorithmConfig. Latter is to configure and specify the ruin-and-recreate meta-heuristic. * Constructs the builder with the problem and an algorithmConfig. Latter is to configure and specify the ruin-and-recreate meta-heuristic.
* *
* @param problem * @param problem to solve
* @param algorithmConfig * @param algorithmConfig config file of VehicleRoutingAlgorithm
*/ */
public VehicleRoutingAlgorithmBuilder(VehicleRoutingProblem problem, AlgorithmConfig algorithmConfig) { public VehicleRoutingAlgorithmBuilder(VehicleRoutingProblem problem, AlgorithmConfig algorithmConfig) {
this.vrp=problem; this.vrp=problem;
@ -85,7 +85,7 @@ public class VehicleRoutingAlgorithmBuilder {
* <p>If objective function is not set, a default function is applied (which basically minimizes * <p>If objective function is not set, a default function is applied (which basically minimizes
* fixed and variable transportation costs ({@link VariablePlusFixedSolutionCostCalculatorFactory}). * fixed and variable transportation costs ({@link VariablePlusFixedSolutionCostCalculatorFactory}).
* *
* @param objectiveFunction * @param objectiveFunction to be minimized
* @see VariablePlusFixedSolutionCostCalculatorFactory * @see VariablePlusFixedSolutionCostCalculatorFactory
*/ */
public void setObjectiveFunction(SolutionCostCalculator objectiveFunction) { public void setObjectiveFunction(SolutionCostCalculator objectiveFunction) {
@ -95,7 +95,7 @@ public class VehicleRoutingAlgorithmBuilder {
/** /**
* Sets stateManager to memorize states. * Sets stateManager to memorize states.
* *
* @param stateManager * @param stateManager that memorizes your states
* @see StateManager * @see StateManager
*/ */
public void setStateManager(StateManager stateManager) { public void setStateManager(StateManager stateManager) {
@ -105,7 +105,7 @@ public class VehicleRoutingAlgorithmBuilder {
/** /**
* Adds core constraints. * Adds core constraints.
* *
* <p>Thus, it adds vehicle-capacity and time-window constraints and their * <p>Thus, it adds vehicle-capacity, time-window and skills constraints and their
* required stateUpdater. * required stateUpdater.
* *
*/ */
@ -130,8 +130,8 @@ public class VehicleRoutingAlgorithmBuilder {
/** /**
* Sets state- and constraintManager. * Sets state- and constraintManager.
* *
* @param stateManager * @param stateManager that memorizes your states
* @param constraintManager * @param constraintManager that manages your constraints
* @see StateManager * @see StateManager
* @see ConstraintManager * @see ConstraintManager
*/ */
@ -143,7 +143,7 @@ public class VehicleRoutingAlgorithmBuilder {
/** /**
* Sets nuOfThreads. * Sets nuOfThreads.
* *
* @param nuOfThreads * @param nuOfThreads to be operated
*/ */
public void setNuOfThreads(int nuOfThreads){ public void setNuOfThreads(int nuOfThreads){
this.nuOfThreads=nuOfThreads; this.nuOfThreads=nuOfThreads;
@ -154,7 +154,7 @@ public class VehicleRoutingAlgorithmBuilder {
* *
* <p>If algorithmConfigFile is set, it reads the configuration. * <p>If algorithmConfigFile is set, it reads the configuration.
* *
* @return * @return the algorithm
*/ */
public VehicleRoutingAlgorithm build() { public VehicleRoutingAlgorithm build() {
if(stateManager == null) stateManager = new StateManager(vrp); if(stateManager == null) stateManager = new StateManager(vrp);
@ -167,8 +167,10 @@ public class VehicleRoutingAlgorithmBuilder {
if(addCoreConstraints){ if(addCoreConstraints){
constraintManager.addLoadConstraint(); constraintManager.addLoadConstraint();
constraintManager.addTimeWindowConstraint(); constraintManager.addTimeWindowConstraint();
stateManager.updateLoadStates(); constraintManager.addSkillsConstraint();
stateManager.updateLoadStates();
stateManager.updateTimeWindowStates(); stateManager.updateTimeWindowStates();
stateManager.updateSkillStates();
} }
if(algorithmConfig==null){ if(algorithmConfig==null){
algorithmConfig = new AlgorithmConfig(); algorithmConfig = new AlgorithmConfig();

View file

@ -461,6 +461,7 @@ public class VehicleRoutingAlgorithms {
} }
stateManager.updateLoadStates(); stateManager.updateLoadStates();
stateManager.updateTimeWindowStates(); stateManager.updateTimeWindowStates();
stateManager.updateSkillStates();
stateManager.addStateUpdater(new UpdateEndLocationIfRouteIsOpen()); stateManager.addStateUpdater(new UpdateEndLocationIfRouteIsOpen());
stateManager.addStateUpdater(new OpenRouteStateVerifier()); stateManager.addStateUpdater(new OpenRouteStateVerifier());
stateManager.addStateUpdater(new UpdateActivityTimes(vrp.getTransportCosts())); stateManager.addStateUpdater(new UpdateActivityTimes(vrp.getTransportCosts()));
@ -473,6 +474,7 @@ public class VehicleRoutingAlgorithms {
ConstraintManager constraintManager = new ConstraintManager(vrp,stateManager,vrp.getConstraints()); ConstraintManager constraintManager = new ConstraintManager(vrp,stateManager,vrp.getConstraints());
constraintManager.addTimeWindowConstraint(); constraintManager.addTimeWindowConstraint();
constraintManager.addLoadConstraint(); constraintManager.addLoadConstraint();
constraintManager.addSkillsConstraint();
return readAndCreateAlgorithm(vrp, config, nuOfThreads, null, stateManager, constraintManager, true); return readAndCreateAlgorithm(vrp, config, nuOfThreads, null, stateManager, constraintManager, true);
} }

View file

@ -0,0 +1,43 @@
package jsprit.core.algorithm.state;
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.
*/
public class UpdateSkills implements StateUpdater, ActivityVisitor{
private Skills.Builder skillBuilder;
private StateManager statesManager;
private VehicleRoute route;
public UpdateSkills(StateManager statesManager) {
this.statesManager = statesManager;
}
@Override
public void begin(VehicleRoute route) {
this.route = route;
skillBuilder = Skills.Builder.newInstance();
}
@Override
public void visit(TourActivity activity) {
if(activity instanceof TourActivity.JobActivity){
Skills skills = ((TourActivity.JobActivity) activity).getJob().getRequiredSkills();
skillBuilder.addAllSkills(skills.values());
}
}
@Override
public void finish() {
Skills skills = skillBuilder.build();
statesManager.putTypedInternalRouteState(route, StateFactory.SKILLS, Skills.class, skills);
}
}

View file

@ -71,7 +71,7 @@ public class Capacity {
/** /**
* Returns the inverted capacity, i.e. it multiplies all capacity dimensions with -1. * Returns the inverted capacity, i.e. it multiplies all capacity dimensions with -1.
* *
* @param cap * @param cap2invert
* @return inverted capacity * @return inverted capacity
* @throws NullPointerException if one of the args is null * @throws NullPointerException if one of the args is null
*/ */

View file

@ -0,0 +1,76 @@
package jsprit.core.problem;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
/**
* Created by schroeder on 01.07.14.
*/
public class Skills {
public static class Builder {
/**
* Returns new instance of skill-builder.
*
* @return
*/
public static Builder newInstance(){
return new Builder();
}
private Set<String> skills = new HashSet<String>();
/**
* Adds skill. Skill is transformed into lowerCase.
*
* @param skill
* @return
*/
public Builder addSkill(String skill){
skills.add(skill.toLowerCase());
return this;
}
public Builder addAllSkills(Collection<String> skills){
for(String skill : skills) this.skills.add(skill);
return this;
}
public Skills build(){
return new Skills(this);
}
}
private Set<String> skills = new HashSet<String>();
private Skills(Builder builder){
skills.addAll(builder.skills);
}
/**
* Returns an unmodifiable set of skills. All skills are inLowerCase.
*
* @return
*/
public Set<String> values(){
return Collections.unmodifiableSet(skills);
}
/**
* Not case sensitive.
*
* @param skill
* @return
*/
public boolean containsSkill(String skill){
return skills.contains(skill.toLowerCase());
}
}

View file

@ -38,7 +38,7 @@ import java.util.List;
*/ */
public class ConstraintManager implements HardActivityStateLevelConstraint, HardRouteStateLevelConstraint, SoftActivityConstraint, SoftRouteConstraint{ public class ConstraintManager implements HardActivityStateLevelConstraint, HardRouteStateLevelConstraint, SoftActivityConstraint, SoftRouteConstraint{
public static enum Priority { public static enum Priority {
CRITICAL, HIGH, LOW CRITICAL, HIGH, LOW
} }
@ -60,6 +60,8 @@ public class ConstraintManager implements HardActivityStateLevelConstraint, Hard
private boolean timeWindowConstraintsSet = false; private boolean timeWindowConstraintsSet = false;
private boolean skillconstraintSet = false;
public ConstraintManager(VehicleRoutingProblem vrp, RouteAndActivityStateGetter stateManager) { public ConstraintManager(VehicleRoutingProblem vrp, RouteAndActivityStateGetter stateManager) {
this.vrp = vrp; this.vrp = vrp;
this.stateManager = stateManager; this.stateManager = stateManager;
@ -114,6 +116,13 @@ public class ConstraintManager implements HardActivityStateLevelConstraint, Hard
} }
} }
public void addSkillsConstraint() {
if (!skillconstraintSet){
addConstraint(new HardSkillConstraint(stateManager));
skillconstraintSet=true;
}
}
// public void add // public void add
public void addConstraint(HardActivityStateLevelConstraint actLevelConstraint, Priority priority){ public void addConstraint(HardActivityStateLevelConstraint actLevelConstraint, Priority priority){

View file

@ -0,0 +1,36 @@
package jsprit.core.problem.constraint;
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.
*
*/
public class HardSkillConstraint implements HardRouteStateLevelConstraint{
private RouteAndActivityStateGetter states;
public HardSkillConstraint(RouteAndActivityStateGetter states) {
this.states = states;
}
@Override
public boolean fulfilled(JobInsertionContext insertionContext) {
for(String skill : insertionContext.getJob().getRequiredSkills().values()){
if(!insertionContext.getNewVehicle().getSkills().containsSkill(skill)){
return false;
}
}
Skills requiredSkillsForRoute = states.getRouteState(insertionContext.getRoute(), StateFactory.SKILLS, Skills.class);
for(String skill : requiredSkillsForRoute.values()){
if(!insertionContext.getNewVehicle().getSkills().containsSkill(skill)){
return false;
}
}
return true;
}
}

View file

@ -0,0 +1,62 @@
package jsprit.core.algorithm.state;
import jsprit.core.problem.Skills;
import jsprit.core.problem.cost.VehicleRoutingTransportCosts;
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 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.
*/
public class UpdateRequiredSkillsTest {
private VehicleRoute route;
private StateManager stateManager;
@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));
}
@Test
public void whenUpdatingRoute_skillsAtRouteLevelShouldContainAllSkills(){
stateManager.update(route);
Skills skills = stateManager.getRouteState(route, StateFactory.SKILLS, Skills.class);
assertNotNull(skills);
Assert.assertEquals(5,skills.values().size());
assertTrue(skills.containsSkill("skill1"));
assertTrue(skills.containsSkill("skill2"));
assertTrue(skills.containsSkill("skill3"));
assertTrue(skills.containsSkill("skill4"));
assertTrue(skills.containsSkill("skill5"));
}
}

View file

@ -0,0 +1,39 @@
package jsprit.core.problem;
import org.junit.Test;
import java.util.HashSet;
import java.util.Set;
import static org.junit.Assert.assertTrue;
/**
* Created by schroeder on 01.07.14.
*/
public class SkillsTest {
@Test
public void whenSkillsAdded_theyShouldBeinSkillSet(){
Skills skills = Skills.Builder.newInstance().addSkill("skill1").addSkill("skill2").build();
assertTrue(skills.containsSkill("skill1"));
assertTrue(skills.containsSkill("skill2"));
}
@Test
public void whenSkillsAddedCaseInsensitive_theyShouldBeinSkillSet(){
Skills skills = Skills.Builder.newInstance().addSkill("skill1").addSkill("skill2").build();
assertTrue(skills.containsSkill("skilL1"));
assertTrue(skills.containsSkill("skIll2"));
}
@Test
public void whenSkillsAddedThroughAddAll_theyShouldBeinSkillSet(){
Set<String> skillSet = new HashSet<String>();
skillSet.add("skill1");
skillSet.add("skill2");
Skills skills = Skills.Builder.newInstance().addAllSkills(skillSet).build();
assertTrue(skills.containsSkill("skill1"));
assertTrue(skills.containsSkill("skill2"));
}
}

View file

@ -0,0 +1,129 @@
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.job.Service;
import jsprit.core.problem.misc.JobInsertionContext;
import jsprit.core.problem.solution.route.VehicleRoute;
import jsprit.core.problem.vehicle.Vehicle;
import org.junit.Before;
import org.junit.Test;
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;
@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);
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.);
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.);
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.);
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.);
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

@ -19,6 +19,8 @@
package jsprit.core.problem.job; package jsprit.core.problem.job;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.junit.Test; import org.junit.Test;
@ -57,5 +59,29 @@ public class DeliveryTest {
assertEquals(1,one.getSize().get(0)); assertEquals(1,one.getSize().get(0));
} }
@Test
public void whenAddingSkills_theyShouldBeAddedCorrectly(){
Delivery s = (Delivery) Delivery.Builder.newInstance("s").setLocationId("loc")
.addSkill("drill").addSkill("screwdriver").build();
assertTrue(s.getRequiredSkills().containsSkill("drill"));
assertTrue(s.getRequiredSkills().containsSkill("ScrewDriver"));
}
@Test
public void whenAddingSkillsCaseSens_theyShouldBeAddedCorrectly(){
Delivery s = (Delivery) Delivery.Builder.newInstance("s").setLocationId("loc")
.addSkill("DriLl").addSkill("screwDriver").build();
assertTrue(s.getRequiredSkills().containsSkill("drill"));
assertTrue(s.getRequiredSkills().containsSkill("drilL"));
}
@Test
public void whenAddingSkillsCaseSensV2_theyShouldBeAddedCorrectly(){
Delivery s = (Delivery) Delivery.Builder.newInstance("s").setLocationId("loc")
.addSkill("screwDriver").build();
assertFalse(s.getRequiredSkills().containsSkill("drill"));
assertFalse(s.getRequiredSkills().containsSkill("drilL"));
}
} }

View file

@ -19,6 +19,8 @@
package jsprit.core.problem.job; package jsprit.core.problem.job;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.junit.Test; import org.junit.Test;
@ -57,5 +59,30 @@ public class PickupTest {
assertEquals(1,one.getSize().get(0)); assertEquals(1,one.getSize().get(0));
} }
@Test
public void whenAddingSkills_theyShouldBeAddedCorrectly(){
Pickup s = (Pickup) Pickup.Builder.newInstance("s").setLocationId("loc")
.addSkill("drill").addSkill("screwdriver").build();
assertTrue(s.getRequiredSkills().containsSkill("drill"));
assertTrue(s.getRequiredSkills().containsSkill("drill"));
assertTrue(s.getRequiredSkills().containsSkill("ScrewDriver"));
}
@Test
public void whenAddingSkillsCaseSens_theyShouldBeAddedCorrectly(){
Pickup s = (Pickup) Pickup.Builder.newInstance("s").setLocationId("loc")
.addSkill("DriLl").addSkill("screwDriver").build();
assertTrue(s.getRequiredSkills().containsSkill("drill"));
assertTrue(s.getRequiredSkills().containsSkill("drilL"));
}
@Test
public void whenAddingSkillsCaseSensV2_theyShouldBeAddedCorrectly(){
Pickup s = (Pickup) Pickup.Builder.newInstance("s").setLocationId("loc")
.addSkill("screwDriver").build();
assertFalse(s.getRequiredSkills().containsSkill("drill"));
assertFalse(s.getRequiredSkills().containsSkill("drilL"));
}
} }

View file

@ -16,12 +16,6 @@
******************************************************************************/ ******************************************************************************/
package jsprit.core.problem.job; package jsprit.core.problem.job;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
@ -30,6 +24,9 @@ import jsprit.core.util.Coordinate;
import org.junit.Test; import org.junit.Test;
import static org.junit.Assert.*;
import static org.junit.Assert.assertFalse;
public class ServiceTest { public class ServiceTest {
@Test @Test
@ -147,4 +144,29 @@ public class ServiceTest {
assertEquals(2.0,s.getTimeWindow().getEnd(),0.01); assertEquals(2.0,s.getTimeWindow().getEnd(),0.01);
} }
@Test
public void whenAddingSkills_theyShouldBeAddedCorrectly(){
Service s = Service.Builder.newInstance("s").setLocationId("loc")
.addSkill("drill").addSkill("screwdriver").build();
assertTrue(s.getRequiredSkills().containsSkill("drill"));
assertTrue(s.getRequiredSkills().containsSkill("drill"));
assertTrue(s.getRequiredSkills().containsSkill("ScrewDriver"));
}
@Test
public void whenAddingSkillsCaseSens_theyShouldBeAddedCorrectly(){
Service s = Service.Builder.newInstance("s").setLocationId("loc")
.addSkill("DriLl").addSkill("screwDriver").build();
assertTrue(s.getRequiredSkills().containsSkill("drill"));
assertTrue(s.getRequiredSkills().containsSkill("drilL"));
}
@Test
public void whenAddingSkillsCaseSensV2_theyShouldBeAddedCorrectly(){
Service s = Service.Builder.newInstance("s").setLocationId("loc")
.addSkill("screwDriver").build();
assertFalse(s.getRequiredSkills().containsSkill("drill"));
assertFalse(s.getRequiredSkills().containsSkill("drilL"));
}
} }

View file

@ -18,14 +18,13 @@
******************************************************************************/ ******************************************************************************/
package jsprit.core.problem.job; package jsprit.core.problem.job;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import jsprit.core.problem.solution.route.activity.TimeWindow; import jsprit.core.problem.solution.route.activity.TimeWindow;
import jsprit.core.util.Coordinate; import jsprit.core.util.Coordinate;
import org.junit.Test; import org.junit.Test;
import static org.junit.Assert.*;
public class ShipmentTest { public class ShipmentTest {
@Test @Test
@ -249,4 +248,29 @@ public class ShipmentTest {
assertEquals(1,one.getSize().getNuOfDimensions()); assertEquals(1,one.getSize().getNuOfDimensions());
assertEquals(1,one.getSize().get(0)); assertEquals(1,one.getSize().get(0));
} }
@Test
public void whenAddingSkills_theyShouldBeAddedCorrectly(){
Shipment s = Shipment.Builder.newInstance("s").setPickupLocation("loc").setDeliveryLocation("delLoc")
.addSkill("drill").addSkill("screwdriver").build();
assertTrue(s.getRequiredSkills().containsSkill("drill"));
assertTrue(s.getRequiredSkills().containsSkill("drill"));
assertTrue(s.getRequiredSkills().containsSkill("ScrewDriver"));
}
@Test
public void whenAddingSkillsCaseSens_theyShouldBeAddedCorrectly(){
Delivery s = (Delivery) Delivery.Builder.newInstance("s").setLocationId("loc")
.addSkill("DriLl").addSkill("screwDriver").build();
assertTrue(s.getRequiredSkills().containsSkill("drill"));
assertTrue(s.getRequiredSkills().containsSkill("drilL"));
}
@Test
public void whenAddingSkillsCaseSensV2_theyShouldBeAddedCorrectly(){
Delivery s = (Delivery) Delivery.Builder.newInstance("s").setLocationId("loc")
.addSkill("screwDriver").build();
assertFalse(s.getRequiredSkills().containsSkill("drill"));
assertFalse(s.getRequiredSkills().containsSkill("drilL"));
}
} }

View file

@ -205,5 +205,33 @@ public class VehicleImplTest {
assertTrue(!v.equals(v2)); assertTrue(!v.equals(v2));
} }
@Test
public void whenAddingSkills_theyShouldBeAddedCorrectly(){
VehicleTypeImpl type1 = VehicleTypeImpl.Builder.newInstance("type").build();
Vehicle v = VehicleImpl.Builder.newInstance("v").setStartLocationId("start").setType(type1).setEndLocationId("start")
.addSkill("drill").addSkill("screwdriver").build();
assertTrue(v.getSkills().containsSkill("drill"));
assertTrue(v.getSkills().containsSkill("drill"));
assertTrue(v.getSkills().containsSkill("screwdriver"));
}
@Test
public void whenAddingSkillsCaseSens_theyShouldBeAddedCorrectly(){
VehicleTypeImpl type1 = VehicleTypeImpl.Builder.newInstance("type").build();
Vehicle v = VehicleImpl.Builder.newInstance("v").setStartLocationId("start").setType(type1).setEndLocationId("start")
.addSkill("drill").addSkill("screwdriver").build();
assertTrue(v.getSkills().containsSkill("drill"));
assertTrue(v.getSkills().containsSkill("dRill"));
assertTrue(v.getSkills().containsSkill("ScrewDriver"));
}
@Test
public void whenAddingSkillsCaseSensV2_theyShouldBeAddedCorrectly(){
VehicleTypeImpl type1 = VehicleTypeImpl.Builder.newInstance("type").build();
Vehicle v = VehicleImpl.Builder.newInstance("v").setStartLocationId("start").setType(type1).setEndLocationId("start")
.addSkill("drill").build();
assertFalse(v.getSkills().containsSkill("ScrewDriver"));
}
} }

View file

@ -0,0 +1,121 @@
/*******************************************************************************
* Copyright (C) 2013 Stefan Schroeder
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
package jsprit.examples;
import jsprit.analysis.toolbox.GraphStreamViewer;
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.problem.VehicleRoutingProblem;
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.Builder;
import jsprit.core.problem.vehicle.VehicleType;
import jsprit.core.problem.vehicle.VehicleTypeImpl;
import jsprit.core.util.Coordinate;
import jsprit.core.util.Solutions;
import java.io.File;
import java.util.Collection;
public class SimpleExampleWithSkills {
public static void main(String[] args) {
/*
* some preparation - create output folder
*/
File dir = new File("output");
// if the directory does not exist, create it
if (!dir.exists()){
System.out.println("creating directory ./output");
boolean result = dir.mkdir();
if(result) System.out.println("./output created");
}
/*
* get a vehicle type-builder and build a type with the typeId "vehicleType" and one capacity dimension, i.e. weight, and capacity dimension value of 2
*/
final int WEIGHT_INDEX = 0;
VehicleTypeImpl.Builder vehicleTypeBuilder = VehicleTypeImpl.Builder.newInstance("vehicleType").addCapacityDimension(WEIGHT_INDEX, 2);
VehicleType vehicleType = vehicleTypeBuilder.build();
/*
* get a vehicle-builder and build a vehicle located at (10,10) with type "vehicleType"
*/
Builder vehicleBuilder = Builder.newInstance("vehicle");
vehicleBuilder.setStartLocationCoordinate(Coordinate.newInstance(10, 10));
vehicleBuilder.setType(vehicleType);
Vehicle vehicle = vehicleBuilder.build();
Builder vehicle2Builder = Builder.newInstance("vehicle2");
vehicle2Builder.setStartLocationCoordinate(Coordinate.newInstance(1, 1));
vehicle2Builder.setType(vehicleType);
vehicle2Builder.addSkill("drill");
Vehicle vehicle2 = vehicle2Builder.build();
/*
* build services at the required locations, each with a capacity-demand of 1.
*/
Service service1 = Service.Builder.newInstance("1").addSizeDimension(WEIGHT_INDEX, 1).setCoord(Coordinate.newInstance(5, 7)).build();
Service service2 = Service.Builder.newInstance("2").addSizeDimension(WEIGHT_INDEX, 1).setCoord(Coordinate.newInstance(5, 13)).build();
Service service3 = Service.Builder.newInstance("3").addSizeDimension(WEIGHT_INDEX, 1).setCoord(Coordinate.newInstance(15, 7)).build();
Service service4 = Service.Builder.newInstance("4").addSizeDimension(WEIGHT_INDEX, 1).addSkill("drill").setCoord(Coordinate.newInstance(15, 13)).build();
VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
vrpBuilder.addVehicle(vehicle).addVehicle(vehicle2);
vrpBuilder.addJob(service1).addJob(service2).addJob(service3).addJob(service4);
VehicleRoutingProblem problem = vrpBuilder.build();
/*
* get the algorithm out-of-the-box.
*/
VehicleRoutingAlgorithm algorithm = new SchrimpfFactory().createAlgorithm(problem);
/*
* and search a solution
*/
Collection<VehicleRoutingProblemSolution> solutions = algorithm.searchSolutions();
/*
* get the best
*/
VehicleRoutingProblemSolution bestSolution = Solutions.bestOf(solutions);
new VrpXMLWriter(problem, solutions).write("output/problem-with-solution.xml");
SolutionPrinter.print(problem,bestSolution,Print.VERBOSE);
/*
* plot
*/
// SolutionPlotter.plotSolutionAsPNG(problem, bestSolution, "output/solution.png", "solution");
new GraphStreamViewer(problem, bestSolution).labelWith(Label.ID).setRenderDelay(200).display();
}
}

View file

@ -215,13 +215,11 @@ public class TransportOfDisabledPeople {
problemPlotter.plotShipments(true); problemPlotter.plotShipments(true);
problemPlotter.setLabel(jsprit.analysis.toolbox.Plotter.Label.SIZE); problemPlotter.setLabel(jsprit.analysis.toolbox.Plotter.Label.SIZE);
problemPlotter.plot("output/transportOfDisabledPeopleExample_problem.png", "disabled people tp"); problemPlotter.plot("output/transportOfDisabledPeopleExample_problem.png", "disabled people tp");
//
// /* Plotter solutionPlotter = new Plotter(problem,Solutions.bestOf(solutions));
// * plot problem with solution solutionPlotter.plotShipments(true);
// */ solutionPlotter.setLabel(jsprit.analysis.toolbox.Plotter.Label.SIZE);
// Plotter solutionPlotter = new Plotter(problem,Arrays.asList(Solutions.bestOf(solutions).getRoutes().iterator().next())); solutionPlotter.plot("output/transportOfDisabledPeopleExample_solution.png", "disabled people tp");
// solutionPlotter.plotShipments(true);
// solutionPlotter.plot("output/enRoutePickupAndDeliveryWithMultipleLocationsExample_solution.png", "en-route pickup and delivery");
new GraphStreamViewer(problem).labelWith(Label.ID).setRenderDelay(100).setRenderShipments(true).display(); new GraphStreamViewer(problem).labelWith(Label.ID).setRenderDelay(100).setRenderShipments(true).display();