/** * */ package vroom.trsp.optimization.alns; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import vroom.common.heuristics.alns.IDestroy; import vroom.common.utilities.math.QuickSelect; import vroom.common.utilities.optimization.IInstance; import vroom.common.utilities.optimization.IParameters; import vroom.trsp.datamodel.TRSPInstance; import vroom.trsp.datamodel.TRSPSolution; import vroom.trsp.datamodel.TRSPTour; import vroom.trsp.datamodel.costDelegates.TRSPDistance; import vroom.trsp.optimization.RemoveMove; /** * <code>DestroyCritical</code> is an implementation of {@link IDestroy} that attempt to remove requests that are the * most costly in the current solution. * <p> * Creation date: Jun 9, 2011 - 1:21:19 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 DestroyCritical extends DestroyTRSP { private final TRSPDistance mDistanceCD; /** the randomization parameter *. */ private final double mRandomization; /** * Getter for the randomization parameter. * * @return the parameter <em>p</em> that control the level of randomization */ public double getRandomization() { return this.mRandomization; } /** * Creates a new <code>DestroyCritical</code> * * @param randomization * the parameter <em>p</em> that control the level of randomization (p≥1, p=1 for no randomization) */ public DestroyCritical(double randomization) { super(); mRandomization = randomization; mDistanceCD = new TRSPDistance(); } /* * (non-Javadoc) * @see vroom.common.heuristics.alns.IALNSComponent#initialize(vroom.common.utilities.optimization.IInstance) */ @Override public void initialize(IInstance instance) { // Do nothing } /* * (non-Javadoc) * @see vroom.common.heuristics.alns.IALNSComponent#getName() */ @Override public String getName() { return "crit"; } /* * (non-Javadoc) * @see vroom.trsp.optimization.alns.DestroyTRSP#doDestroy(vroom.trsp.datamodel.TRSPSolution, * vroom.common.utilities.optimization.IParameters, double) */ @Override protected Set<Integer> doDestroy(TRSPSolution solution, IParameters parameters, List<Integer> removableReq, int numReq) { if (solution.getUnservedCount() == solution.getInstance().getRequestCount()) return Collections.emptySet(); TRSPTour lastModifiedTour = null; Set<Integer> removed = new HashSet<Integer>(); TRSPInstance instance = solution.getInstance(); Evaluation[] evaluations = new Evaluation[instance.getMaxId()]; int removableCount = removableReq.size(); // Evaluate all the removable requests @SuppressWarnings("unchecked") ArrayList<Evaluation>[] tourEval = (ArrayList<Evaluation>[]) new ArrayList<?>[solution.getTourCount()]; for (Integer req : removableReq) { TRSPTour tour = solution.getVisitingTour(req); if (tour == null) throw new IllegalStateException("Request " + req + " is not visited by any tour in solution " + solution); // FIXME Check if it is a good idea to use the distance as proxy evaluations[req] = new Evaluation(req, tour, mDistanceCD.evaluateMove(new RemoveMove(req, tour))); if (tourEval[tour.getTechnicianId()] == null) tourEval[tour.getTechnicianId()] = new ArrayList<Evaluation>(removableReq.size() / 2); tourEval[tour.getTechnicianId()].add(evaluations[req]); } // Sort the candidate list // Collections.sort(candidates); // Remove requests while (removed.size() < numReq && removableCount > 0) { // The k-th most related request will be selected int k = (int) Math.floor(Math.pow(parameters.getRandomStream().nextDouble(), getRandomization()) * removableCount); // Select the k-th most related request Evaluation selectedEval = QuickSelect.quickSelect(evaluations, k + 1, true); selectedEval.eval = Double.NaN; // Mark the evaluation as already removed evaluations[k] = null; lastModifiedTour = selectedEval.tour; removed.add(selectedEval.request); // Remove the request from the tour lastModifiedTour = removeRequest(solution, selectedEval.request); removableCount--; // if (mDistanceCD.isInsertionSeqDependent()) { // Re-evaluate all the requests in the modified tour for (Evaluation e : tourEval[lastModifiedTour.getTechnicianId()]) { if (!Double.isNaN(e.eval)) // Ignore evalutations that were already removed e.eval = mDistanceCD.evaluateMove(new RemoveMove(e.request, e.tour)); } // } else { // // Evaluate the predecessor // int pred = selectedEval.tour.getPred(selectedEval.request); // int succ = selectedEval.tour.getSucc(selectedEval.request); // if (canBeRemoved(solution, pred)) { // RemoveMove rem = new RemoveMove(pred, lastModifiedTour); // double eval = solution.getCostDelegate().evaluateMove(rem); // evaluations[pred].eval = eval; // } // // // Evaluate the successor // if (canBeRemoved(solution, succ)) { // RemoveMove rem = new RemoveMove(succ, lastModifiedTour); // double eval = solution.getCostDelegate().evaluateMove(rem); // evaluations[succ].eval = eval; // } // } } return removed; } @Override public DestroyCritical clone() { return new DestroyCritical(getRandomization()); } @Override public String toString() { return String.format("%s[p:%s]", getName(), getRandomization()); } }