From 501453490d61d1f1a9f1fb26296e4580e0ab5752 Mon Sep 17 00:00:00 2001 From: oblonski <4sschroeder@gmail.com> Date: Thu, 3 Jul 2014 10:38:08 +0200 Subject: [PATCH] added skills --- .../problem/constraint/ConstraintManager.java | 2 +- ...nstraint.java => HardSkillConstraint.java} | 8 +- .../constraint/SkillConstraintTest.java | 24 +++- .../examples/SimpleExampleWithSkills.java | 121 ++++++++++++++++++ 4 files changed, 149 insertions(+), 6 deletions(-) rename jsprit-core/src/main/java/jsprit/core/problem/constraint/{SkillConstraint.java => HardSkillConstraint.java} (75%) create mode 100644 jsprit-examples/src/main/java/jsprit/examples/SimpleExampleWithSkills.java diff --git a/jsprit-core/src/main/java/jsprit/core/problem/constraint/ConstraintManager.java b/jsprit-core/src/main/java/jsprit/core/problem/constraint/ConstraintManager.java index e323c8a5..26d24c08 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/constraint/ConstraintManager.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/constraint/ConstraintManager.java @@ -118,7 +118,7 @@ public class ConstraintManager implements HardActivityStateLevelConstraint, Hard public void addSkillsConstraint() { if (!skillconstraintSet){ - addConstraint(new SkillConstraint(stateManager)); + addConstraint(new HardSkillConstraint(stateManager)); skillconstraintSet=true; } } diff --git a/jsprit-core/src/main/java/jsprit/core/problem/constraint/SkillConstraint.java b/jsprit-core/src/main/java/jsprit/core/problem/constraint/HardSkillConstraint.java similarity index 75% rename from jsprit-core/src/main/java/jsprit/core/problem/constraint/SkillConstraint.java rename to jsprit-core/src/main/java/jsprit/core/problem/constraint/HardSkillConstraint.java index 9459e350..ded358bf 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/constraint/SkillConstraint.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/constraint/HardSkillConstraint.java @@ -9,24 +9,24 @@ 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 SkillConstraint implements HardRouteStateLevelConstraint{ +public class HardSkillConstraint implements HardRouteStateLevelConstraint{ private RouteAndActivityStateGetter states; - public SkillConstraint(RouteAndActivityStateGetter states) { + public HardSkillConstraint(RouteAndActivityStateGetter states) { this.states = states; } @Override public boolean fulfilled(JobInsertionContext insertionContext) { for(String skill : insertionContext.getJob().getRequiredSkills().values()){ - if(!insertionContext.getRoute().getVehicle().getSkills().containsSkill(skill)){ + 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.getRoute().getVehicle().getSkills().containsSkill(skill)){ + if(!insertionContext.getNewVehicle().getSkills().containsSkill(skill)){ return false; } } diff --git a/jsprit-core/src/test/java/jsprit/core/problem/constraint/SkillConstraintTest.java b/jsprit-core/src/test/java/jsprit/core/problem/constraint/SkillConstraintTest.java index 8dd07676..c19ba569 100644 --- a/jsprit-core/src/test/java/jsprit/core/problem/constraint/SkillConstraintTest.java +++ b/jsprit-core/src/test/java/jsprit/core/problem/constraint/SkillConstraintTest.java @@ -44,7 +44,7 @@ public class SkillConstraintTest { stateManager = new StateManager(mock(VehicleRoutingTransportCosts.class)); stateManager.addStateUpdater(new UpdateSkills(stateManager)); stateManager.update(route); - skillConstraint = new SkillConstraint(stateManager); + skillConstraint = new HardSkillConstraint(stateManager); } @Test @@ -57,6 +57,17 @@ public class SkillConstraintTest { 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); @@ -67,6 +78,17 @@ public class SkillConstraintTest { 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); diff --git a/jsprit-examples/src/main/java/jsprit/examples/SimpleExampleWithSkills.java b/jsprit-examples/src/main/java/jsprit/examples/SimpleExampleWithSkills.java new file mode 100644 index 00000000..cab74eb5 --- /dev/null +++ b/jsprit-examples/src/main/java/jsprit/examples/SimpleExampleWithSkills.java @@ -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 . + ******************************************************************************/ +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 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(); + } + +}