/**
*
*/
package vroom.trsp.datamodel;
import java.util.Iterator;
/**
* <code>CVRPTWSolutionChecker</code> is a solution checker for {@link TRSPSolution solutions} of a {@link TRSPInstance}
* representing a sCVRPTW instance.
* <p>
* Creation date: Jun 15, 2011 - 9:05:03 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 CVRPTWSolutionChecker extends TRSPSolutionCheckerBase {
public static final CVRPTWSolutionChecker INSTANCE = new CVRPTWSolutionChecker();
@Override
public String checkTour(ITRSPTour tour) {
if (tour.length() == 0)
return "";
StringBuilder err = new StringBuilder();
TRSPInstance instance = tour.getInstance();
Technician tech = instance.getFleet().getVehicle(tour.getTechnicianId());
int cap = tech.getAvailableSpareParts(0);
boolean checkCap = true;
// Tour must start and end at the depot
if (!tour.getInstance().isDepot(tour.getFirstNode())
|| !tour.getInstance().isDepot(tour.getLastNode()))
append(err, "Tour must start and end at the depot");
if (tour.length() < 2)
return err.toString();
double time = tech.getHome().getTimeWindow().startAsDouble();
Iterator<Integer> it = tour.iterator();
// Iterate over the tour
int pred = it.next();
while (it.hasNext()) {
int node = it.next();
time = instance.getTimeWindow(pred).getEarliestStartOfService(time);
time += instance.getServiceTime(pred);
time += instance.getCostDelegate().getTravelTime(pred, node, tech);
// Time window
if (!instance.getTimeWindow(node).isFeasible(time)) {
append(err, "TW violated at node %s (%.1f-%s)", node, time,
instance.getTimeWindow(node));
}
// Load
cap -= tour.getInstance().getSparePartReq(node, 0);
if (checkCap && cap < 0) {
append(err, "Cap violated at node %s (rem: %s)", node, cap);
checkCap = false;
}
pred = node;
}
return err.toString();
}
}