/** * */ package vroom.trsp.optimization.constraints; import vroom.common.utilities.optimization.IConstraint; import vroom.common.utilities.optimization.IMove; import vroom.trsp.datamodel.ITRSPTour; import vroom.trsp.optimization.InsertionMove; import vroom.trsp.optimization.localSearch.TRSPShift.TRSPShiftMove; import vroom.trsp.optimization.localSearch.TRSPTwoOpt.TRSPTwoOptMove; /** * <code>SkillsConstraint</code> is an implementation of {@link IConstraint} that checks the feasibility of a move * regarding skill constraints * <p> * Creation date: Mar 28, 2011 - 10:27:55 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 SkillsConstraint extends TourConstraintBase { @Override public int checkFeasibility(ITRSPTour tour, IMove move) { // We assume that the tour data is updated and coherent if (move instanceof InsertionMove) { boolean feasible = isFeasible(tour, move); return feasible ? 3 : 0; } else { throw new UnsupportedOperationException(String.format("Unsupported move: %s", move)); } } @Override protected FeasibilityState checkFeasibility(ITRSPTour tour) { for (int node : tour) { if (tour.getInstance().isRequest(node) && !tour.getInstance().hasRequiredSkills(tour.getTechnicianId(), node)) return new FeasibilityState(node, "Missing skills to serve request %s (req:%s has:%s)", node, tour.getInstance().getRequest(node).getSkillSet(), tour .getInstance().getFleet().getVehicle(tour.getTechnicianId()) .getSkillSet()); } return new FeasibilityState(); } @Override protected boolean isTwoOptFeasible(ITRSPTour tour, TRSPTwoOptMove move) { // Intra-tour 2-opt: feasibility is maintained return true; } @Override protected boolean isShiftFeasible(ITRSPTour tour, TRSPShiftMove move) { // The shifted request is already in the tour and the technician therefore has the required skills return true; } @Override protected boolean isInsFeasible(ITRSPTour tour, InsertionMove move) { return tour.getInstance().hasRequiredSkills(tour.getTechnicianId(), move.getNodeId()); } }