mirror of
https://github.com/graphhopper/jsprit.git
synced 2020-01-24 07:45:05 +01:00
add and test skill constraint violation checks
This commit is contained in:
parent
47d859652a
commit
c788b477b6
2 changed files with 287 additions and 92 deletions
|
|
@ -27,10 +27,7 @@ import jsprit.core.util.ActivityTimeTracker;
|
|||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -247,6 +244,48 @@ public class SolutionAnalyser {
|
|||
}
|
||||
}
|
||||
|
||||
private static class SkillUpdater implements StateUpdater, ActivityVisitor {
|
||||
|
||||
private StateManager stateManager;
|
||||
|
||||
private StateId skill_id;
|
||||
|
||||
private VehicleRoute route;
|
||||
|
||||
private boolean skillConstraintViolatedOnRoute;
|
||||
|
||||
private SkillUpdater(StateManager stateManager, StateId skill_id) {
|
||||
this.stateManager = stateManager;
|
||||
this.skill_id = skill_id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void begin(VehicleRoute route) {
|
||||
this.route = route;
|
||||
skillConstraintViolatedOnRoute = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(TourActivity activity) {
|
||||
boolean violatedAtActivity = false;
|
||||
if(activity instanceof TourActivity.JobActivity){
|
||||
Set<String> requiredForActivity = ((TourActivity.JobActivity) activity).getJob().getRequiredSkills().values();
|
||||
for(String skill : requiredForActivity){
|
||||
if(!route.getVehicle().getSkills().containsSkill(skill)){
|
||||
violatedAtActivity = true;
|
||||
skillConstraintViolatedOnRoute = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
stateManager.putActivityState(activity,skill_id,violatedAtActivity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish() {
|
||||
stateManager.putRouteState(route,skill_id, skillConstraintViolatedOnRoute);
|
||||
}
|
||||
}
|
||||
|
||||
private static final Logger log = LogManager.getLogger(SolutionAnalyser.class);
|
||||
|
||||
private VehicleRoutingProblem vrp;
|
||||
|
|
@ -271,16 +310,14 @@ public class SolutionAnalyser {
|
|||
|
||||
private final StateId backhaul_id;
|
||||
|
||||
private final StateId skill_id;
|
||||
|
||||
private ActivityTimeTracker.ActivityPolicy activityPolicy;
|
||||
|
||||
|
||||
private final VehicleRoutingProblemSolution working_solution;
|
||||
|
||||
public SolutionAnalyser(VehicleRoutingProblem vrp, VehicleRoutingProblemSolution solution, DistanceCalculator distanceCalculator) {
|
||||
this.vrp = vrp;
|
||||
// this.original_solution = VehicleRoutingProblemSolution.copyOf(solution);
|
||||
this.working_solution = solution;
|
||||
this.routes = new ArrayList<VehicleRoute>(working_solution.getRoutes());
|
||||
this.routes = new ArrayList<VehicleRoute>(solution.getRoutes());
|
||||
this.stateManager = new StateManager(vrp);
|
||||
this.stateManager.updateTimeWindowStates();
|
||||
this.stateManager.updateLoadStates();
|
||||
|
|
@ -296,9 +333,11 @@ public class SolutionAnalyser {
|
|||
too_late_id = stateManager.createStateId("too-late");
|
||||
shipment_id = stateManager.createStateId("shipment");
|
||||
backhaul_id = stateManager.createStateId("backhaul");
|
||||
skill_id = stateManager.createStateId("skills-violated");
|
||||
stateManager.addStateUpdater(new SumUpActivityTimes(waiting_time_id, transport_time_id, service_time_id,too_late_id , stateManager, activityPolicy));
|
||||
stateManager.addStateUpdater(new DistanceUpdater(distance_id,stateManager,distanceCalculator));
|
||||
stateManager.addStateUpdater(new BackhaulAndShipmentUpdater(backhaul_id,shipment_id,stateManager));
|
||||
stateManager.addStateUpdater(new SkillUpdater(stateManager,skill_id));
|
||||
refreshStates();
|
||||
}
|
||||
|
||||
|
|
@ -451,22 +490,53 @@ public class SolutionAnalyser {
|
|||
return Math.max(0, activity.getArrTime() - activity.getTheoreticalLatestOperationStartTime());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param route to check skill constraint
|
||||
* @return true if skill constraint is violated, i.e. if vehicle does not have the required skills to conduct all
|
||||
* activities on the specified route. Returns null if route is null or skill state cannot be found.
|
||||
*/
|
||||
public Boolean skillConstraintIsViolated(VehicleRoute route){
|
||||
if(route == null) throw new IllegalStateException("route is missing.");
|
||||
return null;
|
||||
return stateManager.getRouteState(route, skill_id, Boolean.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param activity to check skill constraint
|
||||
* @param route that must contain specified activity
|
||||
* @return true if vehicle does not have the skills to conduct specified activity, false otherwise. Returns null
|
||||
* if specified route or activity is null or if route does not contain specified activity or if skill state connot be
|
||||
* found. If specified activity is Start or End, it returns false.
|
||||
*/
|
||||
public Boolean skillConstraintIsViolatedAtActivity(TourActivity activity, VehicleRoute route){
|
||||
if(route == null) throw new IllegalStateException("route is missing.");
|
||||
if(activity == null) throw new IllegalStateException("activity is missing.");
|
||||
if(activity instanceof Start) return false;
|
||||
if(activity instanceof End) return false;
|
||||
verifyThatRouteContainsAct(activity, route);
|
||||
return null;
|
||||
return stateManager.getActivityState(activity, skill_id, Boolean.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if backhaul constraint is violated (false otherwise). Backhaul constraint is violated if either a
|
||||
* pickupService, serviceActivity (which is basically modeled as pickupService) or a pickupShipment occur before
|
||||
* a deliverService activity or - to put it in other words - if a depot bounded delivery occurs after a pickup, thus
|
||||
* the backhaul ensures depot bounded delivery activities first.
|
||||
*
|
||||
* @param route to check backhaul constraint
|
||||
* @return true if backhaul constraint for specified route is violated. returns null if route is null or no backhaul
|
||||
* state can be found. In latter case try routeChanged(route).
|
||||
*/
|
||||
public Boolean backhaulConstraintIsViolated(VehicleRoute route){
|
||||
if(route == null) throw new IllegalStateException("route is missing.");
|
||||
return stateManager.getRouteState(route,backhaul_id,Boolean.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param activity to check backhaul violation
|
||||
* @param route that must contain the specified activity
|
||||
* @return true if backhaul constraint is violated, false otherwise. Null if either specified route or activity is null.
|
||||
* Null if specified route does not contain specified activity.
|
||||
*/
|
||||
public Boolean backhaulConstraintIsViolatedAtActivity(TourActivity activity, VehicleRoute route){
|
||||
if(route == null) throw new IllegalStateException("route is missing.");
|
||||
if(activity == null) throw new IllegalStateException("activity is missing.");
|
||||
|
|
@ -476,11 +546,28 @@ public class SolutionAnalyser {
|
|||
return stateManager.getActivityState(activity,backhaul_id,Boolean.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true, if shipment constraint is violated. Two activities are associated to a shipment: pickupShipment
|
||||
* and deliverShipment. If both shipments are not in the same route OR deliverShipment occurs before pickupShipment
|
||||
* then the shipment constraint is violated.
|
||||
*
|
||||
* @param route to check the shipment constraint.
|
||||
* @return true if violated, false otherwise. Null if no state can be found or specified route is null.
|
||||
*/
|
||||
public Boolean shipmentConstraintIsViolated(VehicleRoute route){
|
||||
if(route == null) throw new IllegalStateException("route is missing.");
|
||||
return stateManager.getRouteState(route,shipment_id,Boolean.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if shipment constraint is violated, i.e. if activity is deliverShipment but no pickupShipment can be
|
||||
* found before OR activity is pickupShipment and no deliverShipment can be found afterwards.
|
||||
*
|
||||
* @param activity to check the shipment constraint
|
||||
* @param route that must contain specified activity
|
||||
* @return true if shipment constraint is violated, false otherwise. If activity is either Start or End, it returns
|
||||
* false. Returns null if either specified activity or route is null or route does not containt activity.
|
||||
*/
|
||||
public Boolean shipmentConstraintIsViolatedAtActivity(TourActivity activity, VehicleRoute route){
|
||||
if(route == null) throw new IllegalStateException("route is missing.");
|
||||
if(activity == null) throw new IllegalStateException("activity is missing.");
|
||||
|
|
|
|||
|
|
@ -58,18 +58,31 @@ public class SolutionAnalyserTest {
|
|||
VehicleType type = VehicleTypeImpl.Builder.newInstance("type").setFixedCost(100.).setCostPerDistance(2.).addCapacityDimension(0, 15).build();
|
||||
|
||||
VehicleImpl vehicle = VehicleImpl.Builder.newInstance("v1").setType(type)
|
||||
.setStartLocationCoordinate(Coordinate.newInstance(-5, 0)).build();
|
||||
.setStartLocationCoordinate(Coordinate.newInstance(-5, 0))
|
||||
.addSkill("skill1").addSkill("skill2")
|
||||
.build();
|
||||
|
||||
VehicleImpl vehicle2 = VehicleImpl.Builder.newInstance("v2").setType(type)
|
||||
.setStartLocationCoordinate(Coordinate.newInstance(5, 0)).build();
|
||||
|
||||
Service s1 = Service.Builder.newInstance("s1")
|
||||
.setTimeWindow(TimeWindow.newInstance(10, 20))
|
||||
.setCoord(Coordinate.newInstance(-10, 1)).addSizeDimension(0, 2).build();
|
||||
Service s2 = Service.Builder.newInstance("s2").setCoord(Coordinate.newInstance(-10, 10)).addSizeDimension(0,3).build();
|
||||
Shipment shipment1 = Shipment.Builder.newInstance("ship1").setPickupCoord(Coordinate.newInstance(-15, 2))
|
||||
.setDeliveryCoord(Coordinate.newInstance(-16, 5)).addSizeDimension(0,10)
|
||||
.setPickupServiceTime(20.).setDeliveryServiceTime(20.).build();
|
||||
.setCoord(Coordinate.newInstance(-10, 1)).addSizeDimension(0, 2)
|
||||
.addRequiredSkill("skill1")
|
||||
.build();
|
||||
Service s2 = Service.Builder.newInstance("s2")
|
||||
.setCoord(Coordinate.newInstance(-10, 10))
|
||||
.addSizeDimension(0,3)
|
||||
.addRequiredSkill("skill2").addRequiredSkill("skill1")
|
||||
.build();
|
||||
Shipment shipment1 = Shipment.Builder.newInstance("ship1")
|
||||
.setPickupCoord(Coordinate.newInstance(-15, 2))
|
||||
.setDeliveryCoord(Coordinate.newInstance(-16, 5))
|
||||
.addSizeDimension(0,10)
|
||||
.setPickupServiceTime(20.)
|
||||
.setDeliveryServiceTime(20.)
|
||||
.addRequiredSkill("skill3")
|
||||
.build();
|
||||
|
||||
Service s3 = Service.Builder.newInstance("s3")
|
||||
.setTimeWindow(TimeWindow.newInstance(10, 20))
|
||||
|
|
@ -95,6 +108,63 @@ public class SolutionAnalyserTest {
|
|||
solution = new VehicleRoutingProblemSolution(Arrays.asList(route1,route2),42);
|
||||
}
|
||||
|
||||
public void buildAnotherScenarioWithOnlyOneVehicleAndWithoutAnyConstraintsBefore(){
|
||||
VehicleType type = VehicleTypeImpl.Builder.newInstance("type").setFixedCost(100.).setCostPerDistance(2.).addCapacityDimension(0, 15).build();
|
||||
|
||||
VehicleImpl vehicle = VehicleImpl.Builder.newInstance("v1").setType(type)
|
||||
.setStartLocationCoordinate(Coordinate.newInstance(-5, 0))
|
||||
.setLatestArrival(150.)
|
||||
.build();
|
||||
|
||||
Pickup s1 = (Pickup) Pickup.Builder.newInstance("s1")
|
||||
.setTimeWindow(TimeWindow.newInstance(10, 20))
|
||||
.setCoord(Coordinate.newInstance(-10, 1))
|
||||
.addSizeDimension(0, 10)
|
||||
.build();
|
||||
Delivery s2 = (Delivery) Delivery.Builder.newInstance("s2")
|
||||
.setCoord(Coordinate.newInstance(-10, 10))
|
||||
.setTimeWindow(TimeWindow.newInstance(10, 20))
|
||||
.addSizeDimension(0, 20)
|
||||
.build();
|
||||
Shipment shipment1 = Shipment.Builder.newInstance("ship1").setPickupCoord(Coordinate.newInstance(-15, 2)).setDeliveryCoord(Coordinate.newInstance(-16, 5))
|
||||
.addSizeDimension(0, 15)
|
||||
.setPickupServiceTime(20.).setDeliveryServiceTime(20.)
|
||||
.setPickupTimeWindow(TimeWindow.newInstance(10,20)).setDeliveryTimeWindow(TimeWindow.newInstance(10,20))
|
||||
.build();
|
||||
|
||||
Pickup s3 = (Pickup) Pickup.Builder.newInstance("s3")
|
||||
.setTimeWindow(TimeWindow.newInstance(10, 20))
|
||||
.setCoord(Coordinate.newInstance(10, 1))
|
||||
.addSizeDimension(0, 10)
|
||||
.build();
|
||||
Delivery s4 = (Delivery) Delivery.Builder.newInstance("s4").setCoord(Coordinate.newInstance(10, 10))
|
||||
.addSizeDimension(0, 20)
|
||||
.setTimeWindow(TimeWindow.newInstance(10, 20))
|
||||
.build();
|
||||
Shipment shipment2 = Shipment.Builder.newInstance("ship2").setPickupCoord(Coordinate.newInstance(15, 2))
|
||||
.setPickupServiceTime(20.).setDeliveryServiceTime(20.)
|
||||
.setDeliveryCoord(Coordinate.newInstance(16, 5))
|
||||
.setPickupTimeWindow(TimeWindow.newInstance(10, 20)).setDeliveryTimeWindow(TimeWindow.newInstance(10, 20))
|
||||
.addSizeDimension(0, 15).build();
|
||||
|
||||
VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance().addVehicle(vehicle)
|
||||
.addJob(s1)
|
||||
.addJob(s2).addJob(shipment1).addJob(s3).addJob(s4).addJob(shipment2).setFleetSize(VehicleRoutingProblem.FleetSize.FINITE);
|
||||
vrpBuilder.setRoutingCost(new ManhattanCosts(vrpBuilder.getLocations()));
|
||||
vrp = vrpBuilder.build();
|
||||
|
||||
VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle).setJobActivityFactory(vrp.getJobActivityFactory())
|
||||
.addPickup(s3)
|
||||
.addPickup(shipment2).addDelivery(shipment2)
|
||||
.addDelivery(s4)
|
||||
.addDelivery(s2)
|
||||
.addPickup(shipment1).addDelivery(shipment1)
|
||||
.addPickup(s1)
|
||||
.build();
|
||||
|
||||
solution = new VehicleRoutingProblemSolution(Arrays.asList(route),300);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructionShouldWork(){
|
||||
SolutionAnalyser analyser = new SolutionAnalyser(vrp,solution, new SolutionAnalyser.DistanceCalculator() {
|
||||
|
|
@ -1689,79 +1759,117 @@ public class SolutionAnalyserTest {
|
|||
assertTrue(violation);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void buildAnotherScenarioWithOnlyOneVehicleAndWithoutAnyConstraintsBefore(){
|
||||
VehicleType type = VehicleTypeImpl.Builder.newInstance("type").setFixedCost(100.).setCostPerDistance(2.).addCapacityDimension(0, 15).build();
|
||||
|
||||
VehicleImpl vehicle = VehicleImpl.Builder.newInstance("v1").setType(type)
|
||||
.setStartLocationCoordinate(Coordinate.newInstance(-5, 0))
|
||||
.setLatestArrival(150.)
|
||||
.build();
|
||||
|
||||
Pickup s1 = (Pickup) Pickup.Builder.newInstance("s1")
|
||||
.setTimeWindow(TimeWindow.newInstance(10, 20))
|
||||
.setCoord(Coordinate.newInstance(-10, 1))
|
||||
.addSizeDimension(0, 10)
|
||||
.build();
|
||||
Delivery s2 = (Delivery) Delivery.Builder.newInstance("s2")
|
||||
.setCoord(Coordinate.newInstance(-10, 10))
|
||||
.setTimeWindow(TimeWindow.newInstance(10, 20))
|
||||
.addSizeDimension(0, 20)
|
||||
.build();
|
||||
Shipment shipment1 = Shipment.Builder.newInstance("ship1").setPickupCoord(Coordinate.newInstance(-15, 2)).setDeliveryCoord(Coordinate.newInstance(-16, 5))
|
||||
.addSizeDimension(0, 15)
|
||||
.setPickupServiceTime(20.).setDeliveryServiceTime(20.)
|
||||
.setPickupTimeWindow(TimeWindow.newInstance(10,20)).setDeliveryTimeWindow(TimeWindow.newInstance(10,20))
|
||||
.build();
|
||||
|
||||
Pickup s3 = (Pickup) Pickup.Builder.newInstance("s3")
|
||||
.setTimeWindow(TimeWindow.newInstance(10, 20))
|
||||
.setCoord(Coordinate.newInstance(10, 1))
|
||||
.addSizeDimension(0, 10)
|
||||
.build();
|
||||
Delivery s4 = (Delivery) Delivery.Builder.newInstance("s4").setCoord(Coordinate.newInstance(10, 10))
|
||||
.addSizeDimension(0, 20)
|
||||
.setTimeWindow(TimeWindow.newInstance(10, 20))
|
||||
.build();
|
||||
Shipment shipment2 = Shipment.Builder.newInstance("ship2").setPickupCoord(Coordinate.newInstance(15, 2))
|
||||
.setPickupServiceTime(20.).setDeliveryServiceTime(20.)
|
||||
.setDeliveryCoord(Coordinate.newInstance(16, 5))
|
||||
.setPickupTimeWindow(TimeWindow.newInstance(10, 20)).setDeliveryTimeWindow(TimeWindow.newInstance(10, 20))
|
||||
.addSizeDimension(0, 15).build();
|
||||
|
||||
VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance().addVehicle(vehicle)
|
||||
.addJob(s1)
|
||||
.addJob(s2).addJob(shipment1).addJob(s3).addJob(s4).addJob(shipment2).setFleetSize(VehicleRoutingProblem.FleetSize.FINITE);
|
||||
vrpBuilder.setRoutingCost(new ManhattanCosts(vrpBuilder.getLocations()));
|
||||
vrp = vrpBuilder.build();
|
||||
|
||||
VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle).setJobActivityFactory(vrp.getJobActivityFactory())
|
||||
.addPickup(s3)
|
||||
.addPickup(shipment2).addDelivery(shipment2)
|
||||
.addDelivery(s4)
|
||||
.addDelivery(s2)
|
||||
.addPickup(shipment1).addDelivery(shipment1)
|
||||
.addPickup(s1)
|
||||
.build();
|
||||
|
||||
solution = new VehicleRoutingProblemSolution(Arrays.asList(route),300);
|
||||
// VehicleRoutingAlgorithmBuilder vraBuilder = new VehicleRoutingAlgorithmBuilder(vrp,"src/test/resources/algorithmConfig.xml");
|
||||
// vraBuilder.addDefaultCostCalculators();
|
||||
//
|
||||
// //adds updater
|
||||
// StateManager stateManager = new StateManager(vrp);
|
||||
// stateManager.updateLoadStates();
|
||||
// stateManager.updateTimeWindowStates();
|
||||
//
|
||||
// //but no constraints to simulate violation
|
||||
// ConstraintManager constraintManager = new ConstraintManager(vrp,stateManager);
|
||||
// vraBuilder.setStateAndConstraintManager(stateManager,constraintManager);
|
||||
//
|
||||
// VehicleRoutingAlgorithm vra = vraBuilder.build();
|
||||
// vra.setMaxIterations(100);
|
||||
// solution = Solutions.bestOf(vra.searchSolutions());
|
||||
|
||||
@Test
|
||||
public void skillViolationOnRoute_shouldWorkWhenViolated(){
|
||||
SolutionAnalyser analyser = new SolutionAnalyser(vrp,solution, new SolutionAnalyser.DistanceCalculator() {
|
||||
@Override
|
||||
public double getDistance(String fromLocationId, String toLocationId) {
|
||||
return vrp.getTransportCosts().getTransportCost(fromLocationId,toLocationId,0.,null,null);
|
||||
}
|
||||
});
|
||||
VehicleRoute route = solution.getRoutes().iterator().next();
|
||||
Boolean violated = analyser.skillConstraintIsViolated(route);
|
||||
assertTrue(violated);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void skillViolationAtStart_shouldWork(){
|
||||
SolutionAnalyser analyser = new SolutionAnalyser(vrp,solution, new SolutionAnalyser.DistanceCalculator() {
|
||||
@Override
|
||||
public double getDistance(String fromLocationId, String toLocationId) {
|
||||
return vrp.getTransportCosts().getTransportCost(fromLocationId,toLocationId,0.,null,null);
|
||||
}
|
||||
});
|
||||
VehicleRoute route = solution.getRoutes().iterator().next();
|
||||
Boolean violated = analyser.skillConstraintIsViolatedAtActivity(route.getStart(), route);
|
||||
assertFalse(violated);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void skillViolationAtAct1_shouldWork(){
|
||||
SolutionAnalyser analyser = new SolutionAnalyser(vrp,solution, new SolutionAnalyser.DistanceCalculator() {
|
||||
@Override
|
||||
public double getDistance(String fromLocationId, String toLocationId) {
|
||||
return vrp.getTransportCosts().getTransportCost(fromLocationId,toLocationId,0.,null,null);
|
||||
}
|
||||
});
|
||||
VehicleRoute route = solution.getRoutes().iterator().next();
|
||||
Boolean violated = analyser.skillConstraintIsViolatedAtActivity(route.getActivities().get(0),route);
|
||||
assertFalse(violated);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void skillViolationAtAct2_shouldWork(){
|
||||
SolutionAnalyser analyser = new SolutionAnalyser(vrp,solution, new SolutionAnalyser.DistanceCalculator() {
|
||||
@Override
|
||||
public double getDistance(String fromLocationId, String toLocationId) {
|
||||
return vrp.getTransportCosts().getTransportCost(fromLocationId,toLocationId,0.,null,null);
|
||||
}
|
||||
});
|
||||
VehicleRoute route = solution.getRoutes().iterator().next();
|
||||
Boolean violated = analyser.skillConstraintIsViolatedAtActivity(route.getActivities().get(1),route);
|
||||
assertTrue(violated);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void skillViolationAtAct3_shouldWork(){
|
||||
SolutionAnalyser analyser = new SolutionAnalyser(vrp,solution, new SolutionAnalyser.DistanceCalculator() {
|
||||
@Override
|
||||
public double getDistance(String fromLocationId, String toLocationId) {
|
||||
return vrp.getTransportCosts().getTransportCost(fromLocationId,toLocationId,0.,null,null);
|
||||
}
|
||||
});
|
||||
VehicleRoute route = solution.getRoutes().iterator().next();
|
||||
Boolean violated = analyser.skillConstraintIsViolatedAtActivity(route.getActivities().get(2),route);
|
||||
assertTrue(violated);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void skillViolationAtAct4_shouldWork(){
|
||||
SolutionAnalyser analyser = new SolutionAnalyser(vrp,solution, new SolutionAnalyser.DistanceCalculator() {
|
||||
@Override
|
||||
public double getDistance(String fromLocationId, String toLocationId) {
|
||||
return vrp.getTransportCosts().getTransportCost(fromLocationId,toLocationId,0.,null,null);
|
||||
}
|
||||
});
|
||||
VehicleRoute route = solution.getRoutes().iterator().next();
|
||||
Boolean violated = analyser.skillConstraintIsViolatedAtActivity(route.getActivities().get(3),route);
|
||||
assertFalse(violated);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void skillViolationAtEnd_shouldWork(){
|
||||
SolutionAnalyser analyser = new SolutionAnalyser(vrp,solution, new SolutionAnalyser.DistanceCalculator() {
|
||||
@Override
|
||||
public double getDistance(String fromLocationId, String toLocationId) {
|
||||
return vrp.getTransportCosts().getTransportCost(fromLocationId,toLocationId,0.,null,null);
|
||||
}
|
||||
});
|
||||
VehicleRoute route = solution.getRoutes().iterator().next();
|
||||
Boolean violated = analyser.skillConstraintIsViolatedAtActivity(route.getEnd(),route);
|
||||
assertFalse(violated);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void skillViolationOnRoute_shouldWorkWhenNotViolated(){
|
||||
SolutionAnalyser analyser = new SolutionAnalyser(vrp,solution, new SolutionAnalyser.DistanceCalculator() {
|
||||
@Override
|
||||
public double getDistance(String fromLocationId, String toLocationId) {
|
||||
return vrp.getTransportCosts().getTransportCost(fromLocationId,toLocationId,0.,null,null);
|
||||
}
|
||||
});
|
||||
|
||||
Iterator<VehicleRoute> iterator = solution.getRoutes().iterator();
|
||||
iterator.next();
|
||||
VehicleRoute route = iterator.next();
|
||||
Boolean violated = analyser.skillConstraintIsViolated(route);
|
||||
assertFalse(violated);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue