package vroom.optimization.online.jmsa.benchmarking;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import vroom.common.heuristics.ConstraintHandler;
import vroom.common.heuristics.cw.CWParameters;
import vroom.common.heuristics.cw.kernel.ClarkeAndWrightHeuristic;
import vroom.common.heuristics.vrp.TwoOptNeighborhood;
import vroom.common.heuristics.vrp.constraints.CapacityConstraint;
import vroom.common.heuristics.vrp.constraints.FixedNodesConstraint;
import vroom.common.modeling.dataModel.IVRPInstance;
import vroom.common.modeling.dataModel.IVRPRequest;
import vroom.common.modeling.dataModel.IVRPSolution;
import vroom.common.modeling.dataModel.NodeVisit;
import vroom.common.modeling.io.NovoaPersistenceHelper.DemandDistribution;
import vroom.common.modeling.util.SolutionChecker;
import vroom.common.modeling.visualization.VRPVisualizationUtilities;
import vroom.common.utilities.StatCollector;
import vroom.common.utilities.StatCollector.Label;
import vroom.common.utilities.Stopwatch;
import vroom.common.utilities.Utilities;
import vroom.common.utilities.logging.LoggerHelper;
import vroom.common.utilities.optimization.IParameters.LSStrategy;
import vroom.common.utilities.optimization.SimpleParameters;
import vroom.optimization.online.jmsa.MSABase;
import vroom.optimization.online.jmsa.MSAGlobalParameters;
import vroom.optimization.online.jmsa.MSASequential;
import vroom.optimization.online.jmsa.components.ScenarioOptimizerParam;
import vroom.optimization.online.jmsa.vrp.MSAVRPInstance;
import vroom.optimization.online.jmsa.vrp.VRPActualRequest;
import vroom.optimization.online.jmsa.vrp.VRPSampledRequest;
import vroom.optimization.online.jmsa.vrp.VRPScenario;
import vroom.optimization.online.jmsa.vrp.optimization.MSACWSavingsHeuristic;
/**
* <code>MSAOptBenchmarking</code>
* <p>
* Creation date: Sep 21, 2010 - 2:39:09 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 MSAOptBenchmarking {
public final static LoggerHelper LOGGER = LoggerHelper.getLogger("MSAOptBenchmarking");
public static final Label<?>[] LABELS = new Label<?>[] { new Label<Integer>("run_id", Integer.class),
new Label<String>("instance_name", String.class), new Label<Integer>("size", Integer.class),
new Label<Integer>("vehicle_capacity", Integer.class), new Label<Long>("time_init", Long.class),
new Label<Long>("time_opt", Long.class), new Label<Long>("time_cw2Opt", Long.class),
new Label<Double>("optimal", Double.class), new Label<String>("seeds", String.class),
new Label<Double>("gap_init", Double.class), new Label<Double>("gap_opt", Double.class),
new Label<Double>("gap_cw2Opt", Double.class) };
public static void main(String[] args) {
NovoaRun.setupLoggers(LoggerHelper.LEVEL_WARN, LoggerHelper.LEVEL_WARN, false, true, false);
LOGGER.setLevel(LoggerHelper.LEVEL_INFO);
int numRuns = 100;
int[] sets = { 1 };
int[] sizes = { 30 };
String fileComment = "na";
if (args.length == 4) {
sizes = vroom.common.utilities.Utilities.toIntArray(args[0]);
sets = vroom.common.utilities.Utilities.toIntArray(args[1]);
numRuns = Integer.parseInt(args[2]);
fileComment = args[3];
} else {
System.err.println("Wrong number of arguments, usage: main [sizes] [sets] nruns comment");
System.err.println("Using default values");
}
MSAGlobalParameters params = NovoaBenchmarking.getDefaultParameters();
@SuppressWarnings({ "unchecked", "rawtypes" })
MSABase msa = new MSASequential(null, params);
String comment = String.format("Date: %s\nMSA:\n%s\n\nNum runs: %s", new Date(System.currentTimeMillis()),
msa.getComponentsDescription(), numRuns);
String file = String.format("results/optbench_%s.csv", fileComment);
StatCollector collector = new StatCollector(new File(file), true, false, comment, LABELS);
PerfectInformationSolver solver = new PerfectInformationSolver();
CWParameters cwParams = new CWParameters();
cwParams.set(CWParameters.RANDOM_SEED, params.get(MSAGlobalParameters.RANDOM_SEED));
ClarkeAndWrightHeuristic<IVRPSolution<?>> cw = new ClarkeAndWrightHeuristic<IVRPSolution<?>>(cwParams,
MSACWSavingsHeuristic.class, getConstraintHandler());
LOGGER.info("=============================================================");
LOGGER.info(" Starting benchmarks for instances %s in sets %s with %s runs", Arrays.toString(sizes),
Arrays.toString(sets), numRuns);
LOGGER.info(" Stats saved in file %s", file);
LOGGER.info("=============================================================");
Stopwatch mainTimer = new Stopwatch();
mainTimer.start();
double progress = 0;
double perc = 100d / (sets.length * sizes.length * 2 * 5 * numRuns);
for (int set : sets) {
for (int size : sizes) {
for (int cap = 0; cap < 2; cap++) {
for (int num = 1; num <= 5; num++) {
for (int run = 0; run < numRuns; run++) {
progress += perc;
long etc = (long) (mainTimer.readTimeMS() / progress * 100);
long[] seeds = NovoaBenchmarking.getSeeds(run, size, num, cap, set);
NovoaRun novoa = null;
try {
novoa = new NovoaRun(set, size, num, cap, run, params, DemandDistribution.UNIFORM);
} catch (IOException e) {
LOGGER.exception("MSAOptBenchmarking.main", e);
break;
}
MSAVRPInstance instance = new MSAVRPInstance(novoa.getSimulationInstance(), params);
LOGGER.info(" %.1f - instance: %s run: %s etc: %s", progress, instance.getName(), run,
Utilities.Time.millisecondsToString(etc, 3, false, false));
Stopwatch timer = new Stopwatch();
double initTime;
double optTime, cw2OptTime;
double initObj, optObj, cw2OptObj;
List<VRPActualRequest> act = new LinkedList<VRPActualRequest>();
for (IVRPRequest r : novoa.getSimulationInstance().getRequests()) {
VRPActualRequest req = new VRPActualRequest(NodeVisit.createNodeVisits(r)[0]);
act.add(req);
}
List<VRPSampledRequest> samp = new LinkedList<VRPSampledRequest>();
VRPScenario solution = new VRPScenario(instance, act, samp);
timer.start();
novoa.getMsa()
.getComponentManager()
.getScenarioOptimizer()
.initialize(solution,
new ScenarioOptimizerParam(Integer.MAX_VALUE, Integer.MAX_VALUE, false));
timer.stop();
SolutionChecker.checkSolution(solution, true, true, true);
initObj = solution.getCost();
initTime = timer.readTimeMS();
timer.restart();
novoa.getMsa()
.getComponentManager()
.getScenarioOptimizer()
.optimize(solution,
new ScenarioOptimizerParam(Integer.MAX_VALUE, Integer.MAX_VALUE, false));
timer.stop();
SolutionChecker.checkSolution(solution, true, true, true);
optObj = solution.getCost();
optTime = timer.readTimeMS();
timer.restart();
cw2OptObj = cw2Opt(instance, cw);
timer.stop();
cw2OptTime = timer.readTimeMS();
double optimal = solver.solvePerfectInformation(run, size, num, cap, set,
Integer.MAX_VALUE, false, true, DemandDistribution.UNIFORM);
collector.collect(run, instance.getName(), size, (int) novoa.getInstance().getFleet()
.getVehicle(0).getCapacity(), initTime, optTime, cw2OptTime, optimal,
Arrays.toString(seeds), (initObj - optimal) / optimal,
(optObj - optimal) / optimal, (cw2OptObj - optimal) / optimal);
novoa = null;
}
Runtime.getRuntime().gc();
}
}
}
}
mainTimer.stop();
LOGGER.info("=============================================================");
LOGGER.info(" FINISHED");
LOGGER.info(" Total time:%s", mainTimer.readTimeString());
LOGGER.info("=============================================================");
System.exit(0);
}
public static double cw2Opt(IVRPInstance instance, ClarkeAndWrightHeuristic<IVRPSolution<?>> cw) {
cw.initialize(instance);
cw.run();
TwoOptNeighborhood<IVRPSolution<?>> twoOpt = new TwoOptNeighborhood<IVRPSolution<?>>(getConstraintHandler());
IVRPSolution<?> cwSol = cw.getSolution();
IVRPSolution<?> twoOptSol = twoOpt.localSearch(instance, cwSol, new SimpleParameters(
LSStrategy.DET_BEST_IMPROVEMENT, Long.MAX_VALUE, Integer.MAX_VALUE, cw.getRandomStream()));
String err = SolutionChecker.checkSolution(twoOptSol, false, true, true);
if (err != null) {
VRPVisualizationUtilities.showVisualizationFrame(twoOptSol);
throw new IllegalStateException("CW+2Opt solution is not feasible: " + err);
}
return twoOptSol.getCost();
}
public static ConstraintHandler<IVRPSolution<?>> getConstraintHandler() {
ConstraintHandler<IVRPSolution<?>> constraintHandler = new ConstraintHandler<IVRPSolution<?>>();
constraintHandler.addConstraint(new FixedNodesConstraint<IVRPSolution<?>>());
constraintHandler.addConstraint(new CapacityConstraint<IVRPSolution<?>>());
return constraintHandler;
}
}