/** * */ package vroom.trsp.optimization.mpa; import static vroom.trsp.util.TRSPGlobalParameters.ALNS_MAX_IT; import static vroom.trsp.util.TRSPGlobalParameters.ALNS_MAX_TIME; import static vroom.trsp.util.TRSPGlobalParameters.ALNS_SA_ALPHA; import static vroom.trsp.util.TRSPGlobalParameters.ALNS_SA_P; import static vroom.trsp.util.TRSPGlobalParameters.ALNS_SA_W; import vroom.common.heuristics.alns.ALNSGlobalParameters; import vroom.common.heuristics.alns.AdaptiveLargeNeighborhoodSearch; import vroom.common.heuristics.alns.IDestroy; import vroom.common.heuristics.alns.IRepair; import vroom.common.heuristics.utils.HeuristicsLogging; import vroom.common.heuristics.vns.VariableNeighborhoodSearch; import vroom.common.heuristics.vns.VariableNeighborhoodSearch.VNSVariant; import vroom.common.utilities.Utilities; import vroom.common.utilities.optimization.IComponentHandler; import vroom.common.utilities.optimization.IParameters.LSStrategy; import vroom.common.utilities.optimization.OptimizationSense; import vroom.common.utilities.optimization.RndComponentHanlder; import vroom.common.utilities.optimization.SAAcceptanceCriterion; import vroom.common.utilities.optimization.SimpleParameters; import vroom.common.utilities.optimization.SimpleStoppingCriterion; import vroom.optimization.online.jmsa.components.ComponentManager; import vroom.optimization.online.jmsa.components.ScenarioOptimizerBase; import vroom.optimization.online.jmsa.components.ScenarioOptimizerParam; import vroom.trsp.ALNSSCSolver; import vroom.trsp.MPASolver; import vroom.trsp.datamodel.TRSPInstance; import vroom.trsp.datamodel.TRSPSolution; import vroom.trsp.datamodel.TRSPSolutionChecker; import vroom.trsp.optimization.alns.RepairRndRegret; import vroom.trsp.optimization.constructive.TRSPConstructiveHeuristic; import vroom.trsp.optimization.constructive.TRSPRepairConsHeur; import vroom.trsp.optimization.localSearch.TRSPCompositeNeighborhood; import vroom.trsp.optimization.localSearch.TRSPRelocate; import vroom.trsp.optimization.localSearch.TRSPTwoOpt; import vroom.trsp.optimization.localSearch.TRSPTwoOpt.TRSPTwoOptMove; import vroom.trsp.util.TRSPGlobalParameters; import vroom.trsp.util.TRSPLogging; /** * <code>DTRSPScenarioOptimizer</code> is a scenario optimizer for the D-TRSP * <p> * Creation date: Feb 7, 2012 - 11:01:36 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 DTRSPScenarioOptimizer extends ScenarioOptimizerBase<DTRSPSolution> { /** A flag to toggle mSolution checking after each move */ private static boolean sCheckSolutionAfterMove = false; /** * Setter for <code>checkSolutionAfterMove</code> * * @param checkSolutionAfterMove * the checkSolutionAfterMove to set */ public static void setCheckSolutionAfterMove(boolean checkSolutionAfterMove) { sCheckSolutionAfterMove = checkSolutionAfterMove; if (sCheckSolutionAfterMove) { HeuristicsLogging .getNeighborhoodsLogger() .warn("DTRSPScenarioOptimizer.CheckSolutionAfterMove is set to true, set to false to increase performance (set in %s)", Thread.currentThread().getStackTrace()[2]); } } private final MPASolver mSolver; /** * Return a reference to the parent {@link MPASolver} * * @return a reference to the parent {@link MPASolver} */ protected MPASolver getSolver() { return mSolver; } private final TRSPConstructiveHeuristic mConsHeur; private AdaptiveLargeNeighborhoodSearch<TRSPSolution> mALNS; private SimpleParameters mALNSParams; private VariableNeighborhoodSearch<TRSPSolution> mVNS; private SimpleParameters mVNSParams; private TRSPInstance getInstance() { return (TRSPInstance) getMSAProxy().getInstance(); } public DTRSPScenarioOptimizer(ComponentManager<DTRSPSolution, ?> componentManager) { super(componentManager); mSolver = getMSAProxy().getParameters().get(MPASolver.TRSP_MPA_SOLVER); // Setup the constructive heuristic // ---------------------------------------- mConsHeur = new TRSPRepairConsHeur(getInstance(), getSolver().getParams(), getSolver() .getTourCtrHandler(), null, new RepairRndRegret(getSolver().getParams(), getSolver().getTourCtrHandler(), 2, getMSAProxy().getOptimizationRandomStream())); // ---------------------------------------- setupALNS(); setupVNS(); } private void setupALNS() { // Setup the LNS // ---------------------------------------- IComponentHandler<IDestroy<TRSPSolution>> destroyComponents = new RndComponentHanlder<IDestroy<TRSPSolution>>( getSolver().getParams().getALNSRndStream(), ALNSSCSolver.newDestroySet(getSolver() .getParams()), false); IComponentHandler<IRepair<TRSPSolution>> repairComponents = new RndComponentHanlder<IRepair<TRSPSolution>>( getSolver().getParams().getALNSRndStream(), ALNSSCSolver.newRepairSet(getSolver() .getTourCtrHandler(), getSolver().getParams()), false); // IComponentHandler<IDestroy<TRSPSolution>> destroyComponents = new // RndComponentHanlder<IDestroy<TRSPSolution>>( // getSolver().getParams().getALNSRndStream(), // Collections.<IDestroy<TRSPSolution>> singleton(new DestroyRandom()), false); // IComponentHandler<IRepair<TRSPSolution>> repairComponents = new RndComponentHanlder<IRepair<TRSPSolution>>( // getSolver().getParams().getALNSRndStream(), // Collections.<IRepair<TRSPSolution>> singleton(new RepairRegret(getSolver().getParams(), getSolver() // .getSolCtrHandler().getTourConstraintHandler(), 1, false)), false); ALNSGlobalParameters alnsParams = new ALNSGlobalParameters(); alnsParams.set(ALNSGlobalParameters.DESTROY_SIZE_RANGE, new double[] { getSolver().getParams().get(TRSPGlobalParameters.ALNS_XI_MIN), getSolver().getParams().get(TRSPGlobalParameters.ALNS_XI_MAX) }); mALNS = new AdaptiveLargeNeighborhoodSearch<TRSPSolution>(OptimizationSense.MINIMIZATION, getSolver().getParams().getALNSRndStream(), alnsParams, destroyComponents, repairComponents); mALNSParams = new SimpleParameters(LSStrategy.DET_BEST_IMPROVEMENT, getSolver().getParams() .get(ALNS_MAX_TIME), getSolver().getParams().get(ALNS_MAX_IT), getSolver() .getParams().getALNSRndStream()); // ---------------------------------------- } @SuppressWarnings("unchecked") private void setupVNS() { mVNS = VariableNeighborhoodSearch.newVNS(VNSVariant.VND, OptimizationSense.MINIMIZATION, null, getMSAProxy().getOptimizationRandomStream(), // new TRSPRelocate(getSolver().getSolCtrHandler(), getSolver().getTourCtrHandler()),// , new TRSPCompositeNeighborhood<TRSPTwoOptMove, TRSPTwoOpt>(getSolver() .getSolCtrHandler(), new TRSPTwoOpt(getSolver().getTourCtrHandler())) // ); mVNSParams = new SimpleParameters(LSStrategy.DET_BEST_IMPROVEMENT, getSolver().getParams() .get(ALNS_MAX_TIME), getSolver().getParams().get(ALNS_MAX_IT), getSolver() .getParams().getALNSRndStream()); } private void optimize(DTRSPSolution scenario, int maxIt, int maxTime) { // if (scenario.getNonImprovingCount() > 5) optimizeALNS(scenario, maxIt, maxTime); // else // optimizeVNS(scenario, maxIt, maxTime); } private void optimizeALNS(DTRSPSolution scenario, int maxIt, int maxTime) { mALNSParams.setAcceptanceCriterion(new SAAcceptanceCriterion( OptimizationSense.MINIMIZATION, getSolver().getParams().getALNSRndStream(), scenario.getObjectiveValue(), getSolver().getParams().get(ALNS_SA_W), getSolver() .getParams().get(ALNS_SA_P), mALNSParams.getMaxIterations(), getSolver() .getParams().get(ALNS_SA_ALPHA), true)); mALNSParams.setStoppingCriterion(getMSAProxy().newStoppingCriterion( new SimpleStoppingCriterion(maxTime, maxIt), true)); TRSPSolution sol = mALNS.localSearch(getInstance(), scenario, mALNSParams); checkScenario(sol, "optimize-?"); scenario.importSolution(sol); } private void optimizeVNS(DTRSPSolution scenario, int maxIt, int maxTime) { mVNSParams.setStoppingCriterion(getMSAProxy().newStoppingCriterion( new SimpleStoppingCriterion(maxTime, maxIt), true)); TRSPSolution sol = mVNS.localSearch(getInstance(), scenario, mVNSParams); scenario.importSolution(sol); } @Override public boolean initialize(DTRSPSolution scenario, ScenarioOptimizerParam params) { mConsHeur.initializeSolution(scenario); boolean initOk = checkScenario(scenario, "initialize-init"); scenario.setCostDelegate(getSolver().getParams().newALNSCostDelegate( getSolver().getInstance().getSimulator().getCurrentSolution())); scenario.getCostDelegate().setPenalize(true); scenario.getCostDelegate().setUnservedPenalty( getSolver().getInstance().getSimulator().getCurrentSolution(), getSolver().getParams().get(TRSPGlobalParameters.ALNS_OBJ_GAMMA) * 100 / scenario.getInstance().getReleasedRequests().size()); if (initOk) { optimize(scenario, 1000, params.getMaxTime()); return checkScenario(scenario, "initialize"); } else return false; } @Override public boolean optimize(DTRSPSolution scenario, ScenarioOptimizerParam params) { double cost = scenario.getObjectiveValue(); scenario.getCostDelegate().setUnservedPenalty( scenario, getSolver().getParams().get(TRSPGlobalParameters.ALNS_OBJ_GAMMA) * 100 / scenario.getInstance().getReleasedRequests().size()); checkScenario(scenario, "optimize-init"); optimize(scenario, 5000, params.getMaxTimePerScen()); if (scenario.getObjectiveValue() < cost) scenario.resetNonImprovingCount(); else scenario.incrementNonImprovingCount(); return checkScenario(scenario, "optimize") && scenario.getUnservedCount() == 0; } private final static TRSPSolutionChecker SOL_CHECK = new TRSPSolutionChecker(false); /** * Check a scenario coherence (only is {@link #setCheckSolutionAfterMove(boolean) CheckSolutionAfterMove} is set to * {@code true} * * @param solution * @param context * @return {@code true} if the scenario is coherent, {@code false} if it has problems */ private boolean checkScenario(TRSPSolution solution, String context) { if (sCheckSolutionAfterMove) { if (solution.getUnservedCount() > 0 && !context.endsWith("-init")) TRSPLogging .getOptimizationLogger() .warn("DTRSPScenarioOptimizer.%s: incoherencies detected in scenario %s unserved requests %s", context, solution.hashCode(), Utilities.toShortString(solution.getUnservedRequests())); String err = SOL_CHECK.checkSolution(solution); if (err.length() > 0) { TRSPLogging.getOptimizationLogger().warn( "DTRSPScenarioOptimizer.%s: incoherencies detected in scenario %s (%s)", context, solution.hashCode(), err); return false; } } return true; } }