/** * */ package vroom.trsp.optimization.split; import java.util.Iterator; import vroom.trsp.datamodel.ITRSPTour; import vroom.trsp.datamodel.ITourIterator; import vroom.trsp.datamodel.SimpleTourIterator; import vroom.trsp.datamodel.TRSPInstance; import vroom.trsp.datamodel.TRSPTourBase; /** * The class <code>SplitTourArc</code> represent an arc in the Split auxiliary graph, i.e. a tour in the solution space. * For efficiency it is defined on top of an existing giant tour. * <p> * Creation date: Sep 26, 2011 - 4:53:41 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 SplitTourArc extends TRSPTourBase { /** A constant used to specify that the main depot is not visited */ public static final int DEPOT_NOT_VISITED = -1; /** the parent giant tour */ private final ITRSPTour mGiantTour; /** the start index of this tour */ private final int mStart; /** the end index of this tour */ private final int mEnd; /** the index of the visit to the depot */ private int mDepotIndex = DEPOT_NOT_VISITED; /** the id of the technician home */ private final int mHomeS; private final int mHomeE; /** the length of this tour */ private int mLength; /** the cost of this tour **/ private double mTotalCost; /** * Getter for the cost of this tour * * @return the value of name */ @Override public double getTotalCost() { return this.mTotalCost; } /** * Setter for the cost of this tour * * @param name * the value to be set for the cost of this tour */ @Override public void setTotalCost(double name) { this.mTotalCost = name; } /** * Returns the index of the first node of this arc in the parent giant tour * * @return the index of the first node of this arc in the parent giant tour */ public int getStart() { return mStart; } /** * Returns the index of the last node of this arc in the parent giant tour * * @return the index of the last node of this arc in the parent giant tour */ public int getEnd() { return mEnd; } /** * Creates a new <code>SplitTourArc</code> * * @param giantTour * the parent giant tour * @param start * the start index of this tour * @param end * the end index of this tour */ public SplitTourArc(ITRSPTour giantTour, int start, int end) { super(); mGiantTour = giantTour; mStart = start; mEnd = end; mTotalCost = Double.NaN; mHomeS = giantTour.getInstance().getTechnician(giantTour.getTechnicianId()).getHome() .getID(); mHomeE = giantTour.getInstance().getHomeDuplicate(mHomeS); mLength = mEnd - mStart + 3; } @Override public TRSPInstance getInstance() { return mGiantTour.getInstance(); } @Override public int getTechnicianId() { return mGiantTour.getTechnicianId(); } @Override public int[] asArray() { int[] array = new int[length()]; int idx = 0; for (int i : this) array[idx++] = i; return array; } /** * Set the index of the visit to the depot * * @param index * the index of the visit to the depot * @throws IllegalStateException * if the depot visit was already set */ public void setDepotVisitIndex(int index) { if (mDepotIndex != DEPOT_NOT_VISITED) throw new IllegalStateException("The depot visit was already set"); if (index != DEPOT_NOT_VISITED) { mDepotIndex = index; mLength++; } } /** * Returns <code>true</code> if the main depot is visited, <code>false</code> otherwise * * @return <code>true</code> if the main depot is visited, <code>false</code> otherwise */ public boolean isMainDepotVisited() { return mDepotIndex != DEPOT_NOT_VISITED; } @Override public int getNodeAt(int index) { if (index == 0) return getFirstNode(); else if (index == length() - 1) return getLastNode(); else if (!isMainDepotVisited()) return mGiantTour.getNodeAt(mStart + index - 1); else { if (index < mDepotIndex) return mGiantTour.getNodeAt(mStart + index - 1); else if (index == mDepotIndex) return getInstance().getMainDepot().getID(); else return mGiantTour.getNodeAt(mStart + index - 2); } } @Override public int getFirstNode() { return mHomeS; } @Override public int getLastNode() { return mHomeE; } @Override public int length() { return mLength; } @Override public String getNodeSeqString() { StringBuilder sb = new StringBuilder(length() * 3); sb.append("<"); Iterator<Integer> it = iterator(); while (it.hasNext()) { int n = it.next(); sb.append(n); if (it.hasNext()) sb.append(","); } sb.append(">"); return sb.toString(); } @Override public boolean isVisited(int node) { for (int i = 0; i < length(); i++) { if (getNodeAt(i) == node) return true; } return false; } @Override public ITourIterator iterator() { return new SimpleTourIterator(this); } @Override public ITRSPTour clone() { SplitTourArc clone = new SplitTourArc(mGiantTour, mStart, mEnd); if (isMainDepotVisited()) clone.setDepotVisitIndex(mDepotIndex); return clone; } @Override public int hashSolution() { return hashCode(); } }