I am trying to do a hardConstraint based on profit of service and cost of route ((cost / profit) * 100) the objective is provide a maxPercentLoss parameter and avoid some deliveries.The problem is if first delivery is less then parameter it dont continue to next.
public class LossConstraint implements HardActivityConstraint {
private final double maxPercentLoss; private final StateManager stateManager; private final VehicleRoutingActivityCosts activityCost; private final VehicleRoutingTransportCosts transportCost; private final Capacity defaultValue;
public LossConstraint(double maxPercentLoss, StateManager stateManager, VehicleRoutingActivityCosts activityCost, VehicleRoutingTransportCosts transportCost) { this.maxPercentLoss = maxPercentLoss; this.stateManager = stateManager; this.activityCost = activityCost; this.transportCost = transportCost; this.defaultValue = Capacity.Builder.newInstance().build(); }
@Override public ConstraintsStatus fulfilled(JobInsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) { double profit = getProfits(iFacts); double cost = getCosts(iFacts, prevAct, newAct, nextAct); double percentRoute = profit <= 0 ? 0 : ((cost / profit) * 100); if (percentRoute > maxPercentLoss) { return HardActivityConstraint.ConstraintsStatus.NOT_FULFILLED; } return HardActivityConstraint.ConstraintsStatus.FULFILLED; }
private double getProfits(JobInsertionContext insertionContext) { Capacity loadAtEnd = stateManager.getRouteState(insertionContext.getRoute(), InternalStates.LOAD_AT_END, Capacity.class); loadAtEnd = firstNonNull(loadAtEnd, defaultValue); double profit = loadAtEnd.get(JspritUtil.PROFIT_INDEX); profit += insertionContext.getJob().getSize().get(JspritUtil.PROFIT_INDEX); return profit; }
private double getCosts(JobInsertionContext iFacts, TourActivity prevAct, TourActivity act, TourActivity nextAct) { Double costs = stateManager.getRouteState(iFacts.getRoute(), InternalStates.COSTS, Double.class); costs = firstNonNull(costs, 0.0); costs += getCostsBetween(iFacts, prevAct, act) + getCostsBetween(iFacts, act, nextAct) - getCostsBetween(iFacts, prevAct, nextAct); return costs; }
private double getCostsBetween(JobInsertionContext iFacts, TourActivity prevAct, TourActivity act) { double costs = transportCost.getTransportCost(prevAct.getLocation(), act.getLocation(), prevAct.getEndTime(), iFacts.getNewDriver(), iFacts.getNewVehicle()); costs += activityCost.getActivityCost(act, act.getArrTime(), iFacts.getNewDriver(), iFacts.getNewVehicle()); return costs; }
}