/**
*
*/
package vrp2013.algorithms;
import vroom.common.heuristics.ConstraintHandler;
import vroom.common.heuristics.cw.CWParameters;
import vroom.common.heuristics.cw.kernel.ClarkeAndWrightHeuristic;
import vroom.common.heuristics.vrp.constraints.CapacityConstraint;
import vroom.common.modeling.dataModel.INodeVisit;
import vroom.common.modeling.dataModel.IVRPInstance;
import vroom.common.modeling.util.IRoutePool;
import vroom.common.modeling.util.ISolutionFactory;
import vroom.common.utilities.Stopwatch;
import vrp2013.util.VRPLogging;
import vrp2013.util.VRPSolution;
/**
* <code>GRASP</code> is a simple implementation of the Greedy Randomized Adaptive Search Procedure based on a
* {@link ClarkeAndWrightHeuristic} for initialization and a {@link VND} for local search.
* <p>
* Creation date: 30/04/2013 - 5:06:35 PM
*
* @author Victor Pillac, <a href="http://www.nicta.com.au">National ICT Australia</a>, <a
* href="http://www.victorpillac.com">www.victorpillac.com</a>
* @version 1.0
*/
public class GRASP implements IVRPOptimizationAlgorithm {
private final IVRPInstance mInstance;
private final CW mInitialization;
private final VND mLocalSearch;
private final ConstraintHandler<VRPSolution> mConstraintHandler;
private final Stopwatch mStopwatch;
private final int mIterations;
private final long mInitSeed;
private final IRoutePool<INodeVisit> mRoutePool;
private VRPSolution mBestSolution;
private final ISolutionFactory mSolutionFactory;
/* (non-Javadoc)
* @see vrp2013.algorithms.VRPOptimizationAlgorithm#getRoutePool()
*/
@Override
public IRoutePool<INodeVisit> getRoutePool() {
return mRoutePool;
}
/* (non-Javadoc)
* @see vrp2013.algorithms.VRPOptimizationAlgorithm#getBestSolution()
*/
@Override
public VRPSolution getBestSolution() {
return mBestSolution;
}
@Override
public IVRPInstance getInstance() {
return mInstance;
}
@Override
public int getIterations() {
return mIterations;
}
@Override
public ISolutionFactory getSolutionFactory() {
return mSolutionFactory;
}
/**
* Creates a new <code>GRASP</code>
*
* @param instance
* the instance that will be solved
* @param solutionFactory
* the solution factory that will be used to create new solutions and routes
* @param initSeed
* the initial random seed
* @param iterations
* the number of iterations
* @param routePool
* an optional pool to collect routes
*/
public GRASP(IVRPInstance instance, ISolutionFactory solutionFactory, long initSeed,
int iterations, IRoutePool<INodeVisit> routePool) {
mInstance = instance;
mConstraintHandler = new ConstraintHandler<>(new CapacityConstraint<VRPSolution>());
mIterations = iterations;
mSolutionFactory = solutionFactory;
CWParameters cwParams = new CWParameters();
cwParams.setDefaultValues();
mStopwatch = new Stopwatch();
mInitialization = new CW(getInstance(), getSolutionFactory(), mConstraintHandler);
mRoutePool = routePool;
mLocalSearch = new VND(getInstance(), mConstraintHandler, mRoutePool);
mInitSeed = initSeed;
}
@Override
public VRPSolution call() {
mBestSolution = null;
mStopwatch.restart();
for (int it = 0; it < mIterations; it++) {
long seed = mInitSeed + it;
VRPLogging.getOptLogger().debug("%s GRASP iteration %s/%s (%s)",
mStopwatch.readTimeString(3, true, false), it + 1, mIterations, seed);
Stopwatch sw = new Stopwatch();
sw.start();
// Execute initialization
mInitialization.updateSeed(seed);
VRPSolution solution = mInitialization.call();
sw.stop();
VRPLogging.logOptResults("init", true, sw, solution);
// Execute the local search
mLocalSearch.setInitialSolution(solution);
solution = mLocalSearch.call();
// Remove empty roads for clarity
solution.removeEmptyRoutes();
if (mBestSolution == null
|| solution.getObjectiveValue() < mBestSolution.getObjectiveValue()) {
// We found a new best solution
mBestSolution = solution;
}
VRPLogging.getOptLogger().debug(
"%s GRASP iteration %s/%s (%s) finished - Current:%.2f Best:%.2f",
mStopwatch.readTimeString(3, true, false), it + 1, mIterations, seed,
solution.getCost(), mBestSolution.getCost());
}
VRPLogging.getOptLogger().info("%s GRASP terminated - Best solution: %s",
mStopwatch.readTimeString(3, true, false), mBestSolution);
mStopwatch.stop();
return mBestSolution;
}
@Override
public void dispose() {
mLocalSearch.dispose();
mRoutePool.dispose();
}
}