package vroom.trsp.optimization.constraints; import vroom.common.utilities.Constants; import vroom.common.utilities.optimization.IMove; import vroom.trsp.datamodel.ITRSPTour; import vroom.trsp.datamodel.TRSPTour; import vroom.trsp.datamodel.costDelegates.TRSPWorkingTime; import vroom.trsp.optimization.InsertionMove; import vroom.trsp.optimization.localSearch.TRSPShift.TRSPShiftMove; import vroom.trsp.optimization.localSearch.TRSPTwoOpt.TRSPTwoOptMove; /** * The class <code>MaxDurationConstraint</code> implements a constraint enforcing a maximum duration for a tour. * <p> * Creation date: Mar 22, 2012 - 2:17:46 PM * * @author Victor Pillac, <a href="http://uniandes.edu.co">Universidad de Los Andes</a>-<a * href="http://copa.uniandes.edu.co">Copa</a> <a href="http://www.emn.fr">Ecole des Mines de Nantes</a>-<a * href="http://www.irccyn.ec-nantes.fr/irccyn/d/en/equipes/Slp">SLP</a> * @version 1.0 */ public class MaxDurationConstraint extends TourConstraintBase { private final double mMaxDuration; private final TRSPWorkingTime mWTDelegate; /** * Creates a new <code>MaxDurationConstraint</code> * * @param maxDuration */ public MaxDurationConstraint(double maxDuration) { mMaxDuration = maxDuration; mWTDelegate = new TRSPWorkingTime(); } @Override public int firstInfeasibleNode(ITRSPTour tour) { if (TRSPTour.class.isAssignableFrom(tour.getClass())) { TRSPTour t = (TRSPTour) tour; for (int i : t) { if (t.getEarliestDepartureTime(i) > mMaxDuration) return i; } return ITRSPTour.UNDEFINED; } else { return isFeasible(tour) ? ITRSPTour.UNDEFINED : tour.getFirstNode(); } } @Override protected FeasibilityState checkFeasibility(ITRSPTour tour) { double excess = mMaxDuration - mWTDelegate.evaluateTour(tour, false); if (Constants.isStrictlyPositive(excess)) return new FeasibilityState(tour.getFirstNode(), "Maximum duration exceeded by %.3f", excess); else return new FeasibilityState(); } @Override protected boolean isTwoOptFeasible(ITRSPTour tour, TRSPTwoOptMove move) { throw new UnsupportedOperationException(); } @Override protected boolean isShiftFeasible(ITRSPTour tour, TRSPShiftMove move) { throw new UnsupportedOperationException(); } @Override protected boolean isInsFeasible(ITRSPTour tour, InsertionMove move) { double delta = mWTDelegate.evaluateInsMove(move); double duration = mWTDelegate.evaluateTour(tour, false); return Constants.isLowerThan(duration - delta, mMaxDuration); } @Override public int checkFeasibility(ITRSPTour tour, IMove move) { return isFeasible(tour, move) ? 3 : 2; } }