Java tutorial
/* * Copyright (C) 2011-2016 Rinde van Lon, iMinds-DistriNet, KU Leuven * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.github.rinde.rinsim.central; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.io.File; import java.io.IOException; import javax.measure.converter.UnitConverter; import javax.measure.unit.NonSI; import javax.measure.unit.SI; import org.apache.commons.math3.random.MersenneTwister; import org.apache.commons.math3.random.RandomGenerator; import org.junit.Test; import com.github.rinde.rinsim.central.Solvers.ExtendedStats; import com.github.rinde.rinsim.central.arrays.ArraysSolverDebugger.MVASDebugger; import com.github.rinde.rinsim.central.arrays.ArraysSolvers; import com.github.rinde.rinsim.central.arrays.ArraysSolvers.MVArraysObject; import com.github.rinde.rinsim.central.arrays.SolutionObject; import com.github.rinde.rinsim.core.model.pdp.Parcel; import com.github.rinde.rinsim.experiment.Experiment; import com.github.rinde.rinsim.experiment.ExperimentResults; import com.github.rinde.rinsim.experiment.PostProcessors; import com.github.rinde.rinsim.pdptw.common.ObjectiveFunction; import com.github.rinde.rinsim.pdptw.common.StatisticsDTO; import com.github.rinde.rinsim.scenario.gendreau06.Gendreau06ObjectiveFunction; import com.github.rinde.rinsim.scenario.gendreau06.Gendreau06Parser; import com.github.rinde.rinsim.scenario.gendreau06.Gendreau06Scenario; import com.google.common.collect.ImmutableList; import com.google.common.primitives.Longs; /** * @author Rinde van Lon */ public class SolverSimTest { private static final double MS_TO_MIN = 60000d; /** * Tests whether the simulator produces the same objective value as the * solver. * @throws IOException In case file loading fails. */ @Test public void testOffline() throws IOException { final Gendreau06Scenario scenario = Gendreau06Parser.parser().addFile(ScenarioPaths.GENDREAU).offline() .parse().get(0); final RandomGenerator rng = new MersenneTwister(123); for (int i = 0; i < 5; i++) { final long seed = rng.nextLong(); final DebugSolverCreator dsc = new DebugSolverCreator(seed, SI.MILLI(SI.SECOND)); final Gendreau06ObjectiveFunction obj = Gendreau06ObjectiveFunction.instance(); final ExperimentResults results = Experiment.builder() .addConfiguration(Central.solverConfiguration(dsc)).addScenario(scenario) .usePostProcessor(PostProcessors.statisticsPostProcessor(obj)).perform(); assertEquals(1, results.getResults().size()); assertEquals(1, dsc.arraysSolver.getInputs().size()); assertEquals(1, dsc.arraysSolver.getOutputs().size()); final SolutionObject[] sols = dsc.arraysSolver.getOutputs().get(0); int objVal = 0; for (final SolutionObject sol : sols) { objVal += sol.objectiveValue; } // convert the objective values computed by the solver to the unit of the // gendreau benchmark (minutes). final UnitConverter converter = SI.MILLI(SI.SECOND).getConverterTo(NonSI.MINUTE); final double objValInMinutes = converter.convert(objVal); final GlobalStateObject solverInput = dsc.solver.getInputs().get(0); final ImmutableList<ImmutableList<Parcel>> solverOutput = dsc.solver.getOutputs().get(0); assertEquals(obj.computeCost((StatisticsDTO) results.getResults().asList().get(0).getResultObject()), objValInMinutes, 0.2); final StatisticsDTO stats = Solvers.computeStats(solverInput, solverOutput); assertTrue(stats.toString(), obj.isValidResult(stats)); assertEquals(objValInMinutes, obj.computeCost(stats), 0.1); assertEquals(objValInMinutes, decomposedCost(solverInput, solverOutput, obj), 0.01); } } /** * Tests whether the computation of the objective value in ArraysSolvers and * in Solvers produce identical values. * @throws IOException When file loading fails. */ @Test public void testOnline() throws IOException { final Gendreau06Scenario scenario = Gendreau06Parser.parse(new File(ScenarioPaths.GENDREAU)); final DebugSolverCreator dsc = new DebugSolverCreator(123, SI.MILLI(SI.SECOND)); final Gendreau06ObjectiveFunction obj = Gendreau06ObjectiveFunction.instance(); Experiment.builder().withThreads(1).addConfiguration(Central.solverConfiguration(dsc)).addScenario(scenario) .repeat(10).perform(); final MVASDebugger arraysSolver = dsc.arraysSolver; final SolverDebugger solver = dsc.solver; final int n = solver.getInputs().size(); assertEquals(n, arraysSolver.getInputs().size()); assertEquals(n, solver.getOutputs().size()); assertEquals(n, arraysSolver.getOutputs().size()); for (int i = 0; i < n; i++) { final GlobalStateObject solverInput = solver.getInputs().get(i); final ImmutableList<ImmutableList<Parcel>> solverOutput = solver.getOutputs().get(i); final SolutionObject[] sols = arraysSolver.getOutputs().get(i); final MVArraysObject arrInput = arraysSolver.getInputs().get(i); assertEquals(solverOutput.size(), sols.length); final double arrObjVal = ArraysSolvers.computeTotalObjectiveValue(sols) / MS_TO_MIN; final double arrOverTime = overTime(sols, arrInput) / MS_TO_MIN; final double arrTardiness = computeTardiness(sols, arrInput) / MS_TO_MIN; final double arrTravelTime = computeTravelTime(sols, arrInput) / MS_TO_MIN; final ExtendedStats stats = Solvers.computeStats(solverInput, solverOutput); // check arrival times for (int j = 0; j < sols.length; j++) { final SolutionObject sol = sols[j]; final long[] arraysArrivalTimes = incrArr(sol.arrivalTimes, solverInput.getTime()); final long[] arrivalTimes = Longs.toArray(stats.arrivalTimes.get(j)); assertArrayEquals(arraysArrivalTimes, arrivalTimes); } final double tardiness = obj.tardiness(stats) + obj.overTime(stats); final double travelTime = obj.travelTime(stats); assertEquals(arrOverTime, obj.overTime(stats), 0.001); assertEquals(arrTravelTime, travelTime, 0.01); assertEquals(arrTardiness, tardiness, 0.001); assertEquals(arrObjVal, obj.computeCost(stats), 0.01); assertEquals(arrObjVal, decomposedCost(solverInput, solverOutput, obj), 0.01); } } static double decomposedCost(GlobalStateObject gso, ImmutableList<ImmutableList<Parcel>> routes, ObjectiveFunction objFunc) { double sum = 0d; for (int i = 0; i < gso.getVehicles().size(); i++) { sum += objFunc .computeCost(Solvers.computeStats(gso.withSingleVehicle(i), ImmutableList.of(routes.get(i)))); } return sum; } // increment & convert to long[] static long[] incrArr(int[] arr, long incr) { final long[] newArr = new long[arr.length]; for (int i = 0; i < newArr.length; i++) { newArr[i] += arr[i] + incr; } return newArr; } static int computeTardiness(SolutionObject[] sols, MVArraysObject arr) { int total = 0; for (int i = 0; i < sols.length; i++) { final SolutionObject sol = sols[i]; total += ArraysSolvers.computeRouteTardiness(sol.route, sol.arrivalTimes, arr.serviceTimes, arr.dueDates, arr.remainingServiceTimes[i]); } return total; } static int computeTravelTime(SolutionObject[] sols, MVArraysObject arr) { int total = 0; for (int i = 0; i < sols.length; i++) { final SolutionObject sol = sols[i]; total += ArraysSolvers.computeTotalTravelTime(sol.route, arr.travelTime, arr.vehicleTravelTimes[i]); } return total; } static int overTime(SolutionObject[] sols, MVArraysObject arr) { int overTime = 0; for (int i = 0; i < sols.length; i++) { final SolutionObject sol = sols[i]; final int index = sol.route.length - 1; assertEquals(0, arr.serviceTimes[sol.route[index]]); final int lateness = sol.arrivalTimes[index] + arr.serviceTimes[sol.route[index]] - arr.dueDates[sol.route[index]]; if (lateness > 0) { overTime += lateness; } } return overTime; } }