Soft Activity Constraint not working
shashikant777 opened this issue · 1 comments
Soft Activity Constraint not working not working for me.
I want to add a soft constraint for distance. If distance for a route is greater than a value(in this case 40000 meter). I expected result that it should use two vehicles if distance for a route is more than this value. It does not work no matter how much I increase penalty cost.
My code is-
DistanceConstraintService class
public class DistanceConstraintService {
public static class DistanceUpdater implements StateUpdater, ActivityVisitor {
private final StateManager stateManager;
private final VehicleRoutingTransportCostsMatrix costMatrix;
private final StateId distanceStateId;
private VehicleRoute vehicleRoute;
private double distance = 0.;
private TourActivity prevAct;
public DistanceUpdater(StateId distanceStateId, StateManager stateManager, VehicleRoutingTransportCostsMatrix transportCosts) { //head of development - upcoming release (v1.4)
this.costMatrix = transportCosts;
this.stateManager = stateManager;
this.distanceStateId = distanceStateId;
}
@Override
public void begin(VehicleRoute vehicleRoute) {
distance = 0.;
prevAct = vehicleRoute.getStart();
this.vehicleRoute = vehicleRoute;
}
@Override
public void visit(TourActivity tourActivity) {
distance += getDistance(prevAct, tourActivity);
prevAct = tourActivity;
}
@Override
public void finish() {
distance += getDistance(prevAct, vehicleRoute.getEnd());
stateManager.putRouteState(vehicleRoute, distanceStateId, distance);
}
double getDistance(TourActivity from, TourActivity to) {
return costMatrix.getDistance(from.getLocation().getId(), to.getLocation().getId());
}
}
public static class DistanceConstraint implements SoftActivityConstraint{
private final StateManager stateManager;
private final double maxDistance;
private final StateId distanceStateId;
private final VehicleRoutingTransportCostsMatrix costMatrix;
public DistanceConstraint(double maxDistance, StateId distanceStateId, StateManager stateManager, VehicleRoutingTransportCostsMatrix transportCosts) { //head of development - upcoming release (v1.4)
this.maxDistance = maxDistance;
this.stateManager = stateManager;
this.distanceStateId = distanceStateId;
this.costMatrix = transportCosts;
}
public double getCosts(JobInsertionContext context, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double v) {
double additionalDistance = getDistance(prevAct, newAct) + getDistance(newAct, nextAct) - getDistance(prevAct, nextAct);
Double routeDistance = stateManager.getRouteState(context.getRoute(), distanceStateId, Double.class);
if (routeDistance == null) routeDistance = 0d;
double newRouteDistance = routeDistance + additionalDistance;
if (newRouteDistance > maxDistance) {
return 1000;
}
return 1;
}
double getDistance(TourActivity from, TourActivity to) {
return this.costMatrix.getDistance(from.getLocation().getId(), to.getLocation().getId());
}
}
Base class -
VehicleRoutingTransportCostsMatrix costMatrix = costMatrixBuilder.build();
VehicleRoutingProblem vrp;
if(!isPickupDelivery){
vrp = VehicleRoutingProblem.Builder.newInstance().setFleetSize(VehicleRoutingProblem.FleetSize.FINITE).setRoutingCost(costMatrix)
.addAllVehicles(vehicles).addAllJobs(jobs).build();
}else{
vrp = VehicleRoutingProblem.Builder.newInstance().setFleetSize(VehicleRoutingProblem.FleetSize.FINITE).setRoutingCost(costMatrix)
.addAllVehicles(vehicles).addAllJobs(shipments).build();
}
StateManager stateManager = new StateManager(vrp); //head of development - upcoming release (v1.4)
StateId distanceStateId = stateManager.createStateId("distance"); //head of development - upcoming release (v1.4)
stateManager.addStateUpdater(new DistanceConstraintService.DistanceUpdater(distanceStateId, stateManager, costMatrix));
ConstraintManager constraintManager = new ConstraintManager(vrp, stateManager);
constraintManager.addConstraint(new DistanceConstraintService.DistanceConstraint(40000, distanceStateId, stateManager, costMatrix));
VehicleRoutingAlgorithm vra;
vra = Jsprit.Builder.newInstance(vrp).setStateAndConstraintManager(stateManager,constraintManager).setProperty(Jsprit.Parameter.THREADS, jspritThreadCount.toString()).setProperty(Jsprit.Parameter.FIXED_COST_PARAM,"2.0").buildAlgorithm();
VariationCoefficientTermination prematureTermination = new VariationCoefficientTermination(40, 0.001);
vra.setPrematureAlgorithmTermination(prematureTermination);
vra.addListener(prematureTermination);
TimeTermination timeTermination = new TimeTermination(78000); // 13 minutes
vra.addTerminationCriterion(timeTermination);
vra.addListener(timeTermination);
Collection<VehicleRoutingProblemSolution> solutions = vra.searchSolutions();
SolutionPrinter.print(Solutions.bestOf(solutions));
VehicleRoutingProblemSolution solution = new SelectBest().selectSolution(solutions);
Thanks for your question. Would you mind to post your problem here: https://discuss.graphhopper.com/c/jsprit/9
Thanks a lot!