/* * */ package vroom.optimization.online.jmsa.vrp.vrpsd; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import umontreal.iro.lecuyer.probdist.DiscreteDistributionInt; import vroom.common.modeling.dataModel.INodeVisit; import vroom.common.modeling.dataModel.attributes.RequestAttributeKey; import vroom.common.modeling.dataModel.attributes.StochasticDemand; import vroom.optimization.online.jmsa.DistinguishedSolutionBase; import vroom.optimization.online.jmsa.IActualRequest; import vroom.optimization.online.jmsa.IDistinguishedSolution; import vroom.optimization.online.jmsa.IScenario; import vroom.optimization.online.jmsa.components.ComponentManager; import vroom.optimization.online.jmsa.components.ConsensusSolutionBuilder; import vroom.optimization.online.jmsa.components.ISolutionBuilderParam; import vroom.optimization.online.jmsa.utils.MSALogging; import vroom.optimization.online.jmsa.vrp.VRPActualRequest; import vroom.optimization.online.jmsa.vrp.VRPConsensusSolutionBuilder; import vroom.optimization.online.jmsa.vrp.VRPScenario; import vroom.optimization.online.jmsa.vrp.VRPScenarioRoute; /** * <code>VRPConsensusSolutionBuilder</code> is a specialization of {@link ConsensusSolutionBuilder} for the VRPSD with a single vehicle. * <p> * Creation date: Sep 8, 2010 - 5:27:57 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 VRPSDConsensus extends VRPConsensusSolutionBuilder { /** * <em>Hack</em> the consensus algorithm to force the visiting of any feasible request before going back to depot */ public static boolean sRepTripHack = false; /** * Creates a new <code>VRPConsensusSolutionBuilder</code> * * @param componentManager */ public VRPSDConsensus(ComponentManager<?, ?> componentManager) { super(componentManager); } @Override public IDistinguishedSolution buildDistinguishedPlan(ISolutionBuilderParam param) { // Special case when vehicle is at the depot, evaluate all // starting/ending nodes of all routes if (getInstance().getShrunkRequest(0).isDepot()) { int nextRequestId = -1; double eval = 0, bestEval = -1, bestCost = 0; Map<Integer, Double> evaluations = new HashMap<Integer, Double>(); INodeVisit depot = getInstance().getShrunkRequest(0); for (IScenario s : getComponentManager().getParentMSAProxy().getScenarioPool()) { s.acquireLock(); VRPScenario scen = (VRPScenario) s; for (VRPScenarioRoute r : scen) { if (r.length() > 2 && (!r.containsShrunkNode() || r.length() > 3)) { // Evaluate the first and last requests int first = r.containsShrunkNode() ? 2 : 1; VRPActualRequest firstReq = (VRPActualRequest) r.getNodeAt(first); VRPActualRequest lastReq = (VRPActualRequest) r.getNodeAt(r.length() - 2); if (isRequestFeasible(firstReq)) { eval = updateEvaluation(evaluations, firstReq.getID()); double cost = scen.getParentInstance().getCost(depot, firstReq); if (eval > bestEval || (eval == bestEval && cost > bestCost)) { bestEval = eval; nextRequestId = firstReq.getID(); bestCost = cost; } } if (isRequestFeasible(lastReq)) { eval = updateEvaluation(evaluations, lastReq.getID()); double cost = scen.getParentInstance().getCost(depot, lastReq); if (eval > bestEval || (eval == bestEval && cost > bestCost)) { bestEval = eval; nextRequestId = lastReq.getID(); } } } } s.releaseLock(); } IActualRequest nextRequest = getInstance().getNodeVisit(nextRequestId); MSALogging.getComponentsLogger().info( "ConsensusSolutionBuilder.buildDistinguishedPlan: best request found : %s - score:%s", nextRequest, bestEval); return new DistinguishedSolutionBase(nextRequest); } else { int nextRequestId = -1; double eval = 0, bestEval = -1; Map<Integer, Double> evaluations = new HashMap<Integer, Double>(); for (IScenario s : getComponentManager().getParentMSAProxy().getScenarioPool()) { s.acquireLock(); VRPSDScenarioUpdater.repairSolution((VRPScenario) s); IActualRequest req = s.getFirstActualRequest(0); if (req != null && isRequestFeasible(req)) { int reqId = req.getID(); eval = updateEvaluation(evaluations, reqId); if (eval >= bestEval) { bestEval = eval; nextRequestId = reqId; } } s.releaseLock(); } VRPActualRequest nextRequest = (VRPActualRequest) getComponentManager().getParentMSAProxy() .getInstance() .getNodeVisit(nextRequestId); // No suitable request was found, force return to the first depot if (nextRequest == null) { nextRequest = new VRPActualRequest(getInstance().getDepotsVisits().iterator().next()); } else if (sRepTripHack && nextRequest.isDepot()) { // Check is there is a "failsafe" request bestEval = 0; VRPActualRequest bestRequest = null; double cap = getInstance().getFleet().getVehicle().getCapacity() - getInstance().getCurrentLoad(0, 0); for (Entry<Integer, Double> cand : evaluations.entrySet()) { if (getInstance().getNodeVisit(cand.getKey()) instanceof VRPSDActualRequest) { VRPSDActualRequest r = (VRPSDActualRequest) getInstance().getNodeVisit(cand.getKey()); StochasticDemand dists = (StochasticDemand) r.getParentRequest().getAttribute( RequestAttributeKey.DEMAND); if (((DiscreteDistributionInt) dists.getDistribution(0)).getXsup() < cap && (bestRequest == null || cand.getValue() > bestEval)) { bestEval = cand.getValue(); bestRequest = r; } } } if (bestRequest != null) { nextRequest = bestRequest; } } MSALogging.getComponentsLogger().info( "ConsensusSolutionBuilder.buildDistinguishedPlan: best request found : %s - score:%s", nextRequest, bestEval); return new DistinguishedSolutionBase(nextRequest); } } }