package vroom.trsp.optimization.constraints;
import vroom.common.utilities.optimization.IMove;
import vroom.trsp.datamodel.ITRSPTour;
import vroom.trsp.datamodel.TRSPTour;
import vroom.trsp.optimization.InsertionMove;
import vroom.trsp.optimization.localSearch.TRSPShift.TRSPShiftMove;
import vroom.trsp.optimization.localSearch.TRSPTwoOpt.TRSPTwoOptMove;
import vroom.trsp.util.TRSPLogging;
/**
* <code>HomeConstraint</code> is a constraint that ensure that a {@link TRSPTour} always start and or end where
* expected, i.e. at the technician home.
* <p>
* Creation date: May 4, 2011 - 11:39:30 AM
*
* @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 HomeConstraint extends TourConstraintBase {
@Override
public boolean isFeasible(ITRSPTour tour) {
int first = tour.getFirstNode();
int last = tour.getLastNode();
int home = tour.getInstance().getFleet().getVehicle(tour.getTechnicianId()).getHome()
.getID();
int home2 = tour.getInstance().getHomeDuplicate(home);
return (first == home || first == home2) && (last == home2 || last == home);
}
@Override
protected FeasibilityState checkFeasibility(ITRSPTour tour) {
int first = tour.getFirstNode();
int last = tour.getLastNode();
int home = tour.getInstance().getFleet().getVehicle(tour.getTechnicianId()).getHome()
.getID();
int home2 = tour.getInstance().getHomeDuplicate(home);
String s = null;
int node = ITRSPTour.UNDEFINED;
if (first != home && first != home2) {
s = "Tour does not start at technician home";
node = first;
}
if (last == home2 && last == home) {
if (s != null)
s += " and ";
else
s = "";
s += "Tour does not end at technician home";
node = node == ITRSPTour.UNDEFINED ? last : node;
}
return new FeasibilityState(node, s);
}
@Override
public int checkFeasibility(ITRSPTour tour, IMove move) {
boolean isFeasible = isFeasible(tour, move);
return isFeasible ? 3 : 2;
}
@Override
protected boolean isTwoOptFeasible(ITRSPTour itour, TRSPTwoOptMove move) {
if (!TRSPTour.class.isAssignableFrom(itour.getClass())) {
TRSPLogging.getOptimizationLogger().warn(
String.format("HomeConstraint.isTwoOptFeasible: unsupported tour class (%s)",
itour.getClass()));
return true;
}
TRSPTour tour = (TRSPTour) itour;
return move.getFirst() != tour.getFirstNode()
&& tour.getSucc(move.getSecond()) != tour.getLastNode();
}
@Override
protected boolean isShiftFeasible(ITRSPTour tour, TRSPShiftMove move) {
return move.getNewSucc() != ITRSPTour.UNDEFINED && move.getNewSucc() != tour.getFirstNode();
}
@Override
protected boolean isInsFeasible(ITRSPTour tour, InsertionMove move) {
return move.getInsertionSucc() != ITRSPTour.UNDEFINED
&& move.getInsertionSucc() != tour.getFirstNode();
}
}