/** * */ package vroom.trsp.optimization.alns; import java.util.Arrays; import java.util.Set; import vroom.common.heuristics.alns.IDestroy; import vroom.common.utilities.optimization.IInstance; import vroom.trsp.datamodel.TRSPInstance; import vroom.trsp.datamodel.TRSPRequest; import vroom.trsp.datamodel.TRSPSolution; /** * <code>DestroyStaticRelated</code> is an implementation of {@link IDestroy} based on a static relatedness metric. * <p> * Given two requests <code>i</code> and <code>j</code> we define the static relatedness * <code>r<sub>ij</sub><sup>s</sup></code> * </p> * <p> * Creation date: May 26, 2011 - 11:23:41 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 DestroyStaticRelated extends DestroyRelated { private Relatedness[][] mRelatednessMatrix; private final double mGammaD; private final double mGammaT; private final double mGammaS; /** * Creates a new <code>DestroyStaticRelated</code> * * @param randomization * the parameter <em>p</em> that control the level of randomization * @param gammaD * the weight of the distance component * @param gammaT * the weight of the time windows end component * @param gammaS * the weight of the skill compatibility component */ public DestroyStaticRelated(double randomization, double gammaD, double gammaT, double gammaS) { super(randomization); mGammaD = gammaD; mGammaT = gammaT; mGammaS = gammaS; } @Override public void initialize(IInstance instance) { TRSPInstance ins = (TRSPInstance) instance; mRelatednessMatrix = new Relatedness[ins.getMaxId()][]; // Scaling constants double Mc = Double.NEGATIVE_INFINITY, Mt = Double.NEGATIVE_INFINITY; double[][] twd = new double[ins.getMaxId()][ins.getMaxId()]; for (TRSPRequest i : ins.getRequests()) { mRelatednessMatrix[i.getID()] = new Relatedness[ins.getMaxId()]; for (TRSPRequest j : ins.getRequests()) { double dij = ins.getCostDelegate().getDistance(i.getID(), j.getID()); if (dij > Mc) Mc = dij; twd[i.getID()][j.getID()] = Math.abs(ins.getTimeWindow(i.getID()).endAsDouble() - ins.getTimeWindow(j.getID()).endAsDouble()); if (twd[i.getID()][j.getID()] > Mt) Mt = twd[i.getID()][j.getID()]; } } if (Mc == 0) Mc = 1; if (Mt == 0) Mt = 1; // Evaluate the relatedness matrix for (TRSPRequest i : ins.getRequests()) { for (TRSPRequest j : ins.getRequests()) { if (i == j) continue; // Distance component double dij = ins.getCostDelegate().getDistance(i.getID(), j.getID()) / Mc; // Time component double tij = twd[i.getID()][j.getID()] / Mt; // Compatible technician component Set<Integer> Ki = ins.getCompatibleTechnicians(i.getID()); Set<Integer> Kj = ins.getCompatibleTechnicians(j.getID()); double Ms = Math.min(Ki.size(), Kj.size()); int inter = 0; for (int t : Ki) if (Kj.contains(t)) inter++; double sij = (1 - inter / Ms); // Relatedness double rij = Math.pow(1 + dij, mGammaD) * Math.pow(1 + tij, mGammaT) * Math.pow(1 + sij, mGammaS); // Store this value mRelatednessMatrix[i.getID()][j.getID()] = new Relatedness(i.getID(), j.getID(), rij); } } } @Override protected Relatedness[] evaluateRelatedRequests(int seed, TRSPSolution solution, Set<Integer> candidates) { return mRelatednessMatrix[seed]; } @Override public String getName() { return String.format("rel-stat-(%s,%s,%s)", mGammaD, mGammaT, mGammaS); }; @Override public DestroyStaticRelated clone() { DestroyStaticRelated clone = new DestroyStaticRelated(getRandomization(), mGammaD, mGammaT, mGammaS); clone.mRelatednessMatrix = new Relatedness[mRelatednessMatrix.length][]; for (int i = 0; i < clone.mRelatednessMatrix.length; i++) { if (mRelatednessMatrix[i] != null) clone.mRelatednessMatrix[i] = Arrays.copyOf(mRelatednessMatrix[i], mRelatednessMatrix[i].length); } return clone; } @Override public void dispose() { mRelatednessMatrix = null; } }