/** * */ package vroom.common.heuristics.vns.benchmarking; import java.io.File; import java.io.IOException; import java.util.Collections; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Set; import umontreal.iro.lecuyer.rng.MRG32k3a; import vroom.common.heuristics.ConstraintHandler; import vroom.common.heuristics.GenericNeighborhood; import vroom.common.heuristics.GenericNeighborhoodHandler; import vroom.common.heuristics.GenericNeighborhoodHandler.Strategy; import vroom.common.heuristics.cw.CWParameters; import vroom.common.heuristics.cw.algorithms.BasicSavingsHeuristic; import vroom.common.heuristics.cw.kernel.ClarkeAndWrightHeuristic; import vroom.common.heuristics.vns.VariableNeighborhoodSearch; import vroom.common.heuristics.vrp.OrOptNeighborhood; import vroom.common.heuristics.vrp.StringExchangeNeighborhood; import vroom.common.heuristics.vrp.SwapNeighborhood; import vroom.common.heuristics.vrp.TwoOptNeighborhood; import vroom.common.heuristics.vrp.VRPParameters; import vroom.common.heuristics.vrp.constraints.CapacityConstraint; import vroom.common.modeling.dataModel.ListRoute.ArrayListRoute; import vroom.common.modeling.dataModel.INodeVisit; import vroom.common.modeling.dataModel.IRoute; import vroom.common.modeling.dataModel.IVRPInstance; import vroom.common.modeling.dataModel.IVRPRequest; import vroom.common.modeling.dataModel.Solution; import vroom.common.modeling.util.DefaultSolutionFactory; import vroom.common.modeling.util.SolutionChecker; import vroom.common.utilities.Stopwatch; import vroom.common.utilities.dataModel.ObjectWithIdComparator; import vroom.common.utilities.logging.LoggerHelper; import vroom.common.utilities.logging.Logging; import vroom.common.utilities.optimization.INeighborhood; import vroom.common.utilities.optimization.OptimizationSense; /** * <code>VNSRun</code> * <p> * Creation date: Jul 8, 2010 - 4:54:08 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 VNSRun implements Runnable { protected final static LoggerHelper LOGGER = LoggerHelper.getLogger(VNSRun.class .getSimpleName()); private final IVRPInstance mInstance; private final VariableNeighborhoodSearch<Solution<ArrayListRoute>> mVNS; private Solution<ArrayListRoute> mSolution; private final ConstraintHandler<Solution<ArrayListRoute>> mCtrHandler; /** * Setter for <code>mSolution</code> * * @param mSolution * the mSolution to set */ public void setSolution(Solution<ArrayListRoute> solution) { mSolution = solution; } /** * Getter for <code>mSolution</code> * * @return the mSolution */ public Solution<ArrayListRoute> getSolution() { return mSolution; } /** the global timer **/ private final Stopwatch mGlobalTimer; /** * Getter for the global timer * * @return the global timer */ public Stopwatch getGlobalTimer() { return mGlobalTimer; } /** the vns timer **/ private final Stopwatch mVNSTimer; /** * Getter for the vns timer * * @return the vns timer */ public Stopwatch getVNSTimer() { return mVNSTimer; } /** vns parameters **/ private final VRPParameters mVNSParameters; /** * Getter for the vns parameters * * @return vns parameters */ public VRPParameters getVNSParameters() { return mVNSParameters; } /** * Creates a new <code>VNSBenchmark</code> * * @param instance * @param vns */ public VNSRun(IVRPInstance instance, VariableNeighborhoodSearch<Solution<ArrayListRoute>> vns, ConstraintHandler<Solution<ArrayListRoute>> ctrHandlr, VRPParameters params) { mInstance = instance; mVNS = vns; mCtrHandler = ctrHandlr; mVNSParameters = params; mGlobalTimer = new Stopwatch(); mVNSTimer = new Stopwatch(); } /* * (non-Javadoc) * @see java.lang.Runnable#run() */ @Override public void run() { LOGGER.info("#########################"); LOGGER.info("Instance: %s", mInstance.getName()); LOGGER.debug(" Detail"); LOGGER.debug(" Fleet \t : %s", mInstance.getFleet()); LOGGER.debug(" %s Depots \t : %s", mInstance.getDepotCount(), mInstance.getDepotsVisits()); List<IVRPRequest> reqs = mInstance.getRequests(); Collections.sort(reqs, new ObjectWithIdComparator()); LOGGER.debug(" %s Requests \t : %s", mInstance.getRequestCount(), reqs); mGlobalTimer.start(); if (getSolution() == null) { throw new IllegalStateException("Set the initial solution first"); } // mCW.initialize(mInstance); // mCW.run(); // Solution<ArrayListRoute> solution = mCW.getSolution(); // // setSolution(solution); LOGGER.info("Initial solution:"); LOGGER.info(getSolution()); mVNSTimer.start(); setSolution(mVNS.localSearch(mInstance, mSolution, mVNSParameters)); mGlobalTimer.stop(); mVNSTimer.stop(); LOGGER.info("VNS finished in %sms", mVNSTimer.readTimeMS()); LOGGER.info("Solution"); LOGGER.info(getSolution()); Set<IVRPRequest> unservedReq = new HashSet<IVRPRequest>(mInstance.getRequests()); for (ArrayListRoute r : getSolution()) { for (INodeVisit n : r) { if (!n.isDepot()) { if (!unservedReq.remove(n.getParentRequest())) { LOGGER.warn("%s was not in the set of requests", n); } } } } if (!unservedReq.isEmpty()) { LOGGER.warn("There are unserved requests: %s", unservedReq); } String err = SolutionChecker.checkSolution(mSolution, true, true, true); if (err != null) { LOGGER.warn("Inconsistent costs/loads:"); LOGGER.warn(err); LOGGER.warn("Corrected Solution"); LOGGER.warn(getSolution()); } err = mCtrHandler.getInfeasibilityExplanation(getSolution()); if (err != null) { LOGGER.error("Solution is infeasible:"); LOGGER.error(err); } else { LOGGER.info("Solution is feasible"); } for (IRoute<?> route : getSolution()) { if (!route.getFirstNode().isDepot() || !route.getLastNode().isDepot()) { LOGGER.error("Route %s does not start/end with a depot (%s)", route.hashCode(), route); } } LOGGER.info("#########################"); } @SuppressWarnings("rawtypes") public static void main(String[] args) { Logging.setupRootLogger(LoggerHelper.LEVEL_DEBUG, LoggerHelper.LEVEL_DEBUG, false); GenericNeighborhood.setCheckSolutionAfterMove(false); File instanceFile = VNSBenchmark.INSTANCES_FILES.iterator().next(); try { IVRPInstance instance = VNSBenchmark.INSTANCE_READER.readInstance(instanceFile); // Constraint Handler ConstraintHandler<Solution<ArrayListRoute>> ctrHandler = new ConstraintHandler<Solution<ArrayListRoute>>(); ctrHandler.addConstraint(new CapacityConstraint<Solution<ArrayListRoute>>()); // Neighborhoods LinkedList<INeighborhood<Solution<ArrayListRoute>, ?>> neighborhoods = new LinkedList<INeighborhood<Solution<ArrayListRoute>, ?>>(); // swap neighborhoods.add(new SwapNeighborhood<Solution<ArrayListRoute>>(ctrHandler)); // 2-opt neighborhoods.add(new TwoOptNeighborhood<Solution<ArrayListRoute>>(ctrHandler)); // Or-opt neighborhoods.add(new OrOptNeighborhood<Solution<ArrayListRoute>>(ctrHandler)); // string-exchange neighborhoods.add(new StringExchangeNeighborhood<Solution<ArrayListRoute>>(ctrHandler)); ((StringExchangeNeighborhood<?>) neighborhoods.getLast()).setMaxLength(3); // Collections.reverse(neighborhoods); // VNS VariableNeighborhoodSearch<Solution<ArrayListRoute>> vns = new VariableNeighborhoodSearch<Solution<ArrayListRoute>>( OptimizationSense.MINIMIZATION, null, neighborhoods, false, new MRG32k3a()); // VNS Params VRPParameters params = new VRPParameters(Long.MAX_VALUE, Integer.MAX_VALUE, false, false, null); ((GenericNeighborhoodHandler) vns.getNeighHandler()).setStrategy(Strategy.SEQUENTIAL); VNSRun run = new VNSRun(instance, vns, ctrHandler, params); CWParameters cwParams = new CWParameters(); cwParams.set(CWParameters.SOLUTION_FACTORY_CLASS, DefaultSolutionFactory.class); cwParams.set(CWParameters.RANDOM_SEED, 0l); ClarkeAndWrightHeuristic<Solution<ArrayListRoute>> cw = new ClarkeAndWrightHeuristic<Solution<ArrayListRoute>>( cwParams, BasicSavingsHeuristic.class, ctrHandler); cw.initialize(instance); Stopwatch t = new Stopwatch(); t.start(); cw.run(); t.stop(); LOGGER.info("CW run in : %sms", t.readTimeMS()); LOGGER.info("Initial solution : %s", cw.getSolution()); run.setSolution(cw.getSolution()); run.run(); LOGGER.info("VNS terminated in: %sms", run.getVNSTimer().readTimeMS()); LOGGER.info("Solution : %s", run.getSolution()); LOGGER.info("Neighborhoods : %s", vns.getNeighHandler()); } catch (IOException e) { e.printStackTrace(); } } }