package vroom.trsp.optimization;
import java.util.concurrent.Callable;
import vroom.common.heuristics.ProcedureStatus;
import vroom.common.utilities.IDisposable;
import vroom.common.utilities.Stopwatch;
import vroom.common.utilities.Stopwatch.ReadOnlyStopwatch;
import vroom.trsp.datamodel.TRSPInstance;
import vroom.trsp.datamodel.costDelegates.TRSPCostDelegate;
import vroom.trsp.optimization.constraints.TourConstraintHandler;
import vroom.trsp.util.TRSPGlobalParameters;
import vroom.trsp.util.TRSPLogging;
/**
* <code>TRSPHeuristic</code> is the parent class for heuristics for the TRSP. It contains a reference to the parent
* instance, a random stream, global parameters, among others.
* <p>
* Creation date: Sep 22, 2011 - 1:59: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 abstract class TRSPHeuristic implements Runnable, Callable<ProcedureStatus>, IDisposable {
private final TRSPGlobalParameters mParameters;
/**
* Returns the parameters used for this heuristic
*
* @return the parameters used for this heuristic
*/
public TRSPGlobalParameters getParameters() {
return mParameters;
}
/** the current instance **/
private final TRSPInstance mInstance;
/**
* Getter for the current instance
*
* @return the value of instance
*/
public TRSPInstance getInstance() {
return this.mInstance;
}
/** this heuristic status **/
private ProcedureStatus mStatus;
/**
* Getter for this heuristic status
*
* @return the value of status
*/
public ProcedureStatus getStatus() {
return this.mStatus;
}
/**
* Setter for this heuristic status
*
* @param status
* the value to be set for this heuristic status
* @throws IllegalStateException
* if <code>status=</code>{@link ProcedureStatus.RUNNING RUNNING} and the heuristic is already running
*/
protected void setStatus(ProcedureStatus status) {
if (status == ProcedureStatus.RUNNING && this.mStatus == ProcedureStatus.RUNNING)
throw new IllegalStateException("Heuristic is already running");
this.mStatus = status;
}
/**
* Returns <code>true</code> if this heuristic is currently running, <code>false</code> otherwise
*
* @return <code>true</code> if this heuristic is currently running, <code>false</code> otherwise
*/
public boolean isRunning() {
return getStatus().isRunning();
}
/**
* Check if the instance is properly defined and the heuristic is not already running
*/
protected void checkState() {
if (getInstance() == null)
throw new IllegalStateException("Heuristic cannot be run if instance is not set");
if (isRunning())
throw new IllegalStateException("Heuristic is already running");
}
/** A timer used to measure time in this procedure */
protected final Stopwatch mTimer;
/**
* Getter for the main timer
*
* @return the main timer
*/
public ReadOnlyStopwatch getTimer() {
return mTimer.getReadOnlyStopwatch();
}
/** The current iteration count */
protected int mIteration = 0;
/**
* Returns the current number of iterations
*
* @return the current number of iterations
*/
public int getIterationCount() {
return mIteration;
}
/** the tour constraint handler for this heuristic **/
protected final TourConstraintHandler mTourConstraintHandler;
/**
* Getter for the tour constraint handler for this heuristic
*
* @return the tour constraint handler
*/
public TourConstraintHandler getTourConstraintHandler() {
return this.mTourConstraintHandler;
}
/** a cost delegate used to evaluate insertion costs **/
protected final TRSPCostDelegate mCostDelegate;
/**
* Getter for a cost delegate used to evaluate insertion costs
*
* @return the cost delegate
*/
public TRSPCostDelegate getCostDelegate() {
return this.mCostDelegate;
}
/** the maximum number of threads that will be used **/
private int mNumThreads;
/**
* Getter for the maximum number of threads that will be used
*
* @return the maximum number of threads that will be used
*/
public int getNumThreads() {
return this.mNumThreads;
}
/**
* Setter for the maximum number of threads that will be used
*
* @param numThreads
* the maximum number of threads that will be used
*/
public void setNumThreads(int numThreads) {
this.mNumThreads = numThreads;
}
/**
* Creates a new <code>TRSPHeuristic</code>
*
* @param constraintHandler
* @param costDelegate
*/
public TRSPHeuristic(TRSPInstance instance, TRSPGlobalParameters parameters,
TourConstraintHandler constraintHandler, TRSPCostDelegate costDelegate) {
mInstance = instance;
mParameters = parameters;
mCostDelegate = costDelegate;
mTourConstraintHandler = constraintHandler;
this.mTimer = new Stopwatch();
setNumThreads(mParameters.getThreadCount());
}
@Override
public void run() {
setStatus(ProcedureStatus.RUNNING);
try {
setStatus(call());
} catch (Exception e) {
TRSPLogging.getOptimizationLogger().exception("TRSPConstructiveHeuristic.run", e);
setStatus(ProcedureStatus.EXCEPTION);
}
}
@Override
public void dispose() {
mStatus = null;
}
}