graphhopper/jsprit

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!