unassignedJobs) {
- if(!record()) return;
- fileSink.stepBegins(graph.getId(),0,RECREATE);
+ if (!record()) return;
+ fileSink.stepBegins(graph.getId(), 0, RECREATE);
}
}
diff --git a/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/AlgorithmEventsViewer.java b/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/AlgorithmEventsViewer.java
index 3efae707..dea49371 100644
--- a/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/AlgorithmEventsViewer.java
+++ b/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/AlgorithmEventsViewer.java
@@ -47,7 +47,7 @@ public class AlgorithmEventsViewer {
this.delayContainer = delayContainer;
}
- public void setRuinDelay(long ruinDelay){
+ public void setRuinDelay(long ruinDelay) {
this.ruinDelay = ruinDelay;
}
@@ -131,16 +131,14 @@ public class AlgorithmEventsViewer {
@Override
public void stepBegins(String sourceId, long timeId, double step) {
- if(step == AlgorithmEventsRecorder.RECREATE) {
+ if (step == AlgorithmEventsRecorder.RECREATE) {
delayContainer.delay = recreateDelay;
}
- if(step == AlgorithmEventsRecorder.RUIN){
+ if (step == AlgorithmEventsRecorder.RUIN) {
delayContainer.delay = ruinDelay;
- }
- else if(step == AlgorithmEventsRecorder.CLEAR_SOLUTION){
+ } else if (step == AlgorithmEventsRecorder.CLEAR_SOLUTION) {
delayContainer.delay = delay;
- }
- else if(step == AlgorithmEventsRecorder.BEFORE_RUIN_RENDER_SOLUTION){
+ } else if (step == AlgorithmEventsRecorder.BEFORE_RUIN_RENDER_SOLUTION) {
delayContainer.delay = delay;
}
}
@@ -156,15 +154,15 @@ public class AlgorithmEventsViewer {
private long delay = 2;
- public void setRecreationDelay(long delay_in_ms){
+ public void setRecreationDelay(long delay_in_ms) {
this.delayRecreation = delay_in_ms;
}
- public void setRuinDelay(long delay_in_ms){
+ public void setRuinDelay(long delay_in_ms) {
this.delayRuin = delay_in_ms;
}
- public void display(String dgsFile){
+ public void display(String dgsFile) {
System.setProperty("org.graphstream.ui.renderer", "org.graphstream.ui.j2dviewer.J2DGraphRenderer");
Graph graph = GraphStreamViewer.createMultiGraph("g", GraphStreamViewer.StyleSheets.BLUE_FOREST);
Viewer viewer = graph.display();
@@ -185,13 +183,13 @@ public class AlgorithmEventsViewer {
while (fs.nextEvents()) {
sleep(delayContainer.delay);
}
- } catch( IOException e) {
+ } catch (IOException e) {
e.printStackTrace();
}
try {
fs.end();
- } catch( IOException e) {
+ } catch (IOException e) {
e.printStackTrace();
} finally {
fs.removeSink(graph);
diff --git a/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/AlgorithmSearchProgressChartListener.java b/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/AlgorithmSearchProgressChartListener.java
index 4136ff8c..5dcca9b3 100644
--- a/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/AlgorithmSearchProgressChartListener.java
+++ b/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/AlgorithmSearchProgressChartListener.java
@@ -1,17 +1,17 @@
/*******************************************************************************
* Copyright (C) 2013 Stefan Schroeder
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
+ * License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
+ *
+ * You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see .
******************************************************************************/
package jsprit.analysis.toolbox;
@@ -30,59 +30,58 @@ import java.util.Collection;
/**
* VehicleRoutingAlgorithm-Listener to record the solution-search-progress.
- *
+ *
* Register this listener in VehicleRoutingAlgorithm.
- *
+ *
* @author stefan schroeder
- *
*/
public class AlgorithmSearchProgressChartListener implements IterationEndsListener, AlgorithmEndsListener, AlgorithmStartsListener {
- private static Logger log = LogManager.getLogger(AlgorithmSearchProgressChartListener.class);
+ private static Logger log = LogManager.getLogger(AlgorithmSearchProgressChartListener.class);
- private String filename;
-
- private XYLineChartBuilder chartBuilder;
+ private String filename;
- /**
- * Constructs chart listener with target png-file (filename plus path).
- *
- * @param pngFileName
- */
- public AlgorithmSearchProgressChartListener(String pngFileName) {
- super();
- this.filename = pngFileName;
- if(!this.filename.endsWith("png")){
- this.filename += ".png";
- }
- }
+ private XYLineChartBuilder chartBuilder;
- @Override
- public void informAlgorithmEnds(VehicleRoutingProblem problem, Collection solutions) {
- log.info("create chart " + filename);
- XYLineChartBuilder.saveChartAsPNG(chartBuilder.build(), filename);
- }
+ /**
+ * Constructs chart listener with target png-file (filename plus path).
+ *
+ * @param pngFileName
+ */
+ public AlgorithmSearchProgressChartListener(String pngFileName) {
+ super();
+ this.filename = pngFileName;
+ if (!this.filename.endsWith("png")) {
+ this.filename += ".png";
+ }
+ }
- @Override
- public void informIterationEnds(int i, VehicleRoutingProblem problem, Collection solutions) {
- double worst = 0.0;
- double best = Double.MAX_VALUE;
- double sum = 0.0;
- for(VehicleRoutingProblemSolution sol : solutions){
- if(sol.getCost() > worst) worst = Math.min(sol.getCost(),Double.MAX_VALUE);
- if(sol.getCost() < best) best = sol.getCost();
- sum += Math.min(sol.getCost(),Double.MAX_VALUE);
- }
- chartBuilder.addData("best", i, best);
- chartBuilder.addData("worst", i, worst);
- chartBuilder.addData("avg", i, sum/(double)solutions.size());
- }
+ @Override
+ public void informAlgorithmEnds(VehicleRoutingProblem problem, Collection solutions) {
+ log.info("create chart {}", filename);
+ XYLineChartBuilder.saveChartAsPNG(chartBuilder.build(), filename);
+ }
+
+ @Override
+ public void informIterationEnds(int i, VehicleRoutingProblem problem, Collection solutions) {
+ double worst = 0.0;
+ double best = Double.MAX_VALUE;
+ double sum = 0.0;
+ for (VehicleRoutingProblemSolution sol : solutions) {
+ if (sol.getCost() > worst) worst = Math.min(sol.getCost(), Double.MAX_VALUE);
+ if (sol.getCost() < best) best = sol.getCost();
+ sum += Math.min(sol.getCost(), Double.MAX_VALUE);
+ }
+ chartBuilder.addData("best", i, best);
+ chartBuilder.addData("worst", i, worst);
+ chartBuilder.addData("avg", i, sum / (double) solutions.size());
+ }
- @Override
- public void informAlgorithmStarts(VehicleRoutingProblem problem,VehicleRoutingAlgorithm algorithm,Collection solutions) {
- chartBuilder = XYLineChartBuilder.newInstance("search-progress", "iterations", "results");
- }
+ @Override
+ public void informAlgorithmStarts(VehicleRoutingProblem problem, VehicleRoutingAlgorithm algorithm, Collection solutions) {
+ chartBuilder = XYLineChartBuilder.newInstance("search-progress", "iterations", "results");
+ }
}
diff --git a/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/ComputationalLaboratory.java b/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/ComputationalLaboratory.java
index 7ebf4b3f..8abf7657 100644
--- a/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/ComputationalLaboratory.java
+++ b/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/ComputationalLaboratory.java
@@ -1,18 +1,18 @@
/*******************************************************************************
* Copyright (c) 2014 Stefan Schroeder.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
+ * License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
+ *
+ * You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see .
- *
+ *
* Contributors:
* Stefan Schroeder - initial API and implementation
******************************************************************************/
@@ -33,433 +33,444 @@ import java.util.concurrent.TimeUnit;
public class ComputationalLaboratory {
- public static interface LabListener {
+ public static interface LabListener {
- }
+ }
- /**
- * Listener-interface to listen to calculation.
- *
- * Note that calculations are run concurrently, i.e. a unique task that is distributed to an available thread is
- * {algorithm, instance, run}.
- *
- * @author schroeder
- *
- */
- public static interface CalculationListener extends LabListener{
-
- public void calculationStarts(final BenchmarkInstance p, final String algorithmName, final VehicleRoutingAlgorithm algorithm, final int run);
-
- public void calculationEnds(final BenchmarkInstance p, final String algorithmName, final VehicleRoutingAlgorithm algorithm, final int run, final Collection solutions);
-
- }
+ /**
+ * Listener-interface to listen to calculation.
+ *
+ * Note that calculations are run concurrently, i.e. a unique task that is distributed to an available thread is
+ * {algorithm, instance, run}.
+ *
+ * @author schroeder
+ */
+ public static interface CalculationListener extends LabListener {
- public static interface LabStartsAndEndsListener extends LabListener {
+ public void calculationStarts(final BenchmarkInstance p, final String algorithmName, final VehicleRoutingAlgorithm algorithm, final int run);
- public void labStarts(List instances, int noAlgorithms, int runs);
+ public void calculationEnds(final BenchmarkInstance p, final String algorithmName, final VehicleRoutingAlgorithm algorithm, final int run, final Collection solutions);
- public void labEnds();
- }
-
- /**
- * Collects whatever indicators you require by algorithmName, instanceName, run and indicator.
- *
- * @author schroeder
- *
- */
- public static class DataCollector {
-
- public static class Key {
- private String instanceName;
- private String algorithmName;
- private int run;
- private String indicatorName;
-
- public Key(String instanceName, String algorithmName, int run,String indicatorName) {
- super();
- this.instanceName = instanceName;
- this.algorithmName = algorithmName;
- this.run = run;
- this.indicatorName = indicatorName;
- }
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime
- * result
- + ((algorithmName == null) ? 0 : algorithmName
- .hashCode());
- result = prime
- * result
- + ((indicatorName == null) ? 0 : indicatorName
- .hashCode());
- result = prime
- * result
- + ((instanceName == null) ? 0 : instanceName.hashCode());
- result = prime * result + run;
- return result;
- }
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- Key other = (Key) obj;
- if (algorithmName == null) {
- if (other.algorithmName != null)
- return false;
- } else if (!algorithmName.equals(other.algorithmName))
- return false;
- if (indicatorName == null) {
- if (other.indicatorName != null)
- return false;
- } else if (!indicatorName.equals(other.indicatorName))
- return false;
- if (instanceName == null) {
- if (other.instanceName != null)
- return false;
- } else if (!instanceName.equals(other.instanceName))
- return false;
- if (run != other.run)
- return false;
- return true;
- }
- public String getInstanceName() {
- return instanceName;
- }
- public String getAlgorithmName() {
- return algorithmName;
- }
- public int getRun() {
- return run;
- }
- public String getIndicatorName() {
- return indicatorName;
- }
-
- @Override
- public String toString() {
- return "[algorithm="+algorithmName+"][instance="+instanceName+"][run="+run+"][indicator="+indicatorName+"]";
- }
-
- }
-
- private final static String SOLUTION_INDICATOR_NAME = "vehicle-routing-problem-solution";
-
- private ConcurrentHashMap data = new ConcurrentHashMap();
-
- private ConcurrentHashMap solutions = new ConcurrentHashMap();
- /**
- * Adds a single date by instanceName, algorithmName, run and indicatorName.
- * If there is already an entry for this instance, algorithm, run and indicatorName, it is overwritten.
- *
- * @param instanceName
- * @param algorithmName
- * @param run
- * @param indicatorName
- * @param value
- */
- public void addDate(String instanceName, String algorithmName, int run, String indicatorName, double value){
- if(indicatorName.equals(SOLUTION_INDICATOR_NAME)) throw new IllegalArgumentException(indicatorName + " is already used internally. please choose another indicator-name.");
- Key key = new Key(instanceName,algorithmName,run,indicatorName);
- data.put(key, value);
- }
-
- public void addSolution(String instanceName, String algorithmName, int run, VehicleRoutingProblemSolution solution){
- Key key = new Key(instanceName,algorithmName,run,SOLUTION_INDICATOR_NAME);
- solutions.put(key, solution);
- }
-
- /**
- * Returns a collections of indicator values representing the calculated values of individual runs.
- *
- * @param instanceName
- * @param algorithmName
- * @param indicator
- * @return
- */
- public Collection getData(String instanceName, String algorithmName, String indicator){
- List values = new ArrayList();
- for(Key key : data.keySet()){
- if(key.getAlgorithmName().equals(algorithmName) && key.getInstanceName().equals(instanceName) && key.getIndicatorName().equals(indicator)){
- values.add(data.get(key));
- }
- }
- return values;
- }
-
- /**
- * Returns indicator value.
- *
- * @param instanceName
- * @param algorithmName
- * @param run
- * @param indicator
- * @return
- */
- public Double getDate(String instanceName, String algorithmName, int run, String indicator){
- return data.get(new Key(instanceName,algorithmName,run,indicator));
- }
-
- public VehicleRoutingProblemSolution getSolution(String instanceName, String algorithmName, int run){
- return solutions.get(new Key(instanceName,algorithmName,run,"solution"));
- }
+ }
- /**
- * Returns all keys that have been created. A key is a unique combination of algorithmName, instanceName, run and indicator.
- *
- * @return
- */
- public Set getDataKeySet(){
- return data.keySet();
- }
-
- public Set getSolutionKeySet(){
- return solutions.keySet();
- }
-
- public VehicleRoutingProblemSolution getSolution(Key solutionKey){
- return solutions.get(solutionKey);
- }
-
- public Collection getSolutions(){
- return solutions.values();
- }
-
- /**
- * Returns date associated to specified key.
- *
- * @param key
- * @return
- */
- public Double getData(Key key){
- return data.get(key);
- }
-
- }
-
-
- private static class Algorithm {
-
- private String name;
-
- private VehicleRoutingAlgorithmFactory factory;
+ public static interface LabStartsAndEndsListener extends LabListener {
- public Algorithm(String name, VehicleRoutingAlgorithmFactory factory) {
- super();
- this.name = name;
- this.factory = factory;
- }
-
- }
-
- private List benchmarkInstances = new ArrayList();
+ public void labStarts(List instances, int noAlgorithms, int runs);
- private int runs = 1;
-
- private Collection listeners = new ArrayList();
+ public void labEnds();
+ }
- private Collection startsAndEndslisteners = new ArrayList();
-
- private List algorithms = new ArrayList();
-
- private Set algorithmNames = new HashSet();
-
- private Set instanceNames = new HashSet();
-
- private int threads = 1;
-
- public ComputationalLaboratory() {
+ /**
+ * Collects whatever indicators you require by algorithmName, instanceName, run and indicator.
+ *
+ * @author schroeder
+ */
+ public static class DataCollector {
- }
-
- /**
- * Adds algorithmFactory by name.
- *
- * @param name
- * @param factory
- * @throws IllegalStateException if there is already an algorithmFactory with the same name
- */
- public void addAlgorithmFactory(String name, VehicleRoutingAlgorithmFactory factory){
- if(algorithmNames.contains(name)) throw new IllegalStateException("there is already a algorithmFactory with the same name (algorithmName="+name+"). unique names are required.");
- algorithms.add(new Algorithm(name,factory));
- algorithmNames.add(name);
- }
-
- public Collection getAlgorithmNames() {
- return algorithmNames;
- }
-
- public Collection getInstanceNames(){
- return instanceNames;
- }
+ public static class Key {
+ private String instanceName;
+ private String algorithmName;
+ private int run;
+ private String indicatorName;
- /**
- * Adds instance by name.
- *
- * @param name
- * @param problem
- * @throws IllegalStateException if there is already an instance with the same name.
- */
- public void addInstance(String name, VehicleRoutingProblem problem){
- if(benchmarkInstances.contains(name)) throw new IllegalStateException("there is already an instance with the same name (instanceName="+name+"). unique names are required.");
- benchmarkInstances.add(new BenchmarkInstance(name,problem,null,null));
- instanceNames.add(name);
- }
-
- /**
- * Adds instance.
- *
- * @param instance the instance to be added
- * @throws IllegalStateException if there is already an instance with the same name.
- */
- public void addInstance(BenchmarkInstance instance){
- if(benchmarkInstances.contains(instance.name)) throw new IllegalStateException("there is already an instance with the same name (instanceName="+instance.name+"). unique names are required.");
- benchmarkInstances.add(instance);
- instanceNames.add(instance.name);
- }
-
- /**
- * Adds collection of instances.
- *
- * @param instances collection of instances to be added
- * @throws IllegalStateException if there is already an instance with the same name.
- */
- public void addAllInstances(Collection instances){
- for(BenchmarkInstance i : instances){
- addInstance(i);
- }
- }
-
- /**
- * Adds instance by name, and with best known results.
- *
- * @param name
- * @param problem
- * @throws IllegalStateException if there is already an instance with the same name.
- */
- public void addInstance(String name, VehicleRoutingProblem problem, Double bestKnownResult, Double bestKnownVehicles){
- addInstance(new BenchmarkInstance(name,problem,bestKnownResult,bestKnownVehicles));
- }
-
- /**
- * Adds listener to listen computational experiments.
- *
- * @param listener
- */
- public void addListener(LabListener listener){
- if(listener instanceof CalculationListener) {
- listeners.add((CalculationListener) listener);
- }
- if(listener instanceof LabStartsAndEndsListener){
- startsAndEndslisteners.add((LabStartsAndEndsListener) listener);
- }
- }
-
- /**
- * Sets nuOfRuns with same algorithm on same instance.
- * Default is 1
- *
- * @param runs
- */
- public void setNuOfRuns(int runs){
- this.runs = runs;
- }
-
- /**
- * Runs experiments.
- *
- *
If nuThreads > 1 it runs them concurrently, i.e. individual runs are distributed to available threads. Therefore
- * a unique task is defined by its algorithmName, instanceName and its runNumber.
- *
If you have one algorithm called "myAlgorithm" and one instance called "myInstance", and you need to run "myAlgorithm" on "myInstance" three times
- * with three threads then "myAlgorithm","myInstance",run1 runs on the first thread, "myAlgorithm", "myInstance", run2 on the second etc.
- *
You can register whatever analysisTool you require by implementing and registering CalculationListener. Then your tool is informed just
- * before a calculation starts as well as just after a calculation has been finished.
- *
- * @see CalculationListener
- * @throws IllegalStateException if either no algorithm or no instance has been specified
- */
- public void run(){
- if(algorithms.isEmpty()){
- throw new IllegalStateException("no algorithm specified. at least one algorithm needs to be specified.");
- }
- if(benchmarkInstances.isEmpty()){
- throw new IllegalStateException("no instance specified. at least one instance needs to be specified.");
- }
- informStart();
- System.out.println("start benchmarking [nuAlgorithms="+algorithms.size()+"][nuInstances=" + benchmarkInstances.size() + "][runsPerInstance=" + runs + "]");
- double startTime = System.currentTimeMillis();
- ExecutorService executor = Executors.newFixedThreadPool(threads);
- for(final Algorithm algorithm : algorithms){
- for(final BenchmarkInstance p : benchmarkInstances){
- for(int run=0;runBy default: nuThreads = Runtime.getRuntime().availableProcessors()+1
- *
- * @param threads
- */
- public void setThreads(int threads) {
- this.threads = threads;
- }
+ public String getIndicatorName() {
+ return indicatorName;
+ }
- private void runAlgorithm(BenchmarkInstance p, Algorithm algorithm, int run) {
- System.out.println("[algorithm=" + algorithm.name + "][instance="+p.name+"][run="+run+"][status=start]");
- VehicleRoutingAlgorithm vra = algorithm.factory.createAlgorithm(p.vrp);
- informCalculationStarts(p, algorithm.name, vra, run);
- Collection solutions = vra.searchSolutions();
- System.out.println("[algorithm=" + algorithm.name + "][instance="+p.name+"][run="+run+"][status=finished]");
- informCalculationsEnds(p, algorithm.name, vra, run, solutions);
- }
+ @Override
+ public String toString() {
+ return "[algorithm=" + algorithmName + "][instance=" + instanceName + "][run=" + run + "][indicator=" + indicatorName + "]";
+ }
- private void informCalculationStarts(BenchmarkInstance p, String name, VehicleRoutingAlgorithm vra, int run) {
- for(CalculationListener l : listeners) l.calculationStarts(p, name, vra, run);
- }
+ }
- private void informCalculationsEnds(BenchmarkInstance p, String name, VehicleRoutingAlgorithm vra, int run,
- Collection solutions) {
- for(CalculationListener l : listeners) l.calculationEnds(p, name, vra, run, solutions);
- }
+ private final static String SOLUTION_INDICATOR_NAME = "vehicle-routing-problem-solution";
+
+ private ConcurrentHashMap data = new ConcurrentHashMap();
+
+ private ConcurrentHashMap solutions = new ConcurrentHashMap();
+
+ /**
+ * Adds a single date by instanceName, algorithmName, run and indicatorName.
+ * If there is already an entry for this instance, algorithm, run and indicatorName, it is overwritten.
+ *
+ * @param instanceName
+ * @param algorithmName
+ * @param run
+ * @param indicatorName
+ * @param value
+ */
+ public void addDate(String instanceName, String algorithmName, int run, String indicatorName, double value) {
+ if (indicatorName.equals(SOLUTION_INDICATOR_NAME))
+ throw new IllegalArgumentException(indicatorName + " is already used internally. please choose another indicator-name.");
+ Key key = new Key(instanceName, algorithmName, run, indicatorName);
+ data.put(key, value);
+ }
+
+ public void addSolution(String instanceName, String algorithmName, int run, VehicleRoutingProblemSolution solution) {
+ Key key = new Key(instanceName, algorithmName, run, SOLUTION_INDICATOR_NAME);
+ solutions.put(key, solution);
+ }
+
+ /**
+ * Returns a collections of indicator values representing the calculated values of individual runs.
+ *
+ * @param instanceName
+ * @param algorithmName
+ * @param indicator
+ * @return
+ */
+ public Collection getData(String instanceName, String algorithmName, String indicator) {
+ List values = new ArrayList();
+ for (Key key : data.keySet()) {
+ if (key.getAlgorithmName().equals(algorithmName) && key.getInstanceName().equals(instanceName) && key.getIndicatorName().equals(indicator)) {
+ values.add(data.get(key));
+ }
+ }
+ return values;
+ }
+
+ /**
+ * Returns indicator value.
+ *
+ * @param instanceName
+ * @param algorithmName
+ * @param run
+ * @param indicator
+ * @return
+ */
+ public Double getDate(String instanceName, String algorithmName, int run, String indicator) {
+ return data.get(new Key(instanceName, algorithmName, run, indicator));
+ }
+
+ public VehicleRoutingProblemSolution getSolution(String instanceName, String algorithmName, int run) {
+ return solutions.get(new Key(instanceName, algorithmName, run, "solution"));
+ }
+
+ /**
+ * Returns all keys that have been created. A key is a unique combination of algorithmName, instanceName, run and indicator.
+ *
+ * @return
+ */
+ public Set getDataKeySet() {
+ return data.keySet();
+ }
+
+ public Set getSolutionKeySet() {
+ return solutions.keySet();
+ }
+
+ public VehicleRoutingProblemSolution getSolution(Key solutionKey) {
+ return solutions.get(solutionKey);
+ }
+
+ public Collection getSolutions() {
+ return solutions.values();
+ }
+
+ /**
+ * Returns date associated to specified key.
+ *
+ * @param key
+ * @return
+ */
+ public Double getData(Key key) {
+ return data.get(key);
+ }
+
+ }
+
+
+ private static class Algorithm {
+
+ private String name;
+
+ private VehicleRoutingAlgorithmFactory factory;
+
+ public Algorithm(String name, VehicleRoutingAlgorithmFactory factory) {
+ super();
+ this.name = name;
+ this.factory = factory;
+ }
+
+ }
+
+ private List benchmarkInstances = new ArrayList();
+
+ private int runs = 1;
+
+ private Collection listeners = new ArrayList();
+
+ private Collection startsAndEndslisteners = new ArrayList();
+
+ private List algorithms = new ArrayList();
+
+ private Set algorithmNames = new HashSet();
+
+ private Set instanceNames = new HashSet();
+
+ private int threads = 1;
+
+ public ComputationalLaboratory() {
+
+ }
+
+ /**
+ * Adds algorithmFactory by name.
+ *
+ * @param name
+ * @param factory
+ * @throws IllegalStateException if there is already an algorithmFactory with the same name
+ */
+ public void addAlgorithmFactory(String name, VehicleRoutingAlgorithmFactory factory) {
+ if (algorithmNames.contains(name))
+ throw new IllegalStateException("there is already a algorithmFactory with the same name (algorithmName=" + name + "). unique names are required.");
+ algorithms.add(new Algorithm(name, factory));
+ algorithmNames.add(name);
+ }
+
+ public Collection getAlgorithmNames() {
+ return algorithmNames;
+ }
+
+ public Collection getInstanceNames() {
+ return instanceNames;
+ }
+
+ /**
+ * Adds instance by name.
+ *
+ * @param name
+ * @param problem
+ * @throws IllegalStateException if there is already an instance with the same name.
+ */
+ public void addInstance(String name, VehicleRoutingProblem problem) {
+ if (benchmarkInstances.contains(name))
+ throw new IllegalStateException("there is already an instance with the same name (instanceName=" + name + "). unique names are required.");
+ benchmarkInstances.add(new BenchmarkInstance(name, problem, null, null));
+ instanceNames.add(name);
+ }
+
+ /**
+ * Adds instance.
+ *
+ * @param instance the instance to be added
+ * @throws IllegalStateException if there is already an instance with the same name.
+ */
+ public void addInstance(BenchmarkInstance instance) {
+ if (benchmarkInstances.contains(instance.name))
+ throw new IllegalStateException("there is already an instance with the same name (instanceName=" + instance.name + "). unique names are required.");
+ benchmarkInstances.add(instance);
+ instanceNames.add(instance.name);
+ }
+
+ /**
+ * Adds collection of instances.
+ *
+ * @param instances collection of instances to be added
+ * @throws IllegalStateException if there is already an instance with the same name.
+ */
+ public void addAllInstances(Collection instances) {
+ for (BenchmarkInstance i : instances) {
+ addInstance(i);
+ }
+ }
+
+ /**
+ * Adds instance by name, and with best known results.
+ *
+ * @param name
+ * @param problem
+ * @throws IllegalStateException if there is already an instance with the same name.
+ */
+ public void addInstance(String name, VehicleRoutingProblem problem, Double bestKnownResult, Double bestKnownVehicles) {
+ addInstance(new BenchmarkInstance(name, problem, bestKnownResult, bestKnownVehicles));
+ }
+
+ /**
+ * Adds listener to listen computational experiments.
+ *
+ * @param listener
+ */
+ public void addListener(LabListener listener) {
+ if (listener instanceof CalculationListener) {
+ listeners.add((CalculationListener) listener);
+ }
+ if (listener instanceof LabStartsAndEndsListener) {
+ startsAndEndslisteners.add((LabStartsAndEndsListener) listener);
+ }
+ }
+
+ /**
+ * Sets nuOfRuns with same algorithm on same instance.
+ * Default is 1
+ *
+ * @param runs
+ */
+ public void setNuOfRuns(int runs) {
+ this.runs = runs;
+ }
+
+ /**
+ * Runs experiments.
+ *
+ * If nuThreads > 1 it runs them concurrently, i.e. individual runs are distributed to available threads. Therefore
+ * a unique task is defined by its algorithmName, instanceName and its runNumber.
+ *
If you have one algorithm called "myAlgorithm" and one instance called "myInstance", and you need to run "myAlgorithm" on "myInstance" three times
+ * with three threads then "myAlgorithm","myInstance",run1 runs on the first thread, "myAlgorithm", "myInstance", run2 on the second etc.
+ *
You can register whatever analysisTool you require by implementing and registering CalculationListener. Then your tool is informed just
+ * before a calculation starts as well as just after a calculation has been finished.
+ *
+ * @throws IllegalStateException if either no algorithm or no instance has been specified
+ * @see CalculationListener
+ */
+ public void run() {
+ if (algorithms.isEmpty()) {
+ throw new IllegalStateException("no algorithm specified. at least one algorithm needs to be specified.");
+ }
+ if (benchmarkInstances.isEmpty()) {
+ throw new IllegalStateException("no instance specified. at least one instance needs to be specified.");
+ }
+ informStart();
+ System.out.println("start benchmarking [nuAlgorithms=" + algorithms.size() + "][nuInstances=" + benchmarkInstances.size() + "][runsPerInstance=" + runs + "]");
+ double startTime = System.currentTimeMillis();
+ ExecutorService executor = Executors.newFixedThreadPool(threads);
+ for (final Algorithm algorithm : algorithms) {
+ for (final BenchmarkInstance p : benchmarkInstances) {
+ for (int run = 0; run < runs; run++) {
+ final int r = run;
+ try {
+ executor.submit(new Runnable() {
+
+ @Override
+ public void run() {
+ runAlgorithm(p, algorithm, r + 1);
+ }
+
+ });
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ }
+ try {
+ executor.shutdown();
+ executor.awaitTermination(Long.MAX_VALUE, TimeUnit.MINUTES);
+
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ System.out.println("benchmarking done [time=" + (System.currentTimeMillis() - startTime) / 1000 + "sec]");
+ informEnd();
+ }
+
+ private void informEnd() {
+ for (LabStartsAndEndsListener l : startsAndEndslisteners) {
+ l.labEnds();
+ }
+ }
+
+ private void informStart() {
+ for (LabStartsAndEndsListener l : startsAndEndslisteners) {
+ l.labStarts(benchmarkInstances, algorithms.size(), runs);
+ }
+ }
+
+ /**
+ * Sets number of threads.
+ *
By default: nuThreads = Runtime.getRuntime().availableProcessors()+1
+ *
+ * @param threads
+ */
+ public void setThreads(int threads) {
+ this.threads = threads;
+ }
+
+ private void runAlgorithm(BenchmarkInstance p, Algorithm algorithm, int run) {
+ System.out.println("[algorithm=" + algorithm.name + "][instance=" + p.name + "][run=" + run + "][status=start]");
+ VehicleRoutingAlgorithm vra = algorithm.factory.createAlgorithm(p.vrp);
+ informCalculationStarts(p, algorithm.name, vra, run);
+ Collection solutions = vra.searchSolutions();
+ System.out.println("[algorithm=" + algorithm.name + "][instance=" + p.name + "][run=" + run + "][status=finished]");
+ informCalculationsEnds(p, algorithm.name, vra, run, solutions);
+ }
+
+ private void informCalculationStarts(BenchmarkInstance p, String name, VehicleRoutingAlgorithm vra, int run) {
+ for (CalculationListener l : listeners) l.calculationStarts(p, name, vra, run);
+ }
+
+ private void informCalculationsEnds(BenchmarkInstance p, String name, VehicleRoutingAlgorithm vra, int run,
+ Collection solutions) {
+ for (CalculationListener l : listeners) l.calculationEnds(p, name, vra, run, solutions);
+ }
}
diff --git a/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/ConcurrentBenchmarker.java b/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/ConcurrentBenchmarker.java
index 7b7a8e0b..67586c60 100644
--- a/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/ConcurrentBenchmarker.java
+++ b/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/ConcurrentBenchmarker.java
@@ -1,17 +1,17 @@
/*******************************************************************************
* Copyright (C) 2013 Stefan Schroeder
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
+ * License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
+ *
+ * You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see .
******************************************************************************/
package jsprit.analysis.toolbox;
@@ -35,185 +35,185 @@ import java.util.concurrent.*;
public class ConcurrentBenchmarker {
-
- public static interface Cost {
- public double getCost(VehicleRoutingProblemSolution sol);
- }
-
-
-
- private String algorithmConfig = null;
-
- private List benchmarkInstances = new ArrayList();
- private int runs = 1;
-
- private Collection writers = new ArrayList();
-
- private Collection results = new ArrayList();
-
- private Cost cost = new Cost(){
+ public static interface Cost {
+ public double getCost(VehicleRoutingProblemSolution sol);
+ }
- @Override
- public double getCost(VehicleRoutingProblemSolution sol) {
- return sol.getCost();
- }
-
- };
- private VehicleRoutingAlgorithmFactory algorithmFactory;
-
- public void setCost(Cost cost){ this.cost = cost; }
-
- public ConcurrentBenchmarker(String algorithmConfig) {
- super();
- this.algorithmConfig = algorithmConfig;
+ private String algorithmConfig = null;
+
+ private List benchmarkInstances = new ArrayList();
+
+ private int runs = 1;
+
+ private Collection writers = new ArrayList();
+
+ private Collection results = new ArrayList();
+
+ private Cost cost = new Cost() {
+
+ @Override
+ public double getCost(VehicleRoutingProblemSolution sol) {
+ return sol.getCost();
+ }
+
+ };
+
+ private VehicleRoutingAlgorithmFactory algorithmFactory;
+
+ public void setCost(Cost cost) {
+ this.cost = cost;
+ }
+
+ public ConcurrentBenchmarker(String algorithmConfig) {
+ super();
+ this.algorithmConfig = algorithmConfig;
// LogManager.getRootLogger().setLevel(Level.ERROR);
- }
-
- public ConcurrentBenchmarker(VehicleRoutingAlgorithmFactory algorithmFactory){
- this.algorithmFactory = algorithmFactory;
- }
-
- public void addBenchmarkWriter(BenchmarkWriter writer){
- writers.add(writer);
- }
+ }
- public void addInstance(String name, VehicleRoutingProblem problem){
- benchmarkInstances.add(new BenchmarkInstance(name,problem,null,null));
- }
-
- public void addInstane(BenchmarkInstance instance){
- benchmarkInstances.add(instance);
- }
-
- public void addAllInstances(Collection instances){
- benchmarkInstances.addAll(instances);
- }
-
- public void addInstance(String name, VehicleRoutingProblem problem, Double bestKnownResult, Double bestKnownVehicles){
- benchmarkInstances.add(new BenchmarkInstance(name,problem,bestKnownResult,bestKnownVehicles));
- }
-
- /**
- * Sets nuOfRuns with same algorithm on same instance.
- * Default is 1
- *
- * @param runs
- */
- public void setNuOfRuns(int runs){
- this.runs = runs;
- }
-
- public void run(){
- System.out.println("start benchmarking [nuOfInstances=" + benchmarkInstances.size() + "][runsPerInstance=" + runs + "]");
- double startTime = System.currentTimeMillis();
- ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()+1);
- List> futures = new ArrayList>();
- for(final BenchmarkInstance p : benchmarkInstances){
-
- Future futureResult = executor.submit(new Callable(){
+ public ConcurrentBenchmarker(VehicleRoutingAlgorithmFactory algorithmFactory) {
+ this.algorithmFactory = algorithmFactory;
+ }
- @Override
- public BenchmarkResult call() throws Exception {
- return runAlgoAndGetResult(p);
- }
+ public void addBenchmarkWriter(BenchmarkWriter writer) {
+ writers.add(writer);
+ }
- });
- futures.add(futureResult);
-
- }
- try {
- int count = 1;
- for(Future f : futures){
- BenchmarkResult r = f.get();
- print(r,count);
- results.add(f.get());
- count++;
- }
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (ExecutionException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- executor.shutdown();
- print(results);
- System.out.println("done [time="+(System.currentTimeMillis()-startTime)/1000 + "sec]");
- }
+ public void addInstance(String name, VehicleRoutingProblem problem) {
+ benchmarkInstances.add(new BenchmarkInstance(name, problem, null, null));
+ }
- private BenchmarkResult runAlgoAndGetResult(BenchmarkInstance p) {
- double[] vehicles = new double[runs];
- double[] results = new double[runs];
- double[] times = new double[runs];
-
- for(int run=0;run solutions = vra.searchSolutions();
- VehicleRoutingProblemSolution best = Solutions.bestOf(solutions);
- vehicles[run] = best.getRoutes().size();
- results[run] = cost.getCost(best);
- times[run] = stopwatch.getCompTimeInSeconds();
- }
-
- return new BenchmarkResult(p, runs, results, times, vehicles);
- }
+ public void addInstane(BenchmarkInstance instance) {
+ benchmarkInstances.add(instance);
+ }
- private VehicleRoutingAlgorithm createAlgorithm(BenchmarkInstance p) {
- if(algorithmConfig != null){
- return VehicleRoutingAlgorithms.readAndCreateAlgorithm(p.vrp, algorithmConfig);
- }
- else{
- return algorithmFactory.createAlgorithm(p.vrp);
- }
-
- }
+ public void addAllInstances(Collection instances) {
+ benchmarkInstances.addAll(instances);
+ }
- private void print(Collection results) {
- double sumTime=0.0;
- double sumResult=0.0;
- for(BenchmarkResult r : results){
- sumTime+=r.getTimesStats().getMean();
- sumResult+=r.getResultStats().getMean();
+ public void addInstance(String name, VehicleRoutingProblem problem, Double bestKnownResult, Double bestKnownVehicles) {
+ benchmarkInstances.add(new BenchmarkInstance(name, problem, bestKnownResult, bestKnownVehicles));
+ }
+
+ /**
+ * Sets nuOfRuns with same algorithm on same instance.
+ * Default is 1
+ *
+ * @param runs
+ */
+ public void setNuOfRuns(int runs) {
+ this.runs = runs;
+ }
+
+ public void run() {
+ System.out.println("start benchmarking [nuOfInstances=" + benchmarkInstances.size() + "][runsPerInstance=" + runs + "]");
+ double startTime = System.currentTimeMillis();
+ ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() + 1);
+ List> futures = new ArrayList>();
+ for (final BenchmarkInstance p : benchmarkInstances) {
+
+ Future futureResult = executor.submit(new Callable() {
+
+ @Override
+ public BenchmarkResult call() throws Exception {
+ return runAlgoAndGetResult(p);
+ }
+
+ });
+ futures.add(futureResult);
+
+ }
+ try {
+ int count = 1;
+ for (Future f : futures) {
+ BenchmarkResult r = f.get();
+ print(r, count);
+ results.add(f.get());
+ count++;
+ }
+ } catch (InterruptedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (ExecutionException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ executor.shutdown();
+ print(results);
+ System.out.println("done [time=" + (System.currentTimeMillis() - startTime) / 1000 + "sec]");
+ }
+
+ private BenchmarkResult runAlgoAndGetResult(BenchmarkInstance p) {
+ double[] vehicles = new double[runs];
+ double[] results = new double[runs];
+ double[] times = new double[runs];
+
+ for (int run = 0; run < runs; run++) {
+ VehicleRoutingAlgorithm vra = createAlgorithm(p);
+ StopWatch stopwatch = new StopWatch();
+ vra.getAlgorithmListeners().addListener(stopwatch, Priority.HIGH);
+ Collection solutions = vra.searchSolutions();
+ VehicleRoutingProblemSolution best = Solutions.bestOf(solutions);
+ vehicles[run] = best.getRoutes().size();
+ results[run] = cost.getCost(best);
+ times[run] = stopwatch.getCompTimeInSeconds();
+ }
+
+ return new BenchmarkResult(p, runs, results, times, vehicles);
+ }
+
+ private VehicleRoutingAlgorithm createAlgorithm(BenchmarkInstance p) {
+ if (algorithmConfig != null) {
+ return VehicleRoutingAlgorithms.readAndCreateAlgorithm(p.vrp, algorithmConfig);
+ } else {
+ return algorithmFactory.createAlgorithm(p.vrp);
+ }
+
+ }
+
+ private void print(Collection results) {
+ double sumTime = 0.0;
+ double sumResult = 0.0;
+ for (BenchmarkResult r : results) {
+ sumTime += r.getTimesStats().getMean();
+ sumResult += r.getResultStats().getMean();
// print(r);
- }
- System.out.println("[avgTime="+round(sumTime/(double)results.size(),2)+"][avgResult="+round(sumResult/(double)results.size(),2)+"]");
- for(BenchmarkWriter writer : writers){
- writer.write(results);
- }
- }
+ }
+ System.out.println("[avgTime=" + round(sumTime / (double) results.size(), 2) + "][avgResult=" + round(sumResult / (double) results.size(), 2) + "]");
+ for (BenchmarkWriter writer : writers) {
+ writer.write(results);
+ }
+ }
- private void print(BenchmarkResult r, int count) {
- Double avgDelta = null;
- Double bestDelta = null;
- Double worstDelta = null;
- if(r.instance.bestKnownResult != null){
- avgDelta = (r.getResultStats().getMean() / r.instance.bestKnownResult - 1) * 100;
- bestDelta = (r.getResultStats().getMin() / r.instance.bestKnownResult - 1) * 100;
- worstDelta = (r.getResultStats().getMax() / r.instance.bestKnownResult - 1) * 100;
- }
- System.out.println("("+count+"/"+benchmarkInstances.size() +")"+ "\t[instance="+r.instance.name+
- "][avgTime="+round(r.getTimesStats().getMean(),2)+"]" +
- "[Result=" + getString(r.getResultStats()) + "]" +
- "[Vehicles=" + getString(r.getVehicleStats()) + "]" +
- "[Delta[%]=" + getString(bestDelta,avgDelta,worstDelta) + "]");
- }
-
- private String getString(Double bestDelta, Double avgDelta,Double worstDelta) {
- return "[best="+round(bestDelta,2)+"][avg="+round(avgDelta,2)+"][worst="+round(worstDelta,2)+"]";
- }
+ private void print(BenchmarkResult r, int count) {
+ Double avgDelta = null;
+ Double bestDelta = null;
+ Double worstDelta = null;
+ if (r.instance.bestKnownResult != null) {
+ avgDelta = (r.getResultStats().getMean() / r.instance.bestKnownResult - 1) * 100;
+ bestDelta = (r.getResultStats().getMin() / r.instance.bestKnownResult - 1) * 100;
+ worstDelta = (r.getResultStats().getMax() / r.instance.bestKnownResult - 1) * 100;
+ }
+ System.out.println("(" + count + "/" + benchmarkInstances.size() + ")" + "\t[instance=" + r.instance.name +
+ "][avgTime=" + round(r.getTimesStats().getMean(), 2) + "]" +
+ "[Result=" + getString(r.getResultStats()) + "]" +
+ "[Vehicles=" + getString(r.getVehicleStats()) + "]" +
+ "[Delta[%]=" + getString(bestDelta, avgDelta, worstDelta) + "]");
+ }
- private String getString(DescriptiveStatistics stats){
- return "[best="+round(stats.getMin(),2)+"][avg="+round(stats.getMean(),2)+"][worst="+round(stats.getMax(),2)+"][stdDev=" + round(stats.getStandardDeviation(),2)+"]";
- }
+ private String getString(Double bestDelta, Double avgDelta, Double worstDelta) {
+ return "[best=" + round(bestDelta, 2) + "][avg=" + round(avgDelta, 2) + "][worst=" + round(worstDelta, 2) + "]";
+ }
- private Double round(Double value, int i) {
- if(value==null) return null;
- long roundedVal = Math.round(value*Math.pow(10, i));
- return (double)roundedVal/(double)(Math.pow(10, i));
- }
+ private String getString(DescriptiveStatistics stats) {
+ return "[best=" + round(stats.getMin(), 2) + "][avg=" + round(stats.getMean(), 2) + "][worst=" + round(stats.getMax(), 2) + "][stdDev=" + round(stats.getStandardDeviation(), 2) + "]";
+ }
+
+ private Double round(Double value, int i) {
+ if (value == null) return null;
+ long roundedVal = Math.round(value * Math.pow(10, i));
+ return (double) roundedVal / (double) (Math.pow(10, i));
+ }
}
diff --git a/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/GraphStreamViewer.java b/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/GraphStreamViewer.java
index 673f7a1b..6e8e2a26 100644
--- a/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/GraphStreamViewer.java
+++ b/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/GraphStreamViewer.java
@@ -46,55 +46,55 @@ public class GraphStreamViewer {
public static class StyleSheets {
public static String BLUE_FOREST =
- "graph { fill-color: #141F2E; }" +
- "node {" +
- " size: 7px, 7px;" +
- " fill-color: #A0FFA0;" +
- " text-alignment: at-right;" +
- " stroke-mode: plain;" +
- " stroke-color: #999;" +
- " stroke-width: 1.0;" +
- " text-font: couriernew;" +
- " text-offset: 2,-5;" +
- " text-size: 8;" +
- "}" +
- "node.pickup {" +
- " fill-color: #6CC644;" +
- "}" +
- "node.delivery {" +
- " fill-color: #f93;" +
- "}" +
- "node.pickupInRoute {" +
- " fill-color: #6CC644;" +
- " stroke-mode: plain;" +
- " stroke-color: #333;" +
- " stroke-width: 2.0;" +
- "}" +
- "node.deliveryInRoute {" +
- " fill-color: #f93;" +
- " stroke-mode: plain;" +
- " stroke-color: #333;" +
- " stroke-width: 2.0;" +
- "}" +
- "node.depot {" +
- " fill-color: #BD2C00;" +
- " size: 10px, 10px;" +
- " shape: box;" +
- "}" +
- "node.removed {" +
- " fill-color: #FF8080;" +
- " size: 10px, 10px;" +
- " stroke-mode: plain;" +
- " stroke-color: #CCF;" +
- " stroke-width: 2.0;" +
- " shadow-mode: gradient-radial;" +
- " shadow-width: 10px; shadow-color: #EEF, #000; shadow-offset: 0px;" +
- "}" +
+ "graph { fill-color: #141F2E; }" +
+ "node {" +
+ " size: 7px, 7px;" +
+ " fill-color: #A0FFA0;" +
+ " text-alignment: at-right;" +
+ " stroke-mode: plain;" +
+ " stroke-color: #999;" +
+ " stroke-width: 1.0;" +
+ " text-font: couriernew;" +
+ " text-offset: 2,-5;" +
+ " text-size: 8;" +
+ "}" +
+ "node.pickup {" +
+ " fill-color: #6CC644;" +
+ "}" +
+ "node.delivery {" +
+ " fill-color: #f93;" +
+ "}" +
+ "node.pickupInRoute {" +
+ " fill-color: #6CC644;" +
+ " stroke-mode: plain;" +
+ " stroke-color: #333;" +
+ " stroke-width: 2.0;" +
+ "}" +
+ "node.deliveryInRoute {" +
+ " fill-color: #f93;" +
+ " stroke-mode: plain;" +
+ " stroke-color: #333;" +
+ " stroke-width: 2.0;" +
+ "}" +
+ "node.depot {" +
+ " fill-color: #BD2C00;" +
+ " size: 10px, 10px;" +
+ " shape: box;" +
+ "}" +
+ "node.removed {" +
+ " fill-color: #FF8080;" +
+ " size: 10px, 10px;" +
+ " stroke-mode: plain;" +
+ " stroke-color: #CCF;" +
+ " stroke-width: 2.0;" +
+ " shadow-mode: gradient-radial;" +
+ " shadow-width: 10px; shadow-color: #EEF, #000; shadow-offset: 0px;" +
+ "}" +
- "edge {" +
- " fill-color: #D3D3D3;" +
- " arrow-size: 6px,3px;" +
- "}" +
+ "edge {" +
+ " fill-color: #D3D3D3;" +
+ " arrow-size: 6px,3px;" +
+ "}" +
// "edge.inserted {" +
// " fill-color: #A0FFA0;" +
// " arrow-size: 6px,3px;" +
@@ -107,69 +107,68 @@ public class GraphStreamViewer {
// " shadow-mode: gradient-radial;" +
// " shadow-width: 10px; shadow-color: #EEF, #000; shadow-offset: 0px;" +
// "}" +
- "edge.shipment {" +
- " fill-color: #999;" +
- " arrow-size: 6px,3px;" +
- "}" ;
-
+ "edge.shipment {" +
+ " fill-color: #999;" +
+ " arrow-size: 6px,3px;" +
+ "}";
@SuppressWarnings("UnusedDeclaration")
public static String SIMPLE_WHITE =
- "node {" +
- " size: 10px, 10px;" +
- " fill-color: #6CC644;" +
- " text-alignment: at-right;" +
- " stroke-mode: plain;" +
- " stroke-color: #999;" +
- " stroke-width: 1.0;" +
- " text-font: couriernew;" +
- " text-offset: 2,-5;" +
- " text-size: 8;" +
- "}" +
- "node.pickup {" +
- " fill-color: #6CC644;" +
- "}" +
- "node.delivery {" +
- " fill-color: #f93;" +
- "}" +
- "node.pickupInRoute {" +
- " fill-color: #6CC644;" +
- " stroke-mode: plain;" +
- " stroke-color: #333;" +
- " stroke-width: 2.0;" +
- "}" +
- "node.deliveryInRoute {" +
- " fill-color: #f93;" +
- " stroke-mode: plain;" +
- " stroke-color: #333;" +
- " stroke-width: 2.0;" +
- "}" +
- "node.depot {" +
- " fill-color: #BD2C00;" +
- " size: 10px, 10px;" +
- " shape: box;" +
- "}" +
- "node.removed {" +
- " fill-color: #BD2C00;" +
- " size: 10px, 10px;" +
- " stroke-mode: plain;" +
- " stroke-color: #333;" +
- " stroke-width: 2.0;" +
- "}" +
+ "node {" +
+ " size: 10px, 10px;" +
+ " fill-color: #6CC644;" +
+ " text-alignment: at-right;" +
+ " stroke-mode: plain;" +
+ " stroke-color: #999;" +
+ " stroke-width: 1.0;" +
+ " text-font: couriernew;" +
+ " text-offset: 2,-5;" +
+ " text-size: 8;" +
+ "}" +
+ "node.pickup {" +
+ " fill-color: #6CC644;" +
+ "}" +
+ "node.delivery {" +
+ " fill-color: #f93;" +
+ "}" +
+ "node.pickupInRoute {" +
+ " fill-color: #6CC644;" +
+ " stroke-mode: plain;" +
+ " stroke-color: #333;" +
+ " stroke-width: 2.0;" +
+ "}" +
+ "node.deliveryInRoute {" +
+ " fill-color: #f93;" +
+ " stroke-mode: plain;" +
+ " stroke-color: #333;" +
+ " stroke-width: 2.0;" +
+ "}" +
+ "node.depot {" +
+ " fill-color: #BD2C00;" +
+ " size: 10px, 10px;" +
+ " shape: box;" +
+ "}" +
+ "node.removed {" +
+ " fill-color: #BD2C00;" +
+ " size: 10px, 10px;" +
+ " stroke-mode: plain;" +
+ " stroke-color: #333;" +
+ " stroke-width: 2.0;" +
+ "}" +
- "edge {" +
- " fill-color: #333;" +
- " arrow-size: 6px,3px;" +
- "}" +
- "edge.shipment {" +
- " fill-color: #999;" +
- " arrow-size: 6px,3px;" +
- "}" ;
+ "edge {" +
+ " fill-color: #333;" +
+ " arrow-size: 6px,3px;" +
+ "}" +
+ "edge.shipment {" +
+ " fill-color: #999;" +
+ " arrow-size: 6px,3px;" +
+ "}";
}
- public static Graph createMultiGraph(String name, String style){
+ public static Graph createMultiGraph(String name, String style) {
Graph g = new MultiGraph(name);
g.addAttribute("ui.quality");
g.addAttribute("ui.antialias");
@@ -177,162 +176,162 @@ public class GraphStreamViewer {
return g;
}
- public static ViewPanel createEmbeddedView(Graph graph, double scaling){
- Viewer viewer = new Viewer(graph,Viewer.ThreadingModel.GRAPH_IN_ANOTHER_THREAD);
+ public static ViewPanel createEmbeddedView(Graph graph, double scaling) {
+ Viewer viewer = new Viewer(graph, Viewer.ThreadingModel.GRAPH_IN_ANOTHER_THREAD);
ViewPanel view = viewer.addDefaultView(false);
view.setPreferredSize(new Dimension((int) (698 * scaling), (int) (440 * scaling)));
return view;
}
- public static String STYLESHEET =
- "node {" +
- " size: 10px, 10px;" +
- " fill-color: #6CC644;" +
- " text-alignment: at-right;" +
- " stroke-mode: plain;" +
- " stroke-color: #999;" +
- " stroke-width: 1.0;" +
- " text-font: couriernew;" +
- " text-offset: 2,-5;" +
- " text-size: 8;" +
- "}" +
- "node.pickup {" +
- " fill-color: #6CC644;" +
- "}" +
- "node.delivery {" +
- " fill-color: #f93;" +
- "}" +
- "node.pickupInRoute {" +
- " fill-color: #6CC644;" +
- " stroke-mode: plain;" +
- " stroke-color: #333;" +
- " stroke-width: 2.0;" +
- "}" +
- "node.deliveryInRoute {" +
- " fill-color: #f93;" +
- " stroke-mode: plain;" +
- " stroke-color: #333;" +
- " stroke-width: 2.0;" +
- "}" +
- "node.depot {" +
- " fill-color: #BD2C00;" +
- " size: 10px, 10px;" +
- " shape: box;" +
- "}" +
- "node.removed {" +
- " fill-color: #BD2C00;" +
- " size: 10px, 10px;" +
- " stroke-mode: plain;" +
- " stroke-color: #333;" +
- " stroke-width: 2.0;" +
- "}" +
-
- "edge {" +
- " fill-color: #333;" +
- " arrow-size: 6px,3px;" +
- "}" +
- "edge.shipment {" +
- " fill-color: #999;" +
- " arrow-size: 6px,3px;" +
- "}" ;
+ public static String STYLESHEET =
+ "node {" +
+ " size: 10px, 10px;" +
+ " fill-color: #6CC644;" +
+ " text-alignment: at-right;" +
+ " stroke-mode: plain;" +
+ " stroke-color: #999;" +
+ " stroke-width: 1.0;" +
+ " text-font: couriernew;" +
+ " text-offset: 2,-5;" +
+ " text-size: 8;" +
+ "}" +
+ "node.pickup {" +
+ " fill-color: #6CC644;" +
+ "}" +
+ "node.delivery {" +
+ " fill-color: #f93;" +
+ "}" +
+ "node.pickupInRoute {" +
+ " fill-color: #6CC644;" +
+ " stroke-mode: plain;" +
+ " stroke-color: #333;" +
+ " stroke-width: 2.0;" +
+ "}" +
+ "node.deliveryInRoute {" +
+ " fill-color: #f93;" +
+ " stroke-mode: plain;" +
+ " stroke-color: #333;" +
+ " stroke-width: 2.0;" +
+ "}" +
+ "node.depot {" +
+ " fill-color: #BD2C00;" +
+ " size: 10px, 10px;" +
+ " shape: box;" +
+ "}" +
+ "node.removed {" +
+ " fill-color: #BD2C00;" +
+ " size: 10px, 10px;" +
+ " stroke-mode: plain;" +
+ " stroke-color: #333;" +
+ " stroke-width: 2.0;" +
+ "}" +
- public static enum Label {
- NO_LABEL, ID, JOB_NAME, ARRIVAL_TIME, DEPARTURE_TIME, ACTIVITY
- }
-
- private static class Center {
- final double x;
- final double y;
-
- public Center(double x, double y) {
- super();
- this.x = x;
- this.y = y;
- }
-
- }
+ "edge {" +
+ " fill-color: #333;" +
+ " arrow-size: 6px,3px;" +
+ "}" +
+ "edge.shipment {" +
+ " fill-color: #999;" +
+ " arrow-size: 6px,3px;" +
+ "}";
- private Label label = Label.NO_LABEL;
+ public static enum Label {
+ NO_LABEL, ID, JOB_NAME, ARRIVAL_TIME, DEPARTURE_TIME, ACTIVITY
+ }
- private long renderDelay_in_ms = 0;
+ private static class Center {
+ final double x;
+ final double y;
- private boolean renderShipments = false;
-
- private Center center;
+ public Center(double x, double y) {
+ super();
+ this.x = x;
+ this.y = y;
+ }
- private VehicleRoutingProblem vrp;
+ }
- private VehicleRoutingProblemSolution solution;
+ private Label label = Label.NO_LABEL;
- private double zoomFactor;
-
- private double scaling = 1.0;
+ private long renderDelay_in_ms = 0;
+
+ private boolean renderShipments = false;
+
+ private Center center;
+
+ private VehicleRoutingProblem vrp;
+
+ private VehicleRoutingProblemSolution solution;
+
+ private double zoomFactor;
+
+ private double scaling = 1.0;
- public GraphStreamViewer(VehicleRoutingProblem vrp) {
- super();
- this.vrp = vrp;
- }
+ public GraphStreamViewer(VehicleRoutingProblem vrp) {
+ super();
+ this.vrp = vrp;
+ }
- public GraphStreamViewer(VehicleRoutingProblem vrp, VehicleRoutingProblemSolution solution) {
- super();
- this.vrp = vrp;
- this.solution = solution;
- }
+ public GraphStreamViewer(VehicleRoutingProblem vrp, VehicleRoutingProblemSolution solution) {
+ super();
+ this.vrp = vrp;
+ this.solution = solution;
+ }
- public GraphStreamViewer labelWith(Label label){
- this.label=label;
- return this;
- }
+ public GraphStreamViewer labelWith(Label label) {
+ this.label = label;
+ return this;
+ }
- public GraphStreamViewer setRenderDelay(long ms){
- this.renderDelay_in_ms=ms;
- return this;
- }
+ public GraphStreamViewer setRenderDelay(long ms) {
+ this.renderDelay_in_ms = ms;
+ return this;
+ }
@Deprecated
- public GraphStreamViewer setEnableAutoLayout(boolean enableAutoLayout) {
- return this;
- }
+ public GraphStreamViewer setEnableAutoLayout(boolean enableAutoLayout) {
+ return this;
+ }
- public GraphStreamViewer setRenderShipments(boolean renderShipments){
- this.renderShipments = renderShipments;
- return this;
- }
-
- public GraphStreamViewer setGraphStreamFrameScalingFactor(double factor){
- this.scaling=factor;
- return this;
- }
+ public GraphStreamViewer setRenderShipments(boolean renderShipments) {
+ this.renderShipments = renderShipments;
+ return this;
+ }
- /**
- * Sets the camera-view. Center describes the center-focus of the camera and zoomFactor its
- * zoomFactor.
- *
- * a zoomFactor < 1 zooms in and > 1 out.
- *
- * @param centerX x coordinate of center
- * @param centerY y coordinate of center
- * @param zoomFactor zoom factor
- * @return the viewer
- */
- public GraphStreamViewer setCameraView(double centerX, double centerY, double zoomFactor){
- center = new Center(centerX,centerY);
- this.zoomFactor = zoomFactor;
- return this;
- }
-
- public void display(){
- System.setProperty("org.graphstream.ui.renderer", "org.graphstream.ui.j2dviewer.J2DGraphRenderer");
+ public GraphStreamViewer setGraphStreamFrameScalingFactor(double factor) {
+ this.scaling = factor;
+ return this;
+ }
+
+ /**
+ * Sets the camera-view. Center describes the center-focus of the camera and zoomFactor its
+ * zoomFactor.
+ *
+ * a zoomFactor < 1 zooms in and > 1 out.
+ *
+ * @param centerX x coordinate of center
+ * @param centerY y coordinate of center
+ * @param zoomFactor zoom factor
+ * @return the viewer
+ */
+ public GraphStreamViewer setCameraView(double centerX, double centerY, double zoomFactor) {
+ center = new Center(centerX, centerY);
+ this.zoomFactor = zoomFactor;
+ return this;
+ }
+
+ public void display() {
+ System.setProperty("org.graphstream.ui.renderer", "org.graphstream.ui.j2dviewer.J2DGraphRenderer");
Graph g = createMultiGraph("g");
- ViewPanel view = createEmbeddedView(g,scaling);
+ ViewPanel view = createEmbeddedView(g, scaling);
- createJFrame(view,scaling);
+ createJFrame(view, scaling);
render(g, view);
- }
+ }
private JFrame createJFrame(ViewPanel view, double scaling) {
JFrame jframe = new JFrame();
@@ -345,11 +344,11 @@ public class GraphStreamViewer {
JPanel graphStreamPanel = new JPanel();
- graphStreamPanel.setPreferredSize(new Dimension((int)(800*scaling),(int)(460*scaling)));
+ graphStreamPanel.setPreferredSize(new Dimension((int) (800 * scaling), (int) (460 * scaling)));
graphStreamPanel.setBackground(Color.WHITE);
JPanel graphStreamBackPanel = new JPanel();
- graphStreamBackPanel.setPreferredSize(new Dimension((int)(700*scaling),(int)(450*scaling)));
+ graphStreamBackPanel.setPreferredSize(new Dimension((int) (700 * scaling), (int) (450 * scaling)));
graphStreamBackPanel.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY, 1));
graphStreamBackPanel.setBackground(Color.WHITE);
@@ -365,7 +364,7 @@ public class GraphStreamViewer {
jframe.add(basicPanel);
//conf jframe
- jframe.setSize((int)(800*scaling),(int)(580*scaling));
+ jframe.setSize((int) (800 * scaling), (int) (580 * scaling));
jframe.setLocationRelativeTo(null);
jframe.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
jframe.setVisible(true);
@@ -375,40 +374,39 @@ public class GraphStreamViewer {
}
private Graph createMultiGraph(String name) {
- return GraphStreamViewer.createMultiGraph(name,STYLESHEET);
+ return GraphStreamViewer.createMultiGraph(name, STYLESHEET);
}
private void render(Graph g, ViewPanel view) {
- if(center != null){
- view.resizeFrame(view.getWidth(), view.getHeight());
+ if (center != null) {
+ view.resizeFrame(view.getWidth(), view.getHeight());
alignCamera(view);
- }
+ }
- for(Vehicle vehicle : vrp.getVehicles()){
- renderVehicle(g,vehicle,label);
- sleep(renderDelay_in_ms);
- }
+ for (Vehicle vehicle : vrp.getVehicles()) {
+ renderVehicle(g, vehicle, label);
+ sleep(renderDelay_in_ms);
+ }
- for(Job j : vrp.getJobs().values()){
- if(j instanceof Service){
- renderService(g,(Service)j,label);
- }
- else if(j instanceof Shipment){
- renderShipment(g,(Shipment)j,label,renderShipments);
- }
- sleep(renderDelay_in_ms);
- }
+ for (Job j : vrp.getJobs().values()) {
+ if (j instanceof Service) {
+ renderService(g, (Service) j, label);
+ } else if (j instanceof Shipment) {
+ renderShipment(g, (Shipment) j, label, renderShipments);
+ }
+ sleep(renderDelay_in_ms);
+ }
- if(solution != null){
- int routeId = 1;
- for(VehicleRoute route : solution.getRoutes()){
- renderRoute(g,route,routeId,renderDelay_in_ms,label);
- sleep(renderDelay_in_ms);
- routeId++;
- }
- }
-
- }
+ if (solution != null) {
+ int routeId = 1;
+ for (VehicleRoute route : solution.getRoutes()) {
+ renderRoute(g, route, routeId, renderDelay_in_ms, label);
+ sleep(renderDelay_in_ms);
+ routeId++;
+ }
+ }
+
+ }
private void alignCamera(View view) {
view.getCamera().setViewCenter(center.x, center.y, 0);
@@ -416,204 +414,202 @@ public class GraphStreamViewer {
}
private JLabel createEmptyLabel() {
- JLabel emptyLabel1 = new JLabel();
- emptyLabel1.setPreferredSize(new Dimension((int)(40*scaling),(int)(25*scaling)));
- return emptyLabel1;
- }
+ JLabel emptyLabel1 = new JLabel();
+ emptyLabel1.setPreferredSize(new Dimension((int) (40 * scaling), (int) (25 * scaling)));
+ return emptyLabel1;
+ }
- private JPanel createResultPanel() {
- int width = 800;
- int height = 50;
-
- JPanel panel = new JPanel();
- panel.setPreferredSize(new Dimension((int)(width*scaling),(int)(height*scaling)));
+ private JPanel createResultPanel() {
+ int width = 800;
+ int height = 50;
+
+ JPanel panel = new JPanel();
+ panel.setPreferredSize(new Dimension((int) (width * scaling), (int) (height * scaling)));
panel.setBackground(Color.WHITE);
-
+
JPanel subpanel = new JPanel();
subpanel.setLayout(new FlowLayout());
- subpanel.setPreferredSize(new Dimension((int)(700*scaling),(int)(40*scaling)));
+ subpanel.setPreferredSize(new Dimension((int) (700 * scaling), (int) (40 * scaling)));
subpanel.setBackground(Color.WHITE);
- subpanel.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY,1));
-
+ subpanel.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY, 1));
+
Font font = Font.decode("couriernew");
JLabel jobs = new JLabel("jobs");
jobs.setFont(font);
- jobs.setPreferredSize(new Dimension((int)(40*scaling),(int)(25*scaling)));
+ jobs.setPreferredSize(new Dimension((int) (40 * scaling), (int) (25 * scaling)));
int noJobs = 0;
- if(this.vrp != null) noJobs = this.vrp.getJobs().values().size();
+ if (this.vrp != null) noJobs = this.vrp.getJobs().values().size();
JFormattedTextField nJobs = new JFormattedTextField(noJobs);
nJobs.setFont(font);
nJobs.setEditable(false);
nJobs.setBorder(BorderFactory.createEmptyBorder());
- nJobs.setBackground(new Color(230,230,230));
-
+ nJobs.setBackground(new Color(230, 230, 230));
+
JLabel costs = new JLabel("costs");
costs.setFont(font);
- costs.setPreferredSize(new Dimension((int)(40*scaling),(int)(25*scaling)));
+ costs.setPreferredSize(new Dimension((int) (40 * scaling), (int) (25 * scaling)));
JFormattedTextField costsVal = new JFormattedTextField(getSolutionCosts());
costsVal.setFont(font);
costsVal.setEditable(false);
costsVal.setBorder(BorderFactory.createEmptyBorder());
- costsVal.setBackground(new Color(230,230,230));
-
+ costsVal.setBackground(new Color(230, 230, 230));
+
JLabel vehicles = new JLabel("routes");
vehicles.setFont(font);
- vehicles.setPreferredSize(new Dimension((int)(40*scaling),(int)(25*scaling)));
+ vehicles.setPreferredSize(new Dimension((int) (40 * scaling), (int) (25 * scaling)));
// vehicles.setForeground(Color.DARK_GRAY);
-
+
JFormattedTextField vehVal = new JFormattedTextField(getNoRoutes());
vehVal.setFont(font);
vehVal.setEditable(false);
vehVal.setBorder(BorderFactory.createEmptyBorder());
// vehVal.setForeground(Color.DARK_GRAY);
- vehVal.setBackground(new Color(230,230,230));
-
+ vehVal.setBackground(new Color(230, 230, 230));
+
//platzhalter
JLabel placeholder1 = new JLabel();
- placeholder1.setPreferredSize(new Dimension((int)(60*scaling),(int)(25*scaling)));
-
+ placeholder1.setPreferredSize(new Dimension((int) (60 * scaling), (int) (25 * scaling)));
+
JLabel emptyLabel1 = createEmptyLabel();
-
+
subpanel.add(jobs);
subpanel.add(nJobs);
-
+
subpanel.add(emptyLabel1);
-
+
subpanel.add(costs);
subpanel.add(costsVal);
JLabel emptyLabel2 = createEmptyLabel();
subpanel.add(emptyLabel2);
-
+
subpanel.add(vehicles);
subpanel.add(vehVal);
panel.add(subpanel);
-
- return panel;
- }
- private Integer getNoRoutes() {
- if(solution!=null) return solution.getRoutes().size();
- return 0;
- }
-
- private Double getSolutionCosts() {
- if(solution!=null) return solution.getCost();
- return 0.0;
- }
-
- private void renderShipment(Graph g, Shipment shipment, Label label, boolean renderShipments) {
-
- Node n1 = g.addNode(makeId(shipment.getId(),shipment.getPickupLocation().getId()));
- if(label.equals(Label.ID)) n1.addAttribute("ui.label", shipment.getId());
- n1.addAttribute("x", shipment.getPickupLocation().getCoordinate().getX());
- n1.addAttribute("y", shipment.getPickupLocation().getCoordinate().getY());
- n1.setAttribute("ui.class", "pickup");
-
- Node n2 = g.addNode(makeId(shipment.getId(),shipment.getDeliveryLocation().getId()));
- if(label.equals(Label.ID)) n2.addAttribute("ui.label", shipment.getId());
- n2.addAttribute("x", shipment.getDeliveryLocation().getCoordinate().getX());
- n2.addAttribute("y", shipment.getDeliveryLocation().getCoordinate().getY());
- n2.setAttribute("ui.class", "delivery");
-
- if(renderShipments){
- Edge s = g.addEdge(shipment.getId(), makeId(shipment.getId(),shipment.getPickupLocation().getId()),
- makeId(shipment.getId(),shipment.getDeliveryLocation().getId()), true);
- s.addAttribute("ui.class", "shipment");
- }
-
- }
-
- private void sleep(long renderDelay_in_ms2) {
- try {
- Thread.sleep(renderDelay_in_ms2);
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
+ return panel;
}
- private void renderService(Graph g, Service service, Label label) {
- Node n = g.addNode(makeId(service.getId(),service.getLocation().getId()));
- if(label.equals(Label.ID)) n.addAttribute("ui.label", service.getId());
- n.addAttribute("x", service.getLocation().getCoordinate().getX());
- n.addAttribute("y", service.getLocation().getCoordinate().getY());
- if(service.getType().equals("pickup")) n.setAttribute("ui.class", "pickup");
- if(service.getType().equals("delivery")) n.setAttribute("ui.class", "delivery");
- }
+ private Integer getNoRoutes() {
+ if (solution != null) return solution.getRoutes().size();
+ return 0;
+ }
- private String makeId(String id, String locationId) {
- return id + "_" + locationId;
- }
+ private Double getSolutionCosts() {
+ if (solution != null) return solution.getCost();
+ return 0.0;
+ }
- private void renderVehicle(Graph g, Vehicle vehicle, Label label) {
- String nodeId = makeId(vehicle.getId(),vehicle.getStartLocation().getId());
+ private void renderShipment(Graph g, Shipment shipment, Label label, boolean renderShipments) {
+
+ Node n1 = g.addNode(makeId(shipment.getId(), shipment.getPickupLocation().getId()));
+ if (label.equals(Label.ID)) n1.addAttribute("ui.label", shipment.getId());
+ n1.addAttribute("x", shipment.getPickupLocation().getCoordinate().getX());
+ n1.addAttribute("y", shipment.getPickupLocation().getCoordinate().getY());
+ n1.setAttribute("ui.class", "pickup");
+
+ Node n2 = g.addNode(makeId(shipment.getId(), shipment.getDeliveryLocation().getId()));
+ if (label.equals(Label.ID)) n2.addAttribute("ui.label", shipment.getId());
+ n2.addAttribute("x", shipment.getDeliveryLocation().getCoordinate().getX());
+ n2.addAttribute("y", shipment.getDeliveryLocation().getCoordinate().getY());
+ n2.setAttribute("ui.class", "delivery");
+
+ if (renderShipments) {
+ Edge s = g.addEdge(shipment.getId(), makeId(shipment.getId(), shipment.getPickupLocation().getId()),
+ makeId(shipment.getId(), shipment.getDeliveryLocation().getId()), true);
+ s.addAttribute("ui.class", "shipment");
+ }
+
+ }
+
+ private void sleep(long renderDelay_in_ms2) {
+ try {
+ Thread.sleep(renderDelay_in_ms2);
+ } catch (InterruptedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ private void renderService(Graph g, Service service, Label label) {
+ Node n = g.addNode(makeId(service.getId(), service.getLocation().getId()));
+ if (label.equals(Label.ID)) n.addAttribute("ui.label", service.getId());
+ n.addAttribute("x", service.getLocation().getCoordinate().getX());
+ n.addAttribute("y", service.getLocation().getCoordinate().getY());
+ if (service.getType().equals("pickup")) n.setAttribute("ui.class", "pickup");
+ if (service.getType().equals("delivery")) n.setAttribute("ui.class", "delivery");
+ }
+
+ private String makeId(String id, String locationId) {
+ return id + "_" + locationId;
+ }
+
+ private void renderVehicle(Graph g, Vehicle vehicle, Label label) {
+ String nodeId = makeId(vehicle.getId(), vehicle.getStartLocation().getId());
Node vehicleStart = g.addNode(nodeId);
- if(label.equals(Label.ID)) vehicleStart.addAttribute("ui.label", "depot");
+ if (label.equals(Label.ID)) vehicleStart.addAttribute("ui.label", "depot");
// if(label.equals(Label.ACTIVITY)) n.addAttribute("ui.label", "start");
- vehicleStart.addAttribute("x", vehicle.getStartLocation().getCoordinate().getX());
- vehicleStart.addAttribute("y", vehicle.getStartLocation().getCoordinate().getY());
- vehicleStart.setAttribute("ui.class", "depot");
-
- if(!vehicle.getStartLocation().getId().equals(vehicle.getEndLocation().getId())){
- Node vehicleEnd = g.addNode(makeId(vehicle.getId(),vehicle.getEndLocation().getId()));
- if(label.equals(Label.ID)) vehicleEnd.addAttribute("ui.label", "depot");
- vehicleEnd.addAttribute("x", vehicle.getEndLocation().getCoordinate().getX());
- vehicleEnd.addAttribute("y", vehicle.getEndLocation().getCoordinate().getY());
- vehicleEnd.setAttribute("ui.class", "depot");
-
- }
- }
+ vehicleStart.addAttribute("x", vehicle.getStartLocation().getCoordinate().getX());
+ vehicleStart.addAttribute("y", vehicle.getStartLocation().getCoordinate().getY());
+ vehicleStart.setAttribute("ui.class", "depot");
- private void renderRoute(Graph g, VehicleRoute route, int routeId, long renderDelay_in_ms, Label label) {
- int vehicle_edgeId = 1;
- String prevIdentifier = makeId(route.getVehicle().getId(),route.getVehicle().getStartLocation().getId());
- if(label.equals(Label.ACTIVITY) || label.equals(Label.JOB_NAME)){
- Node n = g.getNode(prevIdentifier);
- n.addAttribute("ui.label", "start");
- }
- for(TourActivity act : route.getActivities()){
+ if (!vehicle.getStartLocation().getId().equals(vehicle.getEndLocation().getId())) {
+ Node vehicleEnd = g.addNode(makeId(vehicle.getId(), vehicle.getEndLocation().getId()));
+ if (label.equals(Label.ID)) vehicleEnd.addAttribute("ui.label", "depot");
+ vehicleEnd.addAttribute("x", vehicle.getEndLocation().getCoordinate().getX());
+ vehicleEnd.addAttribute("y", vehicle.getEndLocation().getCoordinate().getY());
+ vehicleEnd.setAttribute("ui.class", "depot");
+
+ }
+ }
+
+ private void renderRoute(Graph g, VehicleRoute route, int routeId, long renderDelay_in_ms, Label label) {
+ int vehicle_edgeId = 1;
+ String prevIdentifier = makeId(route.getVehicle().getId(), route.getVehicle().getStartLocation().getId());
+ if (label.equals(Label.ACTIVITY) || label.equals(Label.JOB_NAME)) {
+ Node n = g.getNode(prevIdentifier);
+ n.addAttribute("ui.label", "start");
+ }
+ for (TourActivity act : route.getActivities()) {
Job job = ((JobActivity) act).getJob();
- String currIdentifier = makeId(job.getId(),act.getLocation().getId());
- if(label.equals(Label.ACTIVITY)){
- Node actNode = g.getNode(currIdentifier);
- actNode.addAttribute("ui.label", act.getName());
- }
- else if(label.equals(Label.JOB_NAME)){
+ String currIdentifier = makeId(job.getId(), act.getLocation().getId());
+ if (label.equals(Label.ACTIVITY)) {
+ Node actNode = g.getNode(currIdentifier);
+ actNode.addAttribute("ui.label", act.getName());
+ } else if (label.equals(Label.JOB_NAME)) {
Node actNode = g.getNode(currIdentifier);
actNode.addAttribute("ui.label", job.getName());
- }
- else if(label.equals(Label.ARRIVAL_TIME)){
+ } else if (label.equals(Label.ARRIVAL_TIME)) {
Node actNode = g.getNode(currIdentifier);
actNode.addAttribute("ui.label", Time.parseSecondsToTime(act.getArrTime()));
- }
- else if(label.equals(Label.DEPARTURE_TIME)){
+ } else if (label.equals(Label.DEPARTURE_TIME)) {
Node actNode = g.getNode(currIdentifier);
actNode.addAttribute("ui.label", Time.parseSecondsToTime(act.getEndTime()));
}
- g.addEdge(makeEdgeId(routeId,vehicle_edgeId), prevIdentifier, currIdentifier, true);
- if(act instanceof PickupActivity) g.getNode(currIdentifier).addAttribute("ui.class", "pickupInRoute");
- else if (act instanceof DeliveryActivity) g.getNode(currIdentifier).addAttribute("ui.class", "deliveryInRoute");
- prevIdentifier = currIdentifier;
- vehicle_edgeId++;
- sleep(renderDelay_in_ms);
- }
- if(route.getVehicle().isReturnToDepot()){
- String lastIdentifier = makeId(route.getVehicle().getId(),route.getVehicle().getEndLocation().getId());
- g.addEdge(makeEdgeId(routeId,vehicle_edgeId), prevIdentifier, lastIdentifier, true);
- }
- }
+ g.addEdge(makeEdgeId(routeId, vehicle_edgeId), prevIdentifier, currIdentifier, true);
+ if (act instanceof PickupActivity) g.getNode(currIdentifier).addAttribute("ui.class", "pickupInRoute");
+ else if (act instanceof DeliveryActivity)
+ g.getNode(currIdentifier).addAttribute("ui.class", "deliveryInRoute");
+ prevIdentifier = currIdentifier;
+ vehicle_edgeId++;
+ sleep(renderDelay_in_ms);
+ }
+ if (route.getVehicle().isReturnToDepot()) {
+ String lastIdentifier = makeId(route.getVehicle().getId(), route.getVehicle().getEndLocation().getId());
+ g.addEdge(makeEdgeId(routeId, vehicle_edgeId), prevIdentifier, lastIdentifier, true);
+ }
+ }
- private String makeEdgeId(int routeId, int vehicle_edgeId) {
- return Integer.valueOf(routeId).toString() + "." + Integer.valueOf(vehicle_edgeId).toString();
- }
+ private String makeEdgeId(int routeId, int vehicle_edgeId) {
+ return Integer.valueOf(routeId).toString() + "." + Integer.valueOf(vehicle_edgeId).toString();
+ }
- // public void saveAsPNG(String filename){
- //
- // }
+ // public void saveAsPNG(String filename){
+ //
+ // }
}
diff --git a/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/NoLocationFoundException.java b/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/NoLocationFoundException.java
index 77df2b6e..4c0a2ecc 100644
--- a/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/NoLocationFoundException.java
+++ b/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/NoLocationFoundException.java
@@ -1,28 +1,28 @@
/*******************************************************************************
* Copyright (c) 2014 Stefan Schroeder.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
+ * License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
+ *
+ * You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see .
- *
+ *
* Contributors:
* Stefan Schroeder - initial API and implementation
******************************************************************************/
package jsprit.analysis.toolbox;
-class NoLocationFoundException extends Exception{
+class NoLocationFoundException extends Exception {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
- /**
- *
- */
- private static final long serialVersionUID = 1L;
-
}
diff --git a/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/Plotter.java b/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/Plotter.java
index 383dc732..7b7c7b87 100644
--- a/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/Plotter.java
+++ b/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/Plotter.java
@@ -11,7 +11,7 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
- * You should have received a copy of the GNU Lesser General Public
+ * You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see .
******************************************************************************/
package jsprit.analysis.toolbox;
@@ -51,585 +51,576 @@ import java.util.*;
/**
* Visualizes problem and solution.
*
Note that every item to be rendered need to have coordinates.
- *
- * @author schroeder
*
+ * @author schroeder
*/
public class Plotter {
-
- private final static Color START_COLOR = Color.RED;
- private final static Color END_COLOR = Color.RED;
- private final static Color PICKUP_COLOR = Color.GREEN;
- private final static Color DELIVERY_COLOR = Color.BLUE;
- private final static Color SERVICE_COLOR = Color.BLUE;
-
- private final static Shape ELLIPSE = new Ellipse2D.Double(-3, -3, 6, 6);
-
- private static class MyActivityRenderer extends XYLineAndShapeRenderer {
- /**
- *
- */
- private static final long serialVersionUID = 1L;
-
- private XYSeriesCollection seriesCollection;
-
- private Map activities;
-
- private Set firstActivities;
-
- public MyActivityRenderer(XYSeriesCollection seriesCollection,Map activities,Set firstActivities) {
- super(false,true);
- this.seriesCollection = seriesCollection;
- this.activities = activities;
- this.firstActivities = firstActivities;
- super.setSeriesOutlinePaint(0, Color.DARK_GRAY);
- super.setUseOutlinePaint(true);
- }
+ private final static Color START_COLOR = Color.RED;
+ private final static Color END_COLOR = Color.RED;
+ private final static Color PICKUP_COLOR = Color.GREEN;
+ private final static Color DELIVERY_COLOR = Color.BLUE;
+ private final static Color SERVICE_COLOR = Color.BLUE;
- @Override
- public Shape getItemShape(int seriesIndex, int itemIndex) {
- XYDataItem dataItem = seriesCollection.getSeries(seriesIndex).getDataItem(itemIndex);
- if(firstActivities.contains(dataItem)){
- return ShapeUtilities.createUpTriangle(4.0f);
- }
- return ELLIPSE;
- }
-
- @Override
- public Paint getItemOutlinePaint(int seriesIndex, int itemIndex) {
- XYDataItem dataItem = seriesCollection.getSeries(seriesIndex).getDataItem(itemIndex);
- if(firstActivities.contains(dataItem)){
- return Color.BLACK;
- }
- return super.getItemOutlinePaint(seriesIndex, itemIndex);
- }
-
- @Override
- public Paint getItemPaint(int seriesIndex, int itemIndex) {
- XYDataItem dataItem = seriesCollection.getSeries(seriesIndex).getDataItem(itemIndex);
- Activity activity = activities.get(dataItem);
- if(activity.equals(Activity.PICKUP)) return PICKUP_COLOR;
- if(activity.equals(Activity.DELIVERY)) return DELIVERY_COLOR;
- if(activity.equals(Activity.SERVICE)) return SERVICE_COLOR;
- if(activity.equals(Activity.START)) return START_COLOR;
- if(activity.equals(Activity.END)) return END_COLOR;
- throw new IllegalStateException("activity at "+dataItem.toString()+" cannot be assigned to a color");
- }
-
- }
-
- private static class BoundingBox {
- double minX;
- double minY;
- double maxX;
- double maxY;
- public BoundingBox(double minX, double minY, double maxX, double maxY) {
- super();
- this.minX = minX;
- this.minY = minY;
- this.maxX = maxX;
- this.maxY = maxY;
- }
-
- }
-
- private enum Activity {
- START, END, PICKUP, DELIVERY, SERVICE
- }
-
-
- private static Logger log = LogManager.getLogger(Plotter.class);
-
- /**
- * Label to label ID (=jobId), SIZE (=jobSize=jobCapacityDimensions)
- * @author schroeder
- *
- */
- public static enum Label {
- ID, SIZE, @SuppressWarnings("UnusedDeclaration")NO_LABEL
- }
-
- private Label label = Label.SIZE;
-
- private VehicleRoutingProblem vrp;
-
- private boolean plotSolutionAsWell = false;
+ private final static Shape ELLIPSE = new Ellipse2D.Double(-3, -3, 6, 6);
- private boolean plotShipments = true;
+ private static class MyActivityRenderer extends XYLineAndShapeRenderer {
- private Collection routes;
-
- private BoundingBox boundingBox = null;
-
- private Map activitiesByDataItem = new HashMap();
-
- private Map labelsByDataItem = new HashMap();
-
- private XYSeries activities;
-
- private Set firstActivities = new HashSet();
-
- private boolean containsPickupAct = false;
-
- private boolean containsDeliveryAct = false;
-
- private boolean containsServiceAct = false;
-
- private double scalingFactor = 1.;
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
- private boolean invert = false;
-
- /**
- * Constructs Plotter with problem. Thus only the problem can be rendered.
- *
- * @param vrp the routing problem
- */
- public Plotter(VehicleRoutingProblem vrp) {
- super();
- this.vrp = vrp;
- }
+ private XYSeriesCollection seriesCollection;
- /**
- * Constructs Plotter with problem and solution to render them both.
- *
- * @param vrp the routing problem
- * @param solution the solution
- */
- public Plotter(VehicleRoutingProblem vrp, VehicleRoutingProblemSolution solution) {
- super();
- this.vrp = vrp;
- this.routes = solution.getRoutes();
- plotSolutionAsWell = true;
- }
+ private Map activities;
- /**
- * Constructs Plotter with problem and routes to render individual routes.
- *
- * @param vrp the routing problem
- * @param routes routes
- */
- public Plotter(VehicleRoutingProblem vrp, Collection routes) {
- super();
- this.vrp = vrp;
- this.routes = routes;
- plotSolutionAsWell = true;
- }
+ private Set firstActivities;
- @SuppressWarnings("UnusedDeclaration")
- public Plotter setScalingFactor(double scalingFactor){
- this.scalingFactor=scalingFactor;
- return this;
- }
-
- /**
- * Sets a label.
- * @param label of jobs
- * @return plotter
- */
- public Plotter setLabel(Label label){
- this.label = label;
- return this;
- }
+ public MyActivityRenderer(XYSeriesCollection seriesCollection, Map activities, Set firstActivities) {
+ super(false, true);
+ this.seriesCollection = seriesCollection;
+ this.activities = activities;
+ this.firstActivities = firstActivities;
+ super.setSeriesOutlinePaint(0, Color.DARK_GRAY);
+ super.setUseOutlinePaint(true);
+ }
- public Plotter invertCoordinates(boolean invert){
- this.invert = invert;
- return this;
- }
-
- /**
- * Sets a bounding box to zoom in to certain areas.
- *
- * @param minX lower left x
- * @param minY lower left y
- * @param maxX upper right x
- * @param maxY upper right y
- * @return
- */
- @SuppressWarnings("UnusedDeclaration")
- public Plotter setBoundingBox(double minX, double minY, double maxX, double maxY){
- boundingBox = new BoundingBox(minX,minY,maxX,maxY);
- return this;
- }
+ @Override
+ public Shape getItemShape(int seriesIndex, int itemIndex) {
+ XYDataItem dataItem = seriesCollection.getSeries(seriesIndex).getDataItem(itemIndex);
+ if (firstActivities.contains(dataItem)) {
+ return ShapeUtilities.createUpTriangle(4.0f);
+ }
+ return ELLIPSE;
+ }
- /**
- * Flag that indicates whether shipments should be rendered as well.
- *
- * @param plotShipments flag to plot shipment
- * @return the plotter
- */
- public Plotter plotShipments(boolean plotShipments) {
- this.plotShipments = plotShipments;
- return this;
- }
+ @Override
+ public Paint getItemOutlinePaint(int seriesIndex, int itemIndex) {
+ XYDataItem dataItem = seriesCollection.getSeries(seriesIndex).getDataItem(itemIndex);
+ if (firstActivities.contains(dataItem)) {
+ return Color.BLACK;
+ }
+ return super.getItemOutlinePaint(seriesIndex, itemIndex);
+ }
- /**
- * Plots problem and/or solution/routes.
- *
- * @param pngFileName - path and filename
- * @param plotTitle - title that appears on top of image
- */
- public void plot(String pngFileName, String plotTitle){
- String filename = pngFileName;
- if(!pngFileName.endsWith(".png")) filename += ".png";
- if(plotSolutionAsWell){
- plot(vrp, routes, filename, plotTitle);
- }
- else if(!(vrp.getInitialVehicleRoutes().isEmpty())){
- plot(vrp, vrp.getInitialVehicleRoutes(), filename, plotTitle);
- }
- else{
- plot(vrp, null, filename, plotTitle);
- }
- }
-
- private void plot(VehicleRoutingProblem vrp, final Collection routes, String pngFile, String title){
- log.info("plot to " + pngFile);
- XYSeriesCollection problem;
- XYSeriesCollection solution = null;
- final XYSeriesCollection shipments;
- try {
- retrieveActivities(vrp);
- problem = new XYSeriesCollection(activities);
- shipments = makeShipmentSeries(vrp.getJobs().values());
- if(routes!=null) solution = makeSolutionSeries(vrp, routes);
- } catch (NoLocationFoundException e) {
- log.warn("cannot plot vrp, since coord is missing");
- return;
- }
- final XYPlot plot = createPlot(problem, shipments, solution);
- JFreeChart chart = new JFreeChart(title, plot);
-
- LegendTitle legend = createLegend(routes, shipments, plot);
- chart.removeLegend();
- chart.addLegend(legend);
-
- save(chart,pngFile);
-
- }
+ @Override
+ public Paint getItemPaint(int seriesIndex, int itemIndex) {
+ XYDataItem dataItem = seriesCollection.getSeries(seriesIndex).getDataItem(itemIndex);
+ Activity activity = activities.get(dataItem);
+ if (activity.equals(Activity.PICKUP)) return PICKUP_COLOR;
+ if (activity.equals(Activity.DELIVERY)) return DELIVERY_COLOR;
+ if (activity.equals(Activity.SERVICE)) return SERVICE_COLOR;
+ if (activity.equals(Activity.START)) return START_COLOR;
+ if (activity.equals(Activity.END)) return END_COLOR;
+ throw new IllegalStateException("activity at " + dataItem.toString() + " cannot be assigned to a color");
+ }
- private LegendTitle createLegend(final Collection routes,final XYSeriesCollection shipments, final XYPlot plot) {
- LegendItemSource lis = new LegendItemSource() {
+ }
- @Override
- public LegendItemCollection getLegendItems() {
- LegendItemCollection lic = new LegendItemCollection();
- LegendItem vehLoc = new LegendItem("vehLoc", Color.RED);
- vehLoc.setShape(ELLIPSE);
- vehLoc.setShapeVisible(true);
- lic.add(vehLoc);
- if(containsServiceAct){
- LegendItem item = new LegendItem("service", Color.BLUE);
- item.setShape(ELLIPSE);
- item.setShapeVisible(true);
- lic.add(item);
- }
- if(containsPickupAct){
- LegendItem item = new LegendItem("pickup", Color.GREEN);
- item.setShape(ELLIPSE);
- item.setShapeVisible(true);
- lic.add(item);
- }
- if(containsDeliveryAct){
- LegendItem item = new LegendItem("delivery", Color.BLUE);
- item.setShape(ELLIPSE);
- item.setShapeVisible(true);
- lic.add(item);
- }
- if(routes!=null){
- LegendItem item = new LegendItem("firstActivity",Color.BLACK);
- Shape upTriangle = ShapeUtilities.createUpTriangle(3.0f);
- item.setShape(upTriangle);
- item.setOutlinePaint(Color.BLACK);
-
- item.setLine(upTriangle);
- item.setLinePaint(Color.BLACK);
- item.setShapeVisible(true);
-
- lic.add(item);
- }
- if(!shipments.getSeries().isEmpty()){
- lic.add(plot.getRenderer(1).getLegendItem(1, 0));
- }
- if(routes!=null){
- lic.addAll(plot.getRenderer(2).getLegendItems());
- }
- return lic;
- }
- };
-
- LegendTitle legend = new LegendTitle(lis);
- legend.setPosition(RectangleEdge.BOTTOM);
- return legend;
- }
+ private static class BoundingBox {
+ double minX;
+ double minY;
+ double maxX;
+ double maxY;
- private XYItemRenderer getShipmentRenderer(XYSeriesCollection shipments) {
- XYItemRenderer shipmentsRenderer = new XYLineAndShapeRenderer(true, false); // Shapes only
- for(int i=0;i routes) throws NoLocationFoundException{
- Locations locations = retrieveLocations(vrp);
- XYSeriesCollection coll = new XYSeriesCollection();
- int counter = 1;
- for(VehicleRoute route : routes){
- if(route.isEmpty()) continue;
- XYSeries series = new XYSeries(counter, false, true);
-
- Coordinate startCoord = getCoordinate(locations.getCoord(route.getStart().getLocation().getId()));
- series.add(startCoord.getX()*scalingFactor, startCoord.getY()*scalingFactor);
-
- for(TourActivity act : route.getTourActivities().getActivities()){
- Coordinate coord = getCoordinate(locations.getCoord(act.getLocation().getId()));
- series.add(coord.getX()*scalingFactor, coord.getY()*scalingFactor);
- }
-
- Coordinate endCoord = getCoordinate(locations.getCoord(route.getEnd().getLocation().getId()));
- series.add(endCoord.getX()*scalingFactor, endCoord.getY()*scalingFactor);
-
- coll.addSeries(series);
- counter++;
- }
- return coll;
- }
-
- private XYSeriesCollection makeShipmentSeries(Collection jobs) throws NoLocationFoundException{
- XYSeriesCollection coll = new XYSeriesCollection();
- if(!plotShipments) return coll;
- int sCounter = 1;
- String ship = "shipment";
- boolean first = true;
- for(Job job : jobs){
- if(!(job instanceof Shipment)){
- continue;
- }
- Shipment shipment = (Shipment)job;
- XYSeries shipmentSeries;
- if(first){
- first = false;
- shipmentSeries = new XYSeries(ship, false, true);
- }
- else{
- shipmentSeries = new XYSeries(sCounter, false, true);
- sCounter++;
- }
- Coordinate pickupCoordinate = getCoordinate(shipment.getPickupLocation().getCoordinate());
- Coordinate delCoordinate = getCoordinate(shipment.getDeliveryLocation().getCoordinate());
- shipmentSeries.add(pickupCoordinate.getX()*scalingFactor, pickupCoordinate.getY()*scalingFactor);
- shipmentSeries.add(delCoordinate.getX()*scalingFactor, delCoordinate.getY()*scalingFactor);
- coll.addSeries(shipmentSeries);
- }
- return coll;
- }
+ private boolean plotSolutionAsWell = false;
- private void addJob(XYSeries activities, Job job) {
- if(job instanceof Shipment){
- Shipment s = (Shipment)job;
- Coordinate pickupCoordinate = getCoordinate(s.getPickupLocation().getCoordinate());
- XYDataItem dataItem = new XYDataItem(pickupCoordinate.getX()*scalingFactor, pickupCoordinate.getY()*scalingFactor);
- activities.add(dataItem);
- addLabel(s, dataItem);
- markItem(dataItem,Activity.PICKUP);
- containsPickupAct = true;
+ private boolean plotShipments = true;
- Coordinate deliveryCoordinate = getCoordinate(s.getDeliveryLocation().getCoordinate());
- XYDataItem dataItem2 = new XYDataItem(deliveryCoordinate.getX()*scalingFactor, deliveryCoordinate.getY()*scalingFactor);
- activities.add(dataItem2);
- addLabel(s, dataItem2);
- markItem(dataItem2,Activity.DELIVERY);
- containsDeliveryAct = true;
- }
- else if(job instanceof Pickup){
- Pickup service = (Pickup)job;
- Coordinate coord = getCoordinate(service.getLocation().getCoordinate());
- XYDataItem dataItem = new XYDataItem(coord.getX()*scalingFactor, coord.getY()*scalingFactor);
- activities.add(dataItem);
- addLabel(service, dataItem);
- markItem(dataItem, Activity.PICKUP);
- containsPickupAct = true;
- }
- else if(job instanceof Delivery){
- Delivery service = (Delivery)job;
- Coordinate coord = getCoordinate(service.getLocation().getCoordinate());
- XYDataItem dataItem = new XYDataItem(coord.getX()*scalingFactor, coord.getY()*scalingFactor);
- activities.add(dataItem);
- addLabel(service, dataItem);
- markItem(dataItem, Activity.DELIVERY);
- containsDeliveryAct = true;
- }
- else if(job instanceof Service){
- Service service = (Service)job;
- Coordinate coord = getCoordinate(service.getLocation().getCoordinate());
- XYDataItem dataItem = new XYDataItem(coord.getX()*scalingFactor, coord.getY()*scalingFactor);
- activities.add(dataItem);
- addLabel(service, dataItem);
- markItem(dataItem, Activity.SERVICE);
- containsServiceAct = true;
- }
- else{
- throw new IllegalStateException("job instanceof " + job.getClass().toString() + ". this is not supported.");
- }
- }
+ private Collection routes;
- private void addLabel(Job job, XYDataItem dataItem) {
- if(this.label.equals(Label.SIZE)){
- labelsByDataItem.put(dataItem, getSizeString(job));
- }
- else if(this.label.equals(Label.ID)){
- labelsByDataItem.put(dataItem, String.valueOf(job.getId()));
- }
- }
-
- private String getSizeString(Job job) {
- StringBuilder builder = new StringBuilder();
- builder.append("(");
- boolean firstDim = true;
- for(int i=0;i activitiesByDataItem = new HashMap();
- private void retrieveActivities(VehicleRoutingProblem vrp) throws NoLocationFoundException{
- activities = new XYSeries("activities", false, true);
- for(Vehicle v : vrp.getVehicles()){
- Coordinate start_coordinate = getCoordinate(v.getStartLocation().getCoordinate());
- if(start_coordinate == null) throw new NoLocationFoundException();
- XYDataItem item = new XYDataItem(start_coordinate.getX()*scalingFactor, start_coordinate.getY()*scalingFactor);
- markItem(item,Activity.START);
- activities.add(item);
-
- if(!v.getStartLocation().getId().equals(v.getEndLocation().getId())){
- Coordinate end_coordinate = getCoordinate(v.getEndLocation().getCoordinate());
- if(end_coordinate == null) throw new NoLocationFoundException();
- XYDataItem end_item = new XYDataItem(end_coordinate.getX()*scalingFactor,end_coordinate.getY()*scalingFactor);
- markItem(end_item,Activity.END);
+ private Map labelsByDataItem = new HashMap();
+
+ private XYSeries activities;
+
+ private Set firstActivities = new HashSet();
+
+ private boolean containsPickupAct = false;
+
+ private boolean containsDeliveryAct = false;
+
+ private boolean containsServiceAct = false;
+
+ private double scalingFactor = 1.;
+
+ private boolean invert = false;
+
+ /**
+ * Constructs Plotter with problem. Thus only the problem can be rendered.
+ *
+ * @param vrp the routing problem
+ */
+ public Plotter(VehicleRoutingProblem vrp) {
+ super();
+ this.vrp = vrp;
+ }
+
+ /**
+ * Constructs Plotter with problem and solution to render them both.
+ *
+ * @param vrp the routing problem
+ * @param solution the solution
+ */
+ public Plotter(VehicleRoutingProblem vrp, VehicleRoutingProblemSolution solution) {
+ super();
+ this.vrp = vrp;
+ this.routes = solution.getRoutes();
+ plotSolutionAsWell = true;
+ }
+
+ /**
+ * Constructs Plotter with problem and routes to render individual routes.
+ *
+ * @param vrp the routing problem
+ * @param routes routes
+ */
+ public Plotter(VehicleRoutingProblem vrp, Collection routes) {
+ super();
+ this.vrp = vrp;
+ this.routes = routes;
+ plotSolutionAsWell = true;
+ }
+
+ @SuppressWarnings("UnusedDeclaration")
+ public Plotter setScalingFactor(double scalingFactor) {
+ this.scalingFactor = scalingFactor;
+ return this;
+ }
+
+ /**
+ * Sets a label.
+ *
+ * @param label of jobs
+ * @return plotter
+ */
+ public Plotter setLabel(Label label) {
+ this.label = label;
+ return this;
+ }
+
+ public Plotter invertCoordinates(boolean invert) {
+ this.invert = invert;
+ return this;
+ }
+
+ /**
+ * Sets a bounding box to zoom in to certain areas.
+ *
+ * @param minX lower left x
+ * @param minY lower left y
+ * @param maxX upper right x
+ * @param maxY upper right y
+ * @return
+ */
+ @SuppressWarnings("UnusedDeclaration")
+ public Plotter setBoundingBox(double minX, double minY, double maxX, double maxY) {
+ boundingBox = new BoundingBox(minX, minY, maxX, maxY);
+ return this;
+ }
+
+ /**
+ * Flag that indicates whether shipments should be rendered as well.
+ *
+ * @param plotShipments flag to plot shipment
+ * @return the plotter
+ */
+ public Plotter plotShipments(boolean plotShipments) {
+ this.plotShipments = plotShipments;
+ return this;
+ }
+
+ /**
+ * Plots problem and/or solution/routes.
+ *
+ * @param pngFileName - path and filename
+ * @param plotTitle - title that appears on top of image
+ */
+ public void plot(String pngFileName, String plotTitle) {
+ String filename = pngFileName;
+ if (!pngFileName.endsWith(".png")) filename += ".png";
+ if (plotSolutionAsWell) {
+ plot(vrp, routes, filename, plotTitle);
+ } else if (!(vrp.getInitialVehicleRoutes().isEmpty())) {
+ plot(vrp, vrp.getInitialVehicleRoutes(), filename, plotTitle);
+ } else {
+ plot(vrp, null, filename, plotTitle);
+ }
+ }
+
+ private void plot(VehicleRoutingProblem vrp, final Collection routes, String pngFile, String title) {
+ log.info("plot to {}", pngFile);
+ XYSeriesCollection problem;
+ XYSeriesCollection solution = null;
+ final XYSeriesCollection shipments;
+ try {
+ retrieveActivities(vrp);
+ problem = new XYSeriesCollection(activities);
+ shipments = makeShipmentSeries(vrp.getJobs().values());
+ if (routes != null) solution = makeSolutionSeries(vrp, routes);
+ } catch (NoLocationFoundException e) {
+ log.warn("cannot plot vrp, since coord is missing");
+ return;
+ }
+ final XYPlot plot = createPlot(problem, shipments, solution);
+ JFreeChart chart = new JFreeChart(title, plot);
+
+ LegendTitle legend = createLegend(routes, shipments, plot);
+ chart.removeLegend();
+ chart.addLegend(legend);
+
+ save(chart, pngFile);
+
+ }
+
+ private LegendTitle createLegend(final Collection routes, final XYSeriesCollection shipments, final XYPlot plot) {
+ LegendItemSource lis = new LegendItemSource() {
+
+ @Override
+ public LegendItemCollection getLegendItems() {
+ LegendItemCollection lic = new LegendItemCollection();
+ LegendItem vehLoc = new LegendItem("vehLoc", Color.RED);
+ vehLoc.setShape(ELLIPSE);
+ vehLoc.setShapeVisible(true);
+ lic.add(vehLoc);
+ if (containsServiceAct) {
+ LegendItem item = new LegendItem("service", Color.BLUE);
+ item.setShape(ELLIPSE);
+ item.setShapeVisible(true);
+ lic.add(item);
+ }
+ if (containsPickupAct) {
+ LegendItem item = new LegendItem("pickup", Color.GREEN);
+ item.setShape(ELLIPSE);
+ item.setShapeVisible(true);
+ lic.add(item);
+ }
+ if (containsDeliveryAct) {
+ LegendItem item = new LegendItem("delivery", Color.BLUE);
+ item.setShape(ELLIPSE);
+ item.setShapeVisible(true);
+ lic.add(item);
+ }
+ if (routes != null) {
+ LegendItem item = new LegendItem("firstActivity", Color.BLACK);
+ Shape upTriangle = ShapeUtilities.createUpTriangle(3.0f);
+ item.setShape(upTriangle);
+ item.setOutlinePaint(Color.BLACK);
+
+ item.setLine(upTriangle);
+ item.setLinePaint(Color.BLACK);
+ item.setShapeVisible(true);
+
+ lic.add(item);
+ }
+ if (!shipments.getSeries().isEmpty()) {
+ lic.add(plot.getRenderer(1).getLegendItem(1, 0));
+ }
+ if (routes != null) {
+ lic.addAll(plot.getRenderer(2).getLegendItems());
+ }
+ return lic;
+ }
+ };
+
+ LegendTitle legend = new LegendTitle(lis);
+ legend.setPosition(RectangleEdge.BOTTOM);
+ return legend;
+ }
+
+ private XYItemRenderer getShipmentRenderer(XYSeriesCollection shipments) {
+ XYItemRenderer shipmentsRenderer = new XYLineAndShapeRenderer(true, false); // Shapes only
+ for (int i = 0; i < shipments.getSeriesCount(); i++) {
+ shipmentsRenderer.setSeriesPaint(i, Color.DARK_GRAY);
+ shipmentsRenderer.setSeriesStroke(i, new BasicStroke(
+ 1.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND,
+ 1.f, new float[]{4.0f, 4.0f}, 0.0f
+ ));
+ }
+ return shipmentsRenderer;
+ }
+
+ private MyActivityRenderer getProblemRenderer(final XYSeriesCollection problem) {
+ MyActivityRenderer problemRenderer = new MyActivityRenderer(problem, activitiesByDataItem, firstActivities);
+ problemRenderer.setBaseItemLabelGenerator(new XYItemLabelGenerator() {
+
+ @Override
+ public String generateLabel(XYDataset arg0, int arg1, int arg2) {
+ XYDataItem item = problem.getSeries(arg1).getDataItem(arg2);
+ return labelsByDataItem.get(item);
+ }
+
+ });
+ problemRenderer.setBaseItemLabelsVisible(true);
+ problemRenderer.setBaseItemLabelPaint(Color.BLACK);
+
+ return problemRenderer;
+ }
+
+ private Range getRange(final XYSeriesCollection seriesCol) {
+ if (this.boundingBox == null) return seriesCol.getRangeBounds(false);
+ else return new Range(boundingBox.minY, boundingBox.maxY);
+ }
+
+ private Range getDomainRange(final XYSeriesCollection seriesCol) {
+ if (this.boundingBox == null) return seriesCol.getDomainBounds(true);
+ else return new Range(boundingBox.minX, boundingBox.maxX);
+ }
+
+ private XYPlot createPlot(final XYSeriesCollection problem, XYSeriesCollection shipments, XYSeriesCollection solution) {
+ XYPlot plot = new XYPlot();
+ plot.setBackgroundPaint(Color.LIGHT_GRAY);
+ plot.setRangeGridlinePaint(Color.LIGHT_GRAY);
+ plot.setDomainGridlinePaint(Color.LIGHT_GRAY);
+
+ XYLineAndShapeRenderer problemRenderer = getProblemRenderer(problem);
+ plot.setDataset(0, problem);
+ plot.setRenderer(0, problemRenderer);
+
+ XYItemRenderer shipmentsRenderer = getShipmentRenderer(shipments);
+ plot.setDataset(1, shipments);
+ plot.setRenderer(1, shipmentsRenderer);
+
+ if (solution != null) {
+ XYItemRenderer solutionRenderer = getRouteRenderer(solution);
+ plot.setDataset(2, solution);
+ plot.setRenderer(2, solutionRenderer);
+ }
+
+ NumberAxis xAxis = new NumberAxis();
+ NumberAxis yAxis = new NumberAxis();
+
+ if (boundingBox == null) {
+ xAxis.setRangeWithMargins(getDomainRange(problem));
+ yAxis.setRangeWithMargins(getRange(problem));
+ } else {
+ xAxis.setRangeWithMargins(new Range(boundingBox.minX, boundingBox.maxX));
+ yAxis.setRangeWithMargins(new Range(boundingBox.minY, boundingBox.maxY));
+ }
+
+ plot.setDomainAxis(xAxis);
+ plot.setRangeAxis(yAxis);
+
+ return plot;
+ }
+
+ private XYItemRenderer getRouteRenderer(XYSeriesCollection solutionColl) {
+ XYItemRenderer solutionRenderer = new XYLineAndShapeRenderer(true, false); // Lines only
+ for (int i = 0; i < solutionColl.getSeriesCount(); i++) {
+ XYSeries s = solutionColl.getSeries(i);
+ XYDataItem firstCustomer = s.getDataItem(1);
+ firstActivities.add(firstCustomer);
+ }
+ return solutionRenderer;
+ }
+
+ private void save(JFreeChart chart, String pngFile) {
+ try {
+ ChartUtilities.saveChartAsPNG(new File(pngFile), chart, 1000, 600);
+ } catch (IOException e) {
+ log.error("cannot plot");
+ log.error(e);
+ e.printStackTrace();
+ }
+ }
+
+ private XYSeriesCollection makeSolutionSeries(VehicleRoutingProblem vrp, Collection routes) throws NoLocationFoundException {
+ Locations locations = retrieveLocations(vrp);
+ XYSeriesCollection coll = new XYSeriesCollection();
+ int counter = 1;
+ for (VehicleRoute route : routes) {
+ if (route.isEmpty()) continue;
+ XYSeries series = new XYSeries(counter, false, true);
+
+ Coordinate startCoord = getCoordinate(locations.getCoord(route.getStart().getLocation().getId()));
+ series.add(startCoord.getX() * scalingFactor, startCoord.getY() * scalingFactor);
+
+ for (TourActivity act : route.getTourActivities().getActivities()) {
+ Coordinate coord = getCoordinate(locations.getCoord(act.getLocation().getId()));
+ series.add(coord.getX() * scalingFactor, coord.getY() * scalingFactor);
+ }
+
+ Coordinate endCoord = getCoordinate(locations.getCoord(route.getEnd().getLocation().getId()));
+ series.add(endCoord.getX() * scalingFactor, endCoord.getY() * scalingFactor);
+
+ coll.addSeries(series);
+ counter++;
+ }
+ return coll;
+ }
+
+ private XYSeriesCollection makeShipmentSeries(Collection jobs) throws NoLocationFoundException {
+ XYSeriesCollection coll = new XYSeriesCollection();
+ if (!plotShipments) return coll;
+ int sCounter = 1;
+ String ship = "shipment";
+ boolean first = true;
+ for (Job job : jobs) {
+ if (!(job instanceof Shipment)) {
+ continue;
+ }
+ Shipment shipment = (Shipment) job;
+ XYSeries shipmentSeries;
+ if (first) {
+ first = false;
+ shipmentSeries = new XYSeries(ship, false, true);
+ } else {
+ shipmentSeries = new XYSeries(sCounter, false, true);
+ sCounter++;
+ }
+ Coordinate pickupCoordinate = getCoordinate(shipment.getPickupLocation().getCoordinate());
+ Coordinate delCoordinate = getCoordinate(shipment.getDeliveryLocation().getCoordinate());
+ shipmentSeries.add(pickupCoordinate.getX() * scalingFactor, pickupCoordinate.getY() * scalingFactor);
+ shipmentSeries.add(delCoordinate.getX() * scalingFactor, delCoordinate.getY() * scalingFactor);
+ coll.addSeries(shipmentSeries);
+ }
+ return coll;
+ }
+
+ private void addJob(XYSeries activities, Job job) {
+ if (job instanceof Shipment) {
+ Shipment s = (Shipment) job;
+ Coordinate pickupCoordinate = getCoordinate(s.getPickupLocation().getCoordinate());
+ XYDataItem dataItem = new XYDataItem(pickupCoordinate.getX() * scalingFactor, pickupCoordinate.getY() * scalingFactor);
+ activities.add(dataItem);
+ addLabel(s, dataItem);
+ markItem(dataItem, Activity.PICKUP);
+ containsPickupAct = true;
+
+ Coordinate deliveryCoordinate = getCoordinate(s.getDeliveryLocation().getCoordinate());
+ XYDataItem dataItem2 = new XYDataItem(deliveryCoordinate.getX() * scalingFactor, deliveryCoordinate.getY() * scalingFactor);
+ activities.add(dataItem2);
+ addLabel(s, dataItem2);
+ markItem(dataItem2, Activity.DELIVERY);
+ containsDeliveryAct = true;
+ } else if (job instanceof Pickup) {
+ Pickup service = (Pickup) job;
+ Coordinate coord = getCoordinate(service.getLocation().getCoordinate());
+ XYDataItem dataItem = new XYDataItem(coord.getX() * scalingFactor, coord.getY() * scalingFactor);
+ activities.add(dataItem);
+ addLabel(service, dataItem);
+ markItem(dataItem, Activity.PICKUP);
+ containsPickupAct = true;
+ } else if (job instanceof Delivery) {
+ Delivery service = (Delivery) job;
+ Coordinate coord = getCoordinate(service.getLocation().getCoordinate());
+ XYDataItem dataItem = new XYDataItem(coord.getX() * scalingFactor, coord.getY() * scalingFactor);
+ activities.add(dataItem);
+ addLabel(service, dataItem);
+ markItem(dataItem, Activity.DELIVERY);
+ containsDeliveryAct = true;
+ } else if (job instanceof Service) {
+ Service service = (Service) job;
+ Coordinate coord = getCoordinate(service.getLocation().getCoordinate());
+ XYDataItem dataItem = new XYDataItem(coord.getX() * scalingFactor, coord.getY() * scalingFactor);
+ activities.add(dataItem);
+ addLabel(service, dataItem);
+ markItem(dataItem, Activity.SERVICE);
+ containsServiceAct = true;
+ } else {
+ throw new IllegalStateException("job instanceof " + job.getClass().toString() + ". this is not supported.");
+ }
+ }
+
+ private void addLabel(Job job, XYDataItem dataItem) {
+ if (this.label.equals(Label.SIZE)) {
+ labelsByDataItem.put(dataItem, getSizeString(job));
+ } else if (this.label.equals(Label.ID)) {
+ labelsByDataItem.put(dataItem, String.valueOf(job.getId()));
+ }
+ }
+
+ private String getSizeString(Job job) {
+ StringBuilder builder = new StringBuilder();
+ builder.append("(");
+ boolean firstDim = true;
+ for (int i = 0; i < job.getSize().getNuOfDimensions(); i++) {
+ if (firstDim) {
+ builder.append(String.valueOf(job.getSize().get(i)));
+ firstDim = false;
+ } else {
+ builder.append(",");
+ builder.append(String.valueOf(job.getSize().get(i)));
+ }
+ }
+ builder.append(")");
+ return builder.toString();
+ }
+
+ private Coordinate getCoordinate(Coordinate coordinate) {
+ if (invert) {
+ return Coordinate.newInstance(coordinate.getY(), coordinate.getX());
+ }
+ return coordinate;
+ }
+
+ private void retrieveActivities(VehicleRoutingProblem vrp) throws NoLocationFoundException {
+ activities = new XYSeries("activities", false, true);
+ for (Vehicle v : vrp.getVehicles()) {
+ Coordinate start_coordinate = getCoordinate(v.getStartLocation().getCoordinate());
+ if (start_coordinate == null) throw new NoLocationFoundException();
+ XYDataItem item = new XYDataItem(start_coordinate.getX() * scalingFactor, start_coordinate.getY() * scalingFactor);
+ markItem(item, Activity.START);
+ activities.add(item);
+
+ if (!v.getStartLocation().getId().equals(v.getEndLocation().getId())) {
+ Coordinate end_coordinate = getCoordinate(v.getEndLocation().getCoordinate());
+ if (end_coordinate == null) throw new NoLocationFoundException();
+ XYDataItem end_item = new XYDataItem(end_coordinate.getX() * scalingFactor, end_coordinate.getY() * scalingFactor);
+ markItem(end_item, Activity.END);
activities.add(end_item);
- }
- }
- for(Job job : vrp.getJobs().values()){
- addJob(activities, job);
- }
- for(VehicleRoute r : vrp.getInitialVehicleRoutes()){
- for(Job job : r.getTourActivities().getJobs()){
- addJob(activities, job);
- }
- }
- }
-
- private void markItem(XYDataItem item, Activity activity) {
- activitiesByDataItem.put(item,activity);
- }
+ }
+ }
+ for (Job job : vrp.getJobs().values()) {
+ addJob(activities, job);
+ }
+ for (VehicleRoute r : vrp.getInitialVehicleRoutes()) {
+ for (Job job : r.getTourActivities().getJobs()) {
+ addJob(activities, job);
+ }
+ }
+ }
- private Locations retrieveLocations(VehicleRoutingProblem vrp) throws NoLocationFoundException {
- return vrp.getLocations();
- }
+ private void markItem(XYDataItem item, Activity activity) {
+ activitiesByDataItem.put(item, activity);
+ }
+
+ private Locations retrieveLocations(VehicleRoutingProblem vrp) throws NoLocationFoundException {
+ return vrp.getLocations();
+ }
}
diff --git a/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/StopWatch.java b/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/StopWatch.java
index 2ccac67d..b7f61ff7 100644
--- a/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/StopWatch.java
+++ b/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/StopWatch.java
@@ -1,17 +1,17 @@
/*******************************************************************************
* Copyright (C) 2013 Stefan Schroeder
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
+ * License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
+ *
+ * You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see .
******************************************************************************/
package jsprit.analysis.toolbox;
@@ -27,51 +27,51 @@ import org.apache.logging.log4j.Logger;
import java.util.Collection;
-public class StopWatch implements AlgorithmStartsListener, AlgorithmEndsListener{
-
- private static Logger log = LogManager.getLogger(StopWatch.class);
-
- private double ran;
-
- private double startTime;
-
-
- @Override
- public void informAlgorithmStarts(VehicleRoutingProblem problem, VehicleRoutingAlgorithm algorithm, Collection solutions) {
- reset();
- start();
- }
-
- public double getCompTimeInSeconds(){
- return (ran)/1000.0;
- }
+public class StopWatch implements AlgorithmStartsListener, AlgorithmEndsListener {
- @Override
- public void informAlgorithmEnds(VehicleRoutingProblem problem, Collection solutions) {
- stop();
- log.info("computation time [in sec]: " + getCompTimeInSeconds());
- }
-
- public void stop(){
- ran += System.currentTimeMillis() - startTime;
- }
-
- public void start(){
- startTime = System.currentTimeMillis();
- }
-
- public void reset(){
- startTime = 0;
- ran = 0;
- }
-
- @Override
- public String toString() {
- return "stopWatch: " + getCompTimeInSeconds() + " sec";
- }
+ private static Logger log = LogManager.getLogger(StopWatch.class);
+
+ private double ran;
+
+ private double startTime;
+
+
+ @Override
+ public void informAlgorithmStarts(VehicleRoutingProblem problem, VehicleRoutingAlgorithm algorithm, Collection solutions) {
+ reset();
+ start();
+ }
+
+ public double getCompTimeInSeconds() {
+ return (ran) / 1000.0;
+ }
+
+ @Override
+ public void informAlgorithmEnds(VehicleRoutingProblem problem, Collection solutions) {
+ stop();
+ log.info("computation time [in sec]: {}", getCompTimeInSeconds());
+ }
+
+ public void stop() {
+ ran += System.currentTimeMillis() - startTime;
+ }
+
+ public void start() {
+ startTime = System.currentTimeMillis();
+ }
+
+ public void reset() {
+ startTime = 0;
+ ran = 0;
+ }
+
+ @Override
+ public String toString() {
+ return "stopWatch: " + getCompTimeInSeconds() + " sec";
+ }
+
+ public double getCurrTimeInSeconds() {
+ return (System.currentTimeMillis() - startTime) / 1000.0;
+ }
- public double getCurrTimeInSeconds() {
- return (System.currentTimeMillis()-startTime)/1000.0;
- }
-
}
diff --git a/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/XYLineChartBuilder.java b/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/XYLineChartBuilder.java
index b1a5145d..923ac4ff 100644
--- a/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/XYLineChartBuilder.java
+++ b/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/XYLineChartBuilder.java
@@ -1,18 +1,18 @@
/*******************************************************************************
* Copyright (c) 2014 Stefan Schroeder.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
+ * License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
+ *
+ * You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see .
- *
+ *
* Contributors:
* Stefan Schroeder - initial API and implementation
******************************************************************************/
@@ -32,82 +32,80 @@ import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
/**
- *
* @author schroeder
- *
*/
public class XYLineChartBuilder {
-
- /**
- * Helper that just saves the chart as specified png-file. The width of the image is 1000 and height 600.
- *
- * @param chart
- * @param pngFilename
- */
- public static void saveChartAsPNG(JFreeChart chart, String pngFilename){
- try {
- ChartUtilities.saveChartAsPNG(new File(pngFilename), chart, 1000, 600);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- /**
- * Returns a new instance of the builder.
- *
- * @param chartTitle appears on top of the XYLineChart
- * @param xDomainName appears below the xAxis
- * @param yDomainName appears beside the yAxis
- *
- * @return the builder
- */
- public static XYLineChartBuilder newInstance(String chartTitle, String xDomainName, String yDomainName){
- return new XYLineChartBuilder(chartTitle, xDomainName, yDomainName);
- }
-
- private ConcurrentHashMap seriesMap = new ConcurrentHashMap();
-
- private final String xDomain;
-
- private final String yDomain;
-
- private final String chartName;
-
- private XYLineChartBuilder(String chartName, String xDomainName, String yDomainName) {
- this.xDomain=xDomainName;
- this.yDomain=yDomainName;
- this.chartName=chartName;
- }
-
- /**
- * Adds data to the according series (i.e. XYLine).
- *
- * @param seriesName
- * @param xVal
- * @param yVal
- */
- public void addData(String seriesName, double xVal, double yVal){
- if(!seriesMap.containsKey(seriesName)){
- seriesMap.put(seriesName, new XYSeries(seriesName,true,true));
- }
- seriesMap.get(seriesName).add(xVal, yVal);
- }
-
- /**
- * Builds and returns JFreeChart.
- * @return
- */
- public JFreeChart build(){
- XYSeriesCollection collection = new XYSeriesCollection();
- for(XYSeries s : seriesMap.values()){
- collection.addSeries(s);
- }
- JFreeChart chart = ChartFactory.createXYLineChart(chartName, xDomain, yDomain, collection, PlotOrientation.VERTICAL, true, true, false);
- XYPlot plot = chart.getXYPlot();
- plot.setBackgroundPaint(Color.WHITE);
- plot.setDomainGridlinePaint(Color.LIGHT_GRAY);
- plot.setRangeGridlinePaint(Color.LIGHT_GRAY);
- return chart;
- }
+
+ /**
+ * Helper that just saves the chart as specified png-file. The width of the image is 1000 and height 600.
+ *
+ * @param chart
+ * @param pngFilename
+ */
+ public static void saveChartAsPNG(JFreeChart chart, String pngFilename) {
+ try {
+ ChartUtilities.saveChartAsPNG(new File(pngFilename), chart, 1000, 600);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Returns a new instance of the builder.
+ *
+ * @param chartTitle appears on top of the XYLineChart
+ * @param xDomainName appears below the xAxis
+ * @param yDomainName appears beside the yAxis
+ * @return the builder
+ */
+ public static XYLineChartBuilder newInstance(String chartTitle, String xDomainName, String yDomainName) {
+ return new XYLineChartBuilder(chartTitle, xDomainName, yDomainName);
+ }
+
+ private ConcurrentHashMap seriesMap = new ConcurrentHashMap();
+
+ private final String xDomain;
+
+ private final String yDomain;
+
+ private final String chartName;
+
+ private XYLineChartBuilder(String chartName, String xDomainName, String yDomainName) {
+ this.xDomain = xDomainName;
+ this.yDomain = yDomainName;
+ this.chartName = chartName;
+ }
+
+ /**
+ * Adds data to the according series (i.e. XYLine).
+ *
+ * @param seriesName
+ * @param xVal
+ * @param yVal
+ */
+ public void addData(String seriesName, double xVal, double yVal) {
+ if (!seriesMap.containsKey(seriesName)) {
+ seriesMap.put(seriesName, new XYSeries(seriesName, true, true));
+ }
+ seriesMap.get(seriesName).add(xVal, yVal);
+ }
+
+ /**
+ * Builds and returns JFreeChart.
+ *
+ * @return
+ */
+ public JFreeChart build() {
+ XYSeriesCollection collection = new XYSeriesCollection();
+ for (XYSeries s : seriesMap.values()) {
+ collection.addSeries(s);
+ }
+ JFreeChart chart = ChartFactory.createXYLineChart(chartName, xDomain, yDomain, collection, PlotOrientation.VERTICAL, true, true, false);
+ XYPlot plot = chart.getXYPlot();
+ plot.setBackgroundPaint(Color.WHITE);
+ plot.setDomainGridlinePaint(Color.LIGHT_GRAY);
+ plot.setRangeGridlinePaint(Color.LIGHT_GRAY);
+ return chart;
+ }
}
diff --git a/jsprit-analysis/src/main/java/jsprit/analysis/util/BenchmarkWriter.java b/jsprit-analysis/src/main/java/jsprit/analysis/util/BenchmarkWriter.java
index a4b2be2b..7529fc79 100644
--- a/jsprit-analysis/src/main/java/jsprit/analysis/util/BenchmarkWriter.java
+++ b/jsprit-analysis/src/main/java/jsprit/analysis/util/BenchmarkWriter.java
@@ -1,25 +1,25 @@
/*******************************************************************************
* Copyright (C) 2013 Stefan Schroeder
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
+ * License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
+ *
+ * You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see .
******************************************************************************/
package jsprit.analysis.util;
-import java.util.Collection;
-
import jsprit.core.util.BenchmarkResult;
+import java.util.Collection;
+
public interface BenchmarkWriter {
- public void write(Collection results);
+ public void write(Collection results);
}
diff --git a/jsprit-analysis/src/main/java/jsprit/analysis/util/HtmlBenchmarkTableWriter.java b/jsprit-analysis/src/main/java/jsprit/analysis/util/HtmlBenchmarkTableWriter.java
index 5cc3d8b3..c4159dcd 100644
--- a/jsprit-analysis/src/main/java/jsprit/analysis/util/HtmlBenchmarkTableWriter.java
+++ b/jsprit-analysis/src/main/java/jsprit/analysis/util/HtmlBenchmarkTableWriter.java
@@ -1,259 +1,256 @@
/*******************************************************************************
* Copyright (C) 2013 Stefan Schroeder
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
+ * License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
+ *
+ * You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see .
******************************************************************************/
package jsprit.analysis.util;
+import jsprit.core.util.BenchmarkResult;
+
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Collection;
-import jsprit.core.util.BenchmarkResult;
+public class HtmlBenchmarkTableWriter implements BenchmarkWriter {
-public class HtmlBenchmarkTableWriter implements BenchmarkWriter{
+ private String filename;
- private String filename;
-
- public HtmlBenchmarkTableWriter(String filename) {
- this.filename = filename;
- }
+ public HtmlBenchmarkTableWriter(String filename) {
+ this.filename = filename;
+ }
- @Override
- public void write(Collection results) {
-
- try {
- BufferedWriter writer = new BufferedWriter(new FileWriter(new File(filename)));
- writer.write(openTable() + newline());
- //table head
- writer.write(openRow() + newline());
- writer.write(head("inst") + newline());
- writer.write(head("runs") + newline());
- writer.write(head("Ø time [sec]") + newline());
- writer.write(head("results",4));
- writer.write(head("vehicles",4));
- writer.write(head("res*") + newline());
- writer.write(head("veh*") + newline());
- writer.write(closeRow() + newline());
-
- writer.write(openRow() + newline());
- writer.write(head("") + newline());
- writer.write(head("") + newline());
- writer.write(head("") + newline());
- writer.write(head("best") + newline());
- writer.write(head("avg") + newline());
- writer.write(head("worst") + newline());
- writer.write(head("stdev") + newline());
- writer.write(head("best") + newline());
- writer.write(head("avg") + newline());
- writer.write(head("worst") + newline());
- writer.write(head("stdev") + newline());
- writer.write(head("") + newline());
- writer.write(head("") + newline());
- writer.write(closeRow() + newline());
-
- //data
- double sum_avg_time = 0.0;
- double sum_best_result = 0.0;
- double sum_avg_result = 0.0;
- double sum_worst_result = 0.0;
- double sum_dev_result = 0.0;
-
- double sum_best_veh = 0.0;
- double sum_avg_veh = 0.0;
- double sum_worst_veh = 0.0;
- double sum_dev_veh = 0.0;
-
- Integer runs = null;
- Double sum_res_star=null;
- Double sum_veh_star=null;
-
- for(BenchmarkResult result : results){
- if(runs==null) runs=result.runs;
- writer.write(openRow() + newline());
- writer.write(date(result.instance.name) + newline());
- writer.write(date(Integer.valueOf(result.runs).toString()) + newline());
-
- Double avg_time = round(result.getTimesStats().getMean(),2);
- writer.write(date(Double.valueOf(avg_time).toString()) + newline());
- //bestRes
- Double best_result = round(result.getResultStats().getMin(),2);
- writer.write(date(Double.valueOf(best_result).toString()) + newline());
- //avgRes
- Double avg_result = round(result.getResultStats().getMean(),2);
- writer.write(date(Double.valueOf(avg_result).toString()) + newline());
- //worstRes
- Double worst_result = round(result.getResultStats().getMax(),2);
- writer.write(date(Double.valueOf(worst_result).toString()) + newline());
- //stdevRes
- Double std_result = round(result.getResultStats().getStandardDeviation(),2);
- writer.write(date(Double.valueOf(std_result).toString()) + newline());
- //bestVeh
- Double best_vehicle = round(result.getVehicleStats().getMin(),2);
- writer.write(date(Double.valueOf(best_vehicle).toString()) + newline());
- //avgVeh
- Double avg_vehicle = round(result.getVehicleStats().getMean(),2);
- writer.write(date(Double.valueOf(avg_vehicle).toString()) + newline());
- //worstVeh
- Double worst_vehicle = round(result.getVehicleStats().getMax(),2);
- writer.write(date(Double.valueOf(worst_vehicle).toString()) + newline());
- //stdevVeh
- Double std_vehicle = round(result.getVehicleStats().getStandardDeviation(),2);
- writer.write(date(Double.valueOf(std_vehicle).toString()) + newline());
- //bestKnownRes
- writer.write(date("" + result.instance.bestKnownResult + newline()));
- //bestKnownVeh
- writer.write(date("" + result.instance.bestKnownVehicles + newline()));
- writer.write(closeRow() + newline());
-
- sum_avg_time+=avg_time;
- sum_best_result+=best_result;
- sum_avg_result+=avg_result;
- sum_worst_result+=worst_result;
- sum_dev_result+=std_result;
-
- sum_best_veh+=best_vehicle;
- sum_avg_veh+=avg_vehicle;
- sum_worst_veh+=worst_vehicle;
- sum_dev_veh+=std_vehicle;
-
- if(result.instance.bestKnownResult != null){
- if(sum_res_star==null) sum_res_star=result.instance.bestKnownResult;
- else sum_res_star+=result.instance.bestKnownResult;
- }
- if(result.instance.bestKnownVehicles != null){
- if(sum_veh_star==null) sum_veh_star=result.instance.bestKnownVehicles;
- else sum_veh_star+=result.instance.bestKnownVehicles;
- }
-
- }
- writer.write(openRow() + newline());
- writer.write(date("Ø") + newline());
- writer.write(date(""+runs) + newline());
-
- Double average_time = round(sum_avg_time/(double)results.size(),2);
- writer.write(date(Double.valueOf(average_time).toString()) + newline());
- //bestRes
- writer.write(date(Double.valueOf(round(sum_best_result/(double)results.size(),2)).toString()) + newline());
- //avgRes
- Double average_result = round(sum_avg_result/(double)results.size(),2);
- writer.write(date(Double.valueOf(average_result).toString()) + newline());
- //worstRes
- writer.write(date(Double.valueOf(round(sum_worst_result/(double)results.size(),2)).toString()) + newline());
- //stdevRes
- writer.write(date(Double.valueOf(round(sum_dev_result/(double)results.size(),2)).toString()) + newline());
- //bestVeh
- writer.write(date(Double.valueOf(round(sum_best_veh/(double)results.size(),2)).toString()) + newline());
- //avgVeh
- Double average_vehicles = round(sum_avg_veh/(double)results.size(),2);
- writer.write(date(Double.valueOf(average_vehicles).toString()) + newline());
- //worstVeh
- writer.write(date(Double.valueOf(round(sum_worst_veh/(double)results.size(),2)).toString()) + newline());
- //stdevVeh
- writer.write(date(Double.valueOf(round(sum_dev_veh/(double)results.size(),2)).toString()) + newline());
- //bestKnownRes
- Double delta_res = null;
- if(sum_res_star != null){
- writer.write(date(Double.valueOf(round(sum_res_star.doubleValue()/(double)results.size(),2)).toString()) + newline());
- delta_res = (sum_avg_result/sum_res_star - 1)*100;
- }
- else writer.write(date("null") + newline());
- //bestKnownVeh
- Double delta_veh = null;
- if(sum_veh_star != null){
- writer.write(date(Double.valueOf(round(sum_veh_star.doubleValue()/(double)results.size(),2)).toString()) + newline());
- delta_veh = (sum_avg_veh - sum_veh_star)/(double)results.size();
- }
- else writer.write(date("null") + newline());
- writer.write(closeRow() + newline());
-
- writer.write(closeTable() + newline());
-
- writer.write("avg. percentage deviation to best-known result: " + round(delta_res,2) + newline() + newline());
- writer.write("avg. absolute deviation to best-known vehicles: " + round(delta_veh,2) + newline());
-
- writer.write(openTable() + newline());
- writer.write(openRow() + newline());
- writer.write(date("") + newline());
- writer.write(date("") + newline());
- writer.write(date("") + newline());
- writer.write(date("") + newline());
- writer.write(date(Double.valueOf(average_time).toString(),"align=\"right\"") + newline());
- writer.write(date(Double.valueOf(average_result).toString(),"align=\"right\"") + newline());
- writer.write(date(Double.valueOf(average_vehicles).toString(),"align=\"right\"") + newline());
- if(delta_res != null){
- writer.write(date(Double.valueOf(round(delta_res,2)).toString(),"align=\"right\"") + newline());
- }else writer.write(date("n.a.") + newline());
- if(delta_veh != null){
- writer.write(date(Double.valueOf(round(delta_veh,2)).toString(),"align=\"right\"") + newline());
- }else writer.write(date("n.a.") + newline());
- writer.write(closeRow() + newline());
- writer.write(closeTable() + newline());
-
-
- writer.close();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
-
- }
-
- private String head(String string, int i) {
- return "| "+string+" | ";
- }
+ @Override
+ public void write(Collection results) {
- private Double round(Double value, int i) {
- if(value==null) return null;
- long roundedVal = Math.round(value*Math.pow(10, i));
- return (double)roundedVal/(double)(Math.pow(10, i));
- }
+ try {
+ BufferedWriter writer = new BufferedWriter(new FileWriter(new File(filename)));
+ writer.write(openTable() + newline());
+ //table head
+ writer.write(openRow() + newline());
+ writer.write(head("inst") + newline());
+ writer.write(head("runs") + newline());
+ writer.write(head("Ø time [sec]") + newline());
+ writer.write(head("results", 4));
+ writer.write(head("vehicles", 4));
+ writer.write(head("res*") + newline());
+ writer.write(head("veh*") + newline());
+ writer.write(closeRow() + newline());
- private String head(String head) {
- return ""+head+" | ";
- }
+ writer.write(openRow() + newline());
+ writer.write(head("") + newline());
+ writer.write(head("") + newline());
+ writer.write(head("") + newline());
+ writer.write(head("best") + newline());
+ writer.write(head("avg") + newline());
+ writer.write(head("worst") + newline());
+ writer.write(head("stdev") + newline());
+ writer.write(head("best") + newline());
+ writer.write(head("avg") + newline());
+ writer.write(head("worst") + newline());
+ writer.write(head("stdev") + newline());
+ writer.write(head("") + newline());
+ writer.write(head("") + newline());
+ writer.write(closeRow() + newline());
- private String closeTable() {
- return "";
- }
+ //data
+ double sum_avg_time = 0.0;
+ double sum_best_result = 0.0;
+ double sum_avg_result = 0.0;
+ double sum_worst_result = 0.0;
+ double sum_dev_result = 0.0;
- private String openTable() {
- return "";
- }
+ double sum_best_veh = 0.0;
+ double sum_avg_veh = 0.0;
+ double sum_worst_veh = 0.0;
+ double sum_dev_veh = 0.0;
- private String closeRow() {
- return "";
- }
+ Integer runs = null;
+ Double sum_res_star = null;
+ Double sum_veh_star = null;
- private String date(String date) {
- return "| "+date+" | ";
- }
-
- private String date(String date, String metaData) {
- return ""+date+" | ";
- }
+ for (BenchmarkResult result : results) {
+ if (runs == null) runs = result.runs;
+ writer.write(openRow() + newline());
+ writer.write(date(result.instance.name) + newline());
+ writer.write(date(Integer.valueOf(result.runs).toString()) + newline());
- private String newline() {
- return "\n";
- }
+ Double avg_time = round(result.getTimesStats().getMean(), 2);
+ writer.write(date(Double.valueOf(avg_time).toString()) + newline());
+ //bestRes
+ Double best_result = round(result.getResultStats().getMin(), 2);
+ writer.write(date(Double.valueOf(best_result).toString()) + newline());
+ //avgRes
+ Double avg_result = round(result.getResultStats().getMean(), 2);
+ writer.write(date(Double.valueOf(avg_result).toString()) + newline());
+ //worstRes
+ Double worst_result = round(result.getResultStats().getMax(), 2);
+ writer.write(date(Double.valueOf(worst_result).toString()) + newline());
+ //stdevRes
+ Double std_result = round(result.getResultStats().getStandardDeviation(), 2);
+ writer.write(date(Double.valueOf(std_result).toString()) + newline());
+ //bestVeh
+ Double best_vehicle = round(result.getVehicleStats().getMin(), 2);
+ writer.write(date(Double.valueOf(best_vehicle).toString()) + newline());
+ //avgVeh
+ Double avg_vehicle = round(result.getVehicleStats().getMean(), 2);
+ writer.write(date(Double.valueOf(avg_vehicle).toString()) + newline());
+ //worstVeh
+ Double worst_vehicle = round(result.getVehicleStats().getMax(), 2);
+ writer.write(date(Double.valueOf(worst_vehicle).toString()) + newline());
+ //stdevVeh
+ Double std_vehicle = round(result.getVehicleStats().getStandardDeviation(), 2);
+ writer.write(date(Double.valueOf(std_vehicle).toString()) + newline());
+ //bestKnownRes
+ writer.write(date("" + result.instance.bestKnownResult + newline()));
+ //bestKnownVeh
+ writer.write(date("" + result.instance.bestKnownVehicles + newline()));
+ writer.write(closeRow() + newline());
- private String openRow() {
- return "";
- }
+ sum_avg_time += avg_time;
+ sum_best_result += best_result;
+ sum_avg_result += avg_result;
+ sum_worst_result += worst_result;
+ sum_dev_result += std_result;
+
+ sum_best_veh += best_vehicle;
+ sum_avg_veh += avg_vehicle;
+ sum_worst_veh += worst_vehicle;
+ sum_dev_veh += std_vehicle;
+
+ if (result.instance.bestKnownResult != null) {
+ if (sum_res_star == null) sum_res_star = result.instance.bestKnownResult;
+ else sum_res_star += result.instance.bestKnownResult;
+ }
+ if (result.instance.bestKnownVehicles != null) {
+ if (sum_veh_star == null) sum_veh_star = result.instance.bestKnownVehicles;
+ else sum_veh_star += result.instance.bestKnownVehicles;
+ }
+
+ }
+ writer.write(openRow() + newline());
+ writer.write(date("Ø") + newline());
+ writer.write(date("" + runs) + newline());
+
+ Double average_time = round(sum_avg_time / (double) results.size(), 2);
+ writer.write(date(Double.valueOf(average_time).toString()) + newline());
+ //bestRes
+ writer.write(date(Double.valueOf(round(sum_best_result / (double) results.size(), 2)).toString()) + newline());
+ //avgRes
+ Double average_result = round(sum_avg_result / (double) results.size(), 2);
+ writer.write(date(Double.valueOf(average_result).toString()) + newline());
+ //worstRes
+ writer.write(date(Double.valueOf(round(sum_worst_result / (double) results.size(), 2)).toString()) + newline());
+ //stdevRes
+ writer.write(date(Double.valueOf(round(sum_dev_result / (double) results.size(), 2)).toString()) + newline());
+ //bestVeh
+ writer.write(date(Double.valueOf(round(sum_best_veh / (double) results.size(), 2)).toString()) + newline());
+ //avgVeh
+ Double average_vehicles = round(sum_avg_veh / (double) results.size(), 2);
+ writer.write(date(Double.valueOf(average_vehicles).toString()) + newline());
+ //worstVeh
+ writer.write(date(Double.valueOf(round(sum_worst_veh / (double) results.size(), 2)).toString()) + newline());
+ //stdevVeh
+ writer.write(date(Double.valueOf(round(sum_dev_veh / (double) results.size(), 2)).toString()) + newline());
+ //bestKnownRes
+ Double delta_res = null;
+ if (sum_res_star != null) {
+ writer.write(date(Double.valueOf(round(sum_res_star.doubleValue() / (double) results.size(), 2)).toString()) + newline());
+ delta_res = (sum_avg_result / sum_res_star - 1) * 100;
+ } else writer.write(date("null") + newline());
+ //bestKnownVeh
+ Double delta_veh = null;
+ if (sum_veh_star != null) {
+ writer.write(date(Double.valueOf(round(sum_veh_star.doubleValue() / (double) results.size(), 2)).toString()) + newline());
+ delta_veh = (sum_avg_veh - sum_veh_star) / (double) results.size();
+ } else writer.write(date("null") + newline());
+ writer.write(closeRow() + newline());
+
+ writer.write(closeTable() + newline());
+
+ writer.write("avg. percentage deviation to best-known result: " + round(delta_res, 2) + newline() + newline());
+ writer.write("avg. absolute deviation to best-known vehicles: " + round(delta_veh, 2) + newline());
+
+ writer.write(openTable() + newline());
+ writer.write(openRow() + newline());
+ writer.write(date("") + newline());
+ writer.write(date("") + newline());
+ writer.write(date("") + newline());
+ writer.write(date("") + newline());
+ writer.write(date(Double.valueOf(average_time).toString(), "align=\"right\"") + newline());
+ writer.write(date(Double.valueOf(average_result).toString(), "align=\"right\"") + newline());
+ writer.write(date(Double.valueOf(average_vehicles).toString(), "align=\"right\"") + newline());
+ if (delta_res != null) {
+ writer.write(date(Double.valueOf(round(delta_res, 2)).toString(), "align=\"right\"") + newline());
+ } else writer.write(date("n.a.") + newline());
+ if (delta_veh != null) {
+ writer.write(date(Double.valueOf(round(delta_veh, 2)).toString(), "align=\"right\"") + newline());
+ } else writer.write(date("n.a.") + newline());
+ writer.write(closeRow() + newline());
+ writer.write(closeTable() + newline());
+
+
+ writer.close();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ }
+
+ private String head(String string, int i) {
+ return "| " + string + " | ";
+ }
+
+ private Double round(Double value, int i) {
+ if (value == null) return null;
+ long roundedVal = Math.round(value * Math.pow(10, i));
+ return (double) roundedVal / (double) (Math.pow(10, i));
+ }
+
+ private String head(String head) {
+ return "" + head + " | ";
+ }
+
+ private String closeTable() {
+ return "
";
+ }
+
+ private String openTable() {
+ return "";
+ }
+
+ private String closeRow() {
+ return "";
+ }
+
+ private String date(String date) {
+ return "| " + date + " | ";
+ }
+
+ private String date(String date, String metaData) {
+ return "" + date + " | ";
+ }
+
+ private String newline() {
+ return "\n";
+ }
+
+ private String openRow() {
+ return "";
+ }
-
}
diff --git a/jsprit-core/pom.xml b/jsprit-core/pom.xml
index 66a21c57..a9f13f25 100644
--- a/jsprit-core/pom.xml
+++ b/jsprit-core/pom.xml
@@ -1,4 +1,3 @@
-
-
-
- jsprit
- jsprit
- 1.6.1-SNAPSHOT
-
- 4.0.0
- jsprit-core
- jsprit-core
+
+
+ jsprit
+ jsprit
+ 1.6.2-SNAPSHOT
+
+ 4.0.0
+ jsprit-core
+ jsprit-core
-
-
-
-
- org.eclipse.m2e
- lifecycle-mapping
- 1.0.0
-
-
-
-
-
- org.apache.maven.plugins
- maven-enforcer-plugin
- [1.0.0,)
-
- enforce
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ org.eclipse.m2e
+ lifecycle-mapping
+ 1.0.0
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-enforcer-plugin
+ [1.0.0,)
+
+ enforce
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ maven-surefire-plugin
+ 2.18.1
+
+ jsprit.core.IntegrationTest
+
+
+
+ maven-failsafe-plugin
+ 2.18.1
+
+
+ **/*.java
+
+ jsprit.core.IntegrationTest
+
+
+
+
+ integration-test
+ verify
+
+
+
+
+
+
-
-
-
- org.apache.commons
- commons-math
- 2.2
- jar
- compile
-
-
-
- commons-configuration
- commons-configuration
- 1.9
- jar
- compile
-
-
- xerces
- xerces
- 2.4.0
- compile
-
-
- org.apache.commons
- commons-math3
- 3.4
-
+
+
+
+ org.apache.commons
+ commons-math
+ 2.2
+ jar
+ compile
+
+
+
+ commons-configuration
+ commons-configuration
+ 1.9
+ jar
+ compile
+
+
+
+ xerces
+ xercesImpl
+ 2.11.0
+ compile
+
+
+
+ org.apache.commons
+ commons-math3
+ 3.4
+
+
+
+
-
-
-
diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/InsertionInitialSolutionFactory.java b/jsprit-core/src/main/java/jsprit/core/algorithm/InsertionInitialSolutionFactory.java
index 2e94d01e..9955fcd2 100644
--- a/jsprit-core/src/main/java/jsprit/core/algorithm/InsertionInitialSolutionFactory.java
+++ b/jsprit-core/src/main/java/jsprit/core/algorithm/InsertionInitialSolutionFactory.java
@@ -1,17 +1,17 @@
/*******************************************************************************
* Copyright (C) 2013 Stefan Schroeder
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
+ * License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
+ *
+ * You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see .
******************************************************************************/
@@ -25,6 +25,7 @@ import jsprit.core.problem.solution.InitialSolutionFactory;
import jsprit.core.problem.solution.SolutionCostCalculator;
import jsprit.core.problem.solution.VehicleRoutingProblemSolution;
import jsprit.core.problem.solution.route.VehicleRoute;
+import jsprit.core.problem.vehicle.Vehicle;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -35,32 +36,36 @@ import java.util.List;
public final class InsertionInitialSolutionFactory implements InitialSolutionFactory {
- private static final Logger logger = LogManager.getLogger(InsertionInitialSolutionFactory.class);
+ private static final Logger logger = LogManager.getLogger(InsertionInitialSolutionFactory.class);
- private final InsertionStrategy insertion;
+ private final InsertionStrategy insertion;
- private SolutionCostCalculator solutionCostsCalculator;
+ private SolutionCostCalculator solutionCostsCalculator;
- public InsertionInitialSolutionFactory(InsertionStrategy insertionStrategy, SolutionCostCalculator solutionCostCalculator) {
- super();
- this.insertion = insertionStrategy;
- this.solutionCostsCalculator = solutionCostCalculator;
- }
+ public InsertionInitialSolutionFactory(InsertionStrategy insertionStrategy, SolutionCostCalculator solutionCostCalculator) {
+ super();
+ this.insertion = insertionStrategy;
+ this.solutionCostsCalculator = solutionCostCalculator;
+ }
- @Override
- public VehicleRoutingProblemSolution createSolution(final VehicleRoutingProblem vrp) {
- logger.info("create initial solution");
- List vehicleRoutes = new ArrayList();
- vehicleRoutes.addAll(vrp.getInitialVehicleRoutes());
- Collection badJobs = insertion.insertJobs(vehicleRoutes, getUnassignedJobs(vrp));
- VehicleRoutingProblemSolution solution = new VehicleRoutingProblemSolution(vehicleRoutes, badJobs, Double.MAX_VALUE);
- double costs = solutionCostsCalculator.getCosts(solution);
- solution.setCost(costs);
- return solution;
- }
+ @Override
+ public VehicleRoutingProblemSolution createSolution(final VehicleRoutingProblem vrp) {
+ logger.info("create initial solution");
+ List vehicleRoutes = new ArrayList();
+ vehicleRoutes.addAll(vrp.getInitialVehicleRoutes());
+ Collection badJobs = insertion.insertJobs(vehicleRoutes, getUnassignedJobs(vrp));
+ VehicleRoutingProblemSolution solution = new VehicleRoutingProblemSolution(vehicleRoutes, badJobs, Double.MAX_VALUE);
+ double costs = solutionCostsCalculator.getCosts(solution);
+ solution.setCost(costs);
+ return solution;
+ }
- private List getUnassignedJobs(VehicleRoutingProblem vrp) {
- return new ArrayList(vrp.getJobs().values());
- }
+ private List getUnassignedJobs(VehicleRoutingProblem vrp) {
+ ArrayList jobs = new ArrayList(vrp.getJobs().values());
+ for (Vehicle v : vrp.getVehicles()) {
+ if (v.getBreak() != null) jobs.add(v.getBreak());
+ }
+ return jobs;
+ }
}
diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/PrettyAlgorithmBuilder.java b/jsprit-core/src/main/java/jsprit/core/algorithm/PrettyAlgorithmBuilder.java
index 41b33089..733bb05c 100644
--- a/jsprit-core/src/main/java/jsprit/core/algorithm/PrettyAlgorithmBuilder.java
+++ b/jsprit-core/src/main/java/jsprit/core/algorithm/PrettyAlgorithmBuilder.java
@@ -25,6 +25,7 @@ import jsprit.core.algorithm.recreate.VehicleSwitched;
import jsprit.core.algorithm.state.*;
import jsprit.core.problem.VehicleRoutingProblem;
import jsprit.core.problem.constraint.ConstraintManager;
+import jsprit.core.problem.constraint.SwitchNotFeasible;
import jsprit.core.problem.solution.SolutionCostCalculator;
import jsprit.core.problem.solution.VehicleRoutingProblemSolution;
import jsprit.core.problem.solution.route.VehicleRoute;
@@ -36,8 +37,8 @@ import jsprit.core.util.ActivityTimeTracker;
import java.util.*;
/**
-* Created by schroeder on 10.12.14.
-*/
+ * Created by schroeder on 10.12.14.
+ */
public class PrettyAlgorithmBuilder {
private final VehicleRoutingProblem vrp;
@@ -56,11 +57,11 @@ public class PrettyAlgorithmBuilder {
private boolean coreStuff = false;
- public static PrettyAlgorithmBuilder newInstance(VehicleRoutingProblem vrp, VehicleFleetManager fleetManager, StateManager stateManager, ConstraintManager constraintManager){
- return new PrettyAlgorithmBuilder(vrp,fleetManager,stateManager,constraintManager);
+ public static PrettyAlgorithmBuilder newInstance(VehicleRoutingProblem vrp, VehicleFleetManager fleetManager, StateManager stateManager, ConstraintManager constraintManager) {
+ return new PrettyAlgorithmBuilder(vrp, fleetManager, stateManager, constraintManager);
}
- PrettyAlgorithmBuilder(VehicleRoutingProblem vrp, VehicleFleetManager fleetManager, StateManager stateManager, ConstraintManager constraintManager){
+ PrettyAlgorithmBuilder(VehicleRoutingProblem vrp, VehicleFleetManager fleetManager, StateManager stateManager, ConstraintManager constraintManager) {
this.vrp = vrp;
this.fleetManager = fleetManager;
this.stateManager = stateManager;
@@ -68,40 +69,41 @@ public class PrettyAlgorithmBuilder {
this.searchStrategyManager = new SearchStrategyManager();
}
- public PrettyAlgorithmBuilder setRandom(Random random){
+ public PrettyAlgorithmBuilder setRandom(Random random) {
searchStrategyManager.setRandom(random);
return this;
}
- public PrettyAlgorithmBuilder withStrategy(SearchStrategy strategy, double weight){
- searchStrategyManager.addStrategy(strategy,weight);
+ public PrettyAlgorithmBuilder withStrategy(SearchStrategy strategy, double weight) {
+ searchStrategyManager.addStrategy(strategy, weight);
return this;
}
- public PrettyAlgorithmBuilder constructInitialSolutionWith(InsertionStrategy insertionStrategy, SolutionCostCalculator objFunction){
+ public PrettyAlgorithmBuilder constructInitialSolutionWith(InsertionStrategy insertionStrategy, SolutionCostCalculator objFunction) {
this.iniInsertionStrategy = insertionStrategy;
this.iniObjFunction = objFunction;
return this;
}
- public VehicleRoutingAlgorithm build(){
- if(coreStuff){
+ public VehicleRoutingAlgorithm build() {
+ if (coreStuff) {
constraintManager.addTimeWindowConstraint();
constraintManager.addLoadConstraint();
constraintManager.addSkillsConstraint();
+ constraintManager.addConstraint(new SwitchNotFeasible(stateManager));
stateManager.updateLoadStates();
stateManager.updateTimeWindowStates();
- UpdateVehicleDependentPracticalTimeWindows tw_updater = new UpdateVehicleDependentPracticalTimeWindows(stateManager, vrp.getTransportCosts());
- tw_updater.setVehiclesToUpdate(new UpdateVehicleDependentPracticalTimeWindows.VehiclesToUpdate() {
+ UpdateVehicleDependentPracticalTimeWindows twUpdater = new UpdateVehicleDependentPracticalTimeWindows(stateManager, vrp.getTransportCosts());
+ twUpdater.setVehiclesToUpdate(new UpdateVehicleDependentPracticalTimeWindows.VehiclesToUpdate() {
- Map uniqueTypes = new HashMap();
+ Map uniqueTypes = new HashMap();
@Override
public Collection get(VehicleRoute vehicleRoute) {
- if(uniqueTypes.isEmpty()){
- for( Vehicle v : vrp.getVehicles()){
- if(!uniqueTypes.containsKey(v.getVehicleTypeIdentifier())){
- uniqueTypes.put(v.getVehicleTypeIdentifier(),v);
+ if (uniqueTypes.isEmpty()) {
+ for (Vehicle v : vrp.getVehicles()) {
+ if (!uniqueTypes.containsKey(v.getVehicleTypeIdentifier())) {
+ uniqueTypes.put(v.getVehicleTypeIdentifier(), v);
}
}
}
@@ -109,14 +111,16 @@ public class PrettyAlgorithmBuilder {
vehicles.addAll(uniqueTypes.values());
return vehicles;
}
+
});
- stateManager.addStateUpdater(tw_updater);
+ stateManager.addStateUpdater(twUpdater);
stateManager.updateSkillStates();
stateManager.addStateUpdater(new UpdateEndLocationIfRouteIsOpen());
stateManager.addStateUpdater(new UpdateActivityTimes(vrp.getTransportCosts(), ActivityTimeTracker.ActivityPolicy.AS_SOON_AS_TIME_WINDOW_OPENS));
stateManager.addStateUpdater(new UpdateVariableCosts(vrp.getActivityCosts(), vrp.getTransportCosts(), stateManager));
+ stateManager.addStateUpdater(new UpdateFutureWaitingTimes(stateManager, vrp.getTransportCosts()));
}
- VehicleRoutingAlgorithm vra = new VehicleRoutingAlgorithm(vrp,searchStrategyManager);
+ VehicleRoutingAlgorithm vra = new VehicleRoutingAlgorithm(vrp, searchStrategyManager);
vra.addListener(stateManager);
RemoveEmptyVehicles removeEmptyVehicles = new RemoveEmptyVehicles(fleetManager);
ResetAndIniFleetManager resetAndIniFleetManager = new ResetAndIniFleetManager(fleetManager);
@@ -124,7 +128,7 @@ public class PrettyAlgorithmBuilder {
vra.addListener(removeEmptyVehicles);
vra.addListener(resetAndIniFleetManager);
vra.addListener(vehicleSwitched);
- if(iniInsertionStrategy != null) {
+ if (iniInsertionStrategy != null) {
if (!iniInsertionStrategy.getListeners().contains(removeEmptyVehicles))
iniInsertionStrategy.addListener(removeEmptyVehicles);
if (!iniInsertionStrategy.getListeners().contains(resetAndIniFleetManager))
@@ -136,7 +140,9 @@ public class PrettyAlgorithmBuilder {
vra.addListener(new AlgorithmStartsListener() {
@Override
public void informAlgorithmStarts(VehicleRoutingProblem problem, VehicleRoutingAlgorithm algorithm, Collection solutions) {
- solutions.add(new InsertionInitialSolutionFactory(iniInsertionStrategy, iniObjFunction).createSolution(vrp));
+ if (solutions.isEmpty()) {
+ solutions.add(new InsertionInitialSolutionFactory(iniInsertionStrategy, iniObjFunction).createSolution(vrp));
+ }
}
});
}
@@ -150,10 +156,10 @@ public class PrettyAlgorithmBuilder {
private void searchSchrimpfAndRegister(VehicleRoutingAlgorithm vra) {
boolean schrimpfAdded = false;
- for(SearchStrategy strategy : vra.getSearchStrategyManager().getStrategies()){
+ for (SearchStrategy strategy : vra.getSearchStrategyManager().getStrategies()) {
SolutionAcceptor acceptor = strategy.getSolutionAcceptor();
- if(acceptor instanceof SchrimpfAcceptance){
- if(!schrimpfAdded) {
+ if (acceptor instanceof SchrimpfAcceptance) {
+ if (!schrimpfAdded) {
vra.addListener((SchrimpfAcceptance) acceptor);
schrimpfAdded = true;
}
diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/RemoveEmptyVehicles.java b/jsprit-core/src/main/java/jsprit/core/algorithm/RemoveEmptyVehicles.java
index e4438455..4f5255a4 100644
--- a/jsprit-core/src/main/java/jsprit/core/algorithm/RemoveEmptyVehicles.java
+++ b/jsprit-core/src/main/java/jsprit/core/algorithm/RemoveEmptyVehicles.java
@@ -1,17 +1,17 @@
/*******************************************************************************
* Copyright (C) 2013 Stefan Schroeder
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
+ * License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
+ *
+ * You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see .
******************************************************************************/
package jsprit.core.algorithm;
@@ -25,28 +25,28 @@ import java.util.Collection;
import java.util.List;
-public class RemoveEmptyVehicles implements InsertionEndsListener{
+public class RemoveEmptyVehicles implements InsertionEndsListener {
- private VehicleFleetManager fleetManager;
-
- public RemoveEmptyVehicles(VehicleFleetManager fleetManager) {
- super();
- this.fleetManager = fleetManager;
- }
+ private VehicleFleetManager fleetManager;
- @Override
- public String toString() {
- return "[name=removeEmptyVehicles]";
- }
+ public RemoveEmptyVehicles(VehicleFleetManager fleetManager) {
+ super();
+ this.fleetManager = fleetManager;
+ }
- @Override
- public void informInsertionEnds(Collection vehicleRoutes) {
- List routes = new ArrayList(vehicleRoutes);
- for(VehicleRoute route : routes){
- if(route.isEmpty()) {
- fleetManager.unlock(route.getVehicle());
- vehicleRoutes.remove(route);
- }
- }
- }
+ @Override
+ public String toString() {
+ return "[name=removeEmptyVehicles]";
+ }
+
+ @Override
+ public void informInsertionEnds(Collection vehicleRoutes) {
+ List routes = new ArrayList(vehicleRoutes);
+ for (VehicleRoute route : routes) {
+ if (route.isEmpty()) {
+ fleetManager.unlock(route.getVehicle());
+ vehicleRoutes.remove(route);
+ }
+ }
+ }
}
diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/ResetAndIniFleetManager.java b/jsprit-core/src/main/java/jsprit/core/algorithm/ResetAndIniFleetManager.java
index 4ef1bafa..4ff712a7 100644
--- a/jsprit-core/src/main/java/jsprit/core/algorithm/ResetAndIniFleetManager.java
+++ b/jsprit-core/src/main/java/jsprit/core/algorithm/ResetAndIniFleetManager.java
@@ -1,17 +1,17 @@
/*******************************************************************************
* Copyright (C) 2013 Stefan Schroeder
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
+ * License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
+ *
+ * You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see .
******************************************************************************/
package jsprit.core.algorithm;
@@ -25,26 +25,26 @@ import java.util.ArrayList;
import java.util.Collection;
-public class ResetAndIniFleetManager implements InsertionStartsListener{
+public class ResetAndIniFleetManager implements InsertionStartsListener {
- private VehicleFleetManager vehicleFleetManager;
-
- public ResetAndIniFleetManager(VehicleFleetManager vehicleFleetManager) {
- super();
- this.vehicleFleetManager = vehicleFleetManager;
- }
+ private VehicleFleetManager vehicleFleetManager;
- @Override
- public void informInsertionStarts(Collection vehicleRoutes, Collection unassignedJobs) {
- vehicleFleetManager.unlockAll();
- Collection routes = new ArrayList(vehicleRoutes);
- for(VehicleRoute route : routes){
- vehicleFleetManager.lock(route.getVehicle());
- }
- }
+ public ResetAndIniFleetManager(VehicleFleetManager vehicleFleetManager) {
+ super();
+ this.vehicleFleetManager = vehicleFleetManager;
+ }
- @Override
- public String toString() {
- return "[name=resetAndIniFleetManager]";
- }
+ @Override
+ public void informInsertionStarts(Collection vehicleRoutes, Collection unassignedJobs) {
+ vehicleFleetManager.unlockAll();
+ Collection routes = new ArrayList(vehicleRoutes);
+ for (VehicleRoute route : routes) {
+ vehicleFleetManager.lock(route.getVehicle());
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "[name=resetAndIniFleetManager]";
+ }
}
diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/SearchStrategy.java b/jsprit-core/src/main/java/jsprit/core/algorithm/SearchStrategy.java
index 711d3724..5f07727f 100644
--- a/jsprit-core/src/main/java/jsprit/core/algorithm/SearchStrategy.java
+++ b/jsprit-core/src/main/java/jsprit/core/algorithm/SearchStrategy.java
@@ -11,7 +11,7 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
- * You should have received a copy of the GNU Lesser General Public
+ * You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see .
******************************************************************************/
package jsprit.core.algorithm;
@@ -31,64 +31,66 @@ import java.util.Collections;
public class SearchStrategy {
-
- public static class DiscoveredSolution {
- private VehicleRoutingProblemSolution solution;
+ public static class DiscoveredSolution {
- private boolean accepted;
+ private VehicleRoutingProblemSolution solution;
- private String strategyId;
-
- public DiscoveredSolution(VehicleRoutingProblemSolution solution, boolean accepted, String strategyId) {
- super();
- this.solution = solution;
- this.accepted = accepted;
- this.strategyId = strategyId;
- }
+ private boolean accepted;
- public VehicleRoutingProblemSolution getSolution() {
- return solution;
- }
+ private String strategyId;
- public boolean isAccepted() {
- return accepted;
- }
+ public DiscoveredSolution(VehicleRoutingProblemSolution solution, boolean accepted, String strategyId) {
+ super();
+ this.solution = solution;
+ this.accepted = accepted;
+ this.strategyId = strategyId;
+ }
- @Deprecated
+ public VehicleRoutingProblemSolution getSolution() {
+ return solution;
+ }
+
+ public boolean isAccepted() {
+ return accepted;
+ }
+
+ @Deprecated
public String getStrategyName() {
- return strategyId;
- }
+ return strategyId;
+ }
- public String getStrategyId() { return strategyId; }
+ public String getStrategyId() {
+ return strategyId;
+ }
- @Override
- public String toString() {
- return "[strategyId="+strategyId+"][solution="+solution+"][accepted="+accepted+"]";
- }
- }
-
- private static Logger logger = LogManager.getLogger(SearchStrategy.class);
-
- private final Collection searchStrategyModules = new ArrayList();
-
- private final SolutionSelector solutionSelector;
-
- private final SolutionCostCalculator solutionCostCalculator;
+ @Override
+ public String toString() {
+ return "[strategyId=" + strategyId + "][solution=" + solution + "][accepted=" + accepted + "]";
+ }
+ }
- private final SolutionAcceptor solutionAcceptor;
+ private static Logger logger = LogManager.getLogger(SearchStrategy.class);
+
+ private final Collection searchStrategyModules = new ArrayList();
+
+ private final SolutionSelector solutionSelector;
+
+ private final SolutionCostCalculator solutionCostCalculator;
+
+ private final SolutionAcceptor solutionAcceptor;
private final String id;
-
- private String name;
+
+ private String name;
public SearchStrategy(String id, SolutionSelector solutionSelector, SolutionAcceptor solutionAcceptor, SolutionCostCalculator solutionCostCalculator) {
- if(id == null) throw new IllegalStateException("strategy id cannot be null");
+ if (id == null) throw new IllegalStateException("strategy id cannot be null");
this.solutionSelector = solutionSelector;
this.solutionAcceptor = solutionAcceptor;
this.solutionCostCalculator = solutionCostCalculator;
this.id = id;
- logger.debug("initialise " + this);
+ logger.debug("initialise {}", this);
}
public String getId() {
@@ -96,77 +98,77 @@ public class SearchStrategy {
}
public String getName() {
- return name;
- }
+ return name;
+ }
- public void setName(String name) {
- this.name = name;
- }
+ public void setName(String name) {
+ this.name = name;
+ }
- public Collection getSearchStrategyModules() {
- return Collections.unmodifiableCollection(searchStrategyModules);
- }
-
- @SuppressWarnings("UnusedDeclaration")
- public SolutionSelector getSolutionSelector() {
- return solutionSelector;
- }
+ public Collection getSearchStrategyModules() {
+ return Collections.unmodifiableCollection(searchStrategyModules);
+ }
@SuppressWarnings("UnusedDeclaration")
- public SolutionAcceptor getSolutionAcceptor() {
- return solutionAcceptor;
- }
+ public SolutionSelector getSolutionSelector() {
+ return solutionSelector;
+ }
- @Override
- public String toString() {
- return "searchStrategy [#modules="+searchStrategyModules.size()+"][selector="+solutionSelector+"][acceptor="+solutionAcceptor+"]";
- }
-
- /**
- * Runs the search-strategy and its according modules, and returns DiscoveredSolution.
- *
- * This involves three basic steps: 1) Selecting a solution from solutions (input parameter) according to {@link jsprit.core.algorithm.selector.SolutionSelector}, 2) running the modules
- * ({@link jsprit.core.algorithm.SearchStrategyModule}) on the selectedSolution and 3) accepting the new solution according to {@link jsprit.core.algorithm.acceptor.SolutionAcceptor}.
- *
Note that after 1) the selected solution is copied, thus the original solution is not modified.
- *
Note also that 3) modifies the input parameter solutions by adding, removing, replacing the existing solutions or whatever is defined in the solutionAcceptor.
- *
- * @param vrp the underlying vehicle routing problem
- * @param solutions which will be modified
- * @return discoveredSolution
+ @SuppressWarnings("UnusedDeclaration")
+ public SolutionAcceptor getSolutionAcceptor() {
+ return solutionAcceptor;
+ }
+
+ @Override
+ public String toString() {
+ return "searchStrategy [#modules=" + searchStrategyModules.size() + "][selector=" + solutionSelector + "][acceptor=" + solutionAcceptor + "]";
+ }
+
+ /**
+ * Runs the search-strategy and its according modules, and returns DiscoveredSolution.
+ *
+ * This involves three basic steps: 1) Selecting a solution from solutions (input parameter) according to {@link jsprit.core.algorithm.selector.SolutionSelector}, 2) running the modules
+ * ({@link jsprit.core.algorithm.SearchStrategyModule}) on the selectedSolution and 3) accepting the new solution according to {@link jsprit.core.algorithm.acceptor.SolutionAcceptor}.
+ *
Note that after 1) the selected solution is copied, thus the original solution is not modified.
+ *
Note also that 3) modifies the input parameter solutions by adding, removing, replacing the existing solutions or whatever is defined in the solutionAcceptor.
+ *
+ * @param vrp the underlying vehicle routing problem
+ * @param solutions which will be modified
+ * @return discoveredSolution
* @throws java.lang.IllegalStateException if selector cannot select any solution
*/
- @SuppressWarnings("UnusedParameters")
- public DiscoveredSolution run(VehicleRoutingProblem vrp, Collection solutions){
- VehicleRoutingProblemSolution solution = solutionSelector.selectSolution(solutions);
- if(solution == null) throw new IllegalStateException(getErrMsg());
- VehicleRoutingProblemSolution lastSolution = VehicleRoutingProblemSolution.copyOf(solution);
- for(SearchStrategyModule module : searchStrategyModules){
+ @SuppressWarnings("UnusedParameters")
+ public DiscoveredSolution run(VehicleRoutingProblem vrp, Collection solutions) {
+ VehicleRoutingProblemSolution solution = solutionSelector.selectSolution(solutions);
+ if (solution == null) throw new IllegalStateException(getErrMsg());
+ VehicleRoutingProblemSolution lastSolution = VehicleRoutingProblemSolution.copyOf(solution);
+ for (SearchStrategyModule module : searchStrategyModules) {
lastSolution = module.runAndGetSolution(lastSolution);
- }
- double costs = solutionCostCalculator.getCosts(lastSolution);
- lastSolution.setCost(costs);
- boolean solutionAccepted = solutionAcceptor.acceptSolution(solutions, lastSolution);
- return new DiscoveredSolution(lastSolution, solutionAccepted, getId());
- }
+ }
+ double costs = solutionCostCalculator.getCosts(lastSolution);
+ lastSolution.setCost(costs);
+ boolean solutionAccepted = solutionAcceptor.acceptSolution(solutions, lastSolution);
+ return new DiscoveredSolution(lastSolution, solutionAccepted, getId());
+ }
private String getErrMsg() {
return "solution is null. check solutionSelector to return an appropriate solution. " +
- "\nfigure out whether you start with an initial solution. either you set it manually by algorithm.addInitialSolution(...)"
- + " or let the algorithm create an initial solution for you. then add the ... xml-snippet to your algorithm's config file.";
+ "\nfigure out whether you start with an initial solution. either you set it manually by algorithm.addInitialSolution(...)"
+ + " or let the algorithm create an initial solution for you. then add the ... xml-snippet to your algorithm's config file.";
}
- public void addModule(SearchStrategyModule module){
- if(module == null) throw new IllegalStateException("module to be added is null.");
- searchStrategyModules.add(module);
- logger.debug("module added [module=" + module + "][#modules=" + searchStrategyModules.size() + "]");
- }
+ public void addModule(SearchStrategyModule module) {
+ if (module == null) throw new IllegalStateException("module to be added is null.");
+ searchStrategyModules.add(module);
+ logger.debug("module added [module={}][#modules={}]", module, searchStrategyModules.size());
+ }
- public void addModuleListener(SearchStrategyModuleListener moduleListener) {
- for(SearchStrategyModule module : searchStrategyModules){
- module.addModuleListener(moduleListener);
- }
-
- }
+ public void addModuleListener(SearchStrategyModuleListener moduleListener) {
+ for (SearchStrategyModule module : searchStrategyModules) {
+ module.addModuleListener(moduleListener);
+ }
+
+ }
}
diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/SearchStrategyManager.java b/jsprit-core/src/main/java/jsprit/core/algorithm/SearchStrategyManager.java
index b5ce9935..3feaa696 100644
--- a/jsprit-core/src/main/java/jsprit/core/algorithm/SearchStrategyManager.java
+++ b/jsprit-core/src/main/java/jsprit/core/algorithm/SearchStrategyManager.java
@@ -11,7 +11,7 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
- * You should have received a copy of the GNU Lesser General Public
+ * You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see .
******************************************************************************/
package jsprit.core.algorithm;
@@ -27,71 +27,75 @@ import java.util.*;
public class SearchStrategyManager {
- private final static Logger logger = LogManager.getLogger();
-
- private List searchStrategyListeners = new ArrayList();
-
- private List strategies = new ArrayList();
-
- private List weights = new ArrayList();
+ private final static Logger logger = LogManager.getLogger();
- private Map id2index = new HashMap();
-
- private Random random = RandomNumberGeneration.getRandom();
-
- private double sumWeights = 0;
+ private List searchStrategyListeners = new ArrayList();
+
+ private List strategies = new ArrayList();
+
+ private List weights = new ArrayList();
+
+ private Map id2index = new HashMap();
+
+ private Random random = RandomNumberGeneration.getRandom();
+
+ private double sumWeights = 0;
private int strategyIndex = 0;
-
- public void setRandom(Random random) {
- this.random = random;
- }
-
- public List getStrategies() {
- return Collections.unmodifiableList(strategies);
- }
+
+ public void setRandom(Random random) {
+ this.random = random;
+ }
+
+ public List getStrategies() {
+ return Collections.unmodifiableList(strategies);
+ }
/**
* Returns the probabilities.
* [schroeder (2014.11.21): Now they are actually no propabilities anymore but weights. The resulting probabilities
* are calculated here with the sum of weights]
+ *
* @return list of probabilities
*/
- @Deprecated
- public List getProbabilities() {
- return Collections.unmodifiableList(weights);
- }
+ @Deprecated
+ public List getProbabilities() {
+ return Collections.unmodifiableList(weights);
+ }
- public List getWeights(){ return Collections.unmodifiableList(weights); }
+ public List getWeights() {
+ return Collections.unmodifiableList(weights);
+ }
- public double getWeight(String strategyId){
- return weights.get(id2index.get(strategyId));
- }
+ public double getWeight(String strategyId) {
+ return weights.get(id2index.get(strategyId));
+ }
- /**
- * adds a new search strategy with a certain weight.
- * @param strategy strategy to be added
- * @param weight of corresponding strategy to be added
+ /**
+ * adds a new search strategy with a certain weight.
+ *
+ * @param strategy strategy to be added
+ * @param weight of corresponding strategy to be added
* @throws java.lang.IllegalStateException if strategy is null OR weight < 0
- */
- public void addStrategy(SearchStrategy strategy, double weight){
- if(strategy == null){
+ */
+ public void addStrategy(SearchStrategy strategy, double weight) {
+ if (strategy == null) {
throw new IllegalStateException("strategy is null. make sure adding a valid strategy.");
}
- if(id2index.keySet().contains(strategy.getId())){
+ if (id2index.keySet().contains(strategy.getId())) {
throw new IllegalStateException("strategyId " + strategy.getId() + " already in use. replace strateId in your config file or code with a unique strategy id");
}
- if(weight < 0.0){
- throw new IllegalStateException("weight is lower than zero.");
- }
- id2index.put(strategy.getId(),strategyIndex);
+ if (weight < 0.0) {
+ throw new IllegalStateException("weight is lower than zero.");
+ }
+ id2index.put(strategy.getId(), strategyIndex);
strategyIndex++;
- strategies.add(strategy);
- weights.add(weight);
- sumWeights += weight;
- }
+ strategies.add(strategy);
+ weights.add(weight);
+ sumWeights += weight;
+ }
- public void informStrategyWeightChanged(String strategyId, double weight){
+ public void informStrategyWeightChanged(String strategyId, double weight) {
int strategyIndex = id2index.get(strategyId);
weights.set(strategyIndex, weight);
updateSumWeights();
@@ -99,7 +103,7 @@ public class SearchStrategyManager {
private void updateSumWeights() {
double sum = 0.;
- for(double w : weights){
+ for (double w : weights) {
sum += w;
}
sumWeights = sum;
@@ -111,26 +115,27 @@ public class SearchStrategyManager {
* @return selected search strategy
* @throws java.lang.IllegalStateException if randomNumberGenerator is null OR no search strategy can be found
*/
- public SearchStrategy getRandomStrategy() {
- if(random == null) throw new IllegalStateException("randomizer is null. make sure you set random object correctly");
- double randomFig = random.nextDouble();
- double sumProbabilities = 0.0;
- for (int i = 0; i < weights.size(); i++) {
- sumProbabilities += weights.get(i) / sumWeights;
- if (randomFig < sumProbabilities) {
- return strategies.get(i);
- }
- }
- throw new IllegalStateException("no search-strategy found");
- }
-
- public void addSearchStrategyListener(SearchStrategyListener strategyListener){
- searchStrategyListeners.add(strategyListener);
- }
-
- public void addSearchStrategyModuleListener(SearchStrategyModuleListener moduleListener){
- for(SearchStrategy s : strategies){
- s.addModuleListener(moduleListener);
- }
- }
+ public SearchStrategy getRandomStrategy() {
+ if (random == null)
+ throw new IllegalStateException("randomizer is null. make sure you set random object correctly");
+ double randomFig = random.nextDouble();
+ double sumProbabilities = 0.0;
+ for (int i = 0; i < weights.size(); i++) {
+ sumProbabilities += weights.get(i) / sumWeights;
+ if (randomFig < sumProbabilities) {
+ return strategies.get(i);
+ }
+ }
+ throw new IllegalStateException("no search-strategy found");
+ }
+
+ public void addSearchStrategyListener(SearchStrategyListener strategyListener) {
+ searchStrategyListeners.add(strategyListener);
+ }
+
+ public void addSearchStrategyModuleListener(SearchStrategyModuleListener moduleListener) {
+ for (SearchStrategy s : strategies) {
+ s.addModuleListener(moduleListener);
+ }
+ }
}
diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/SearchStrategyModule.java b/jsprit-core/src/main/java/jsprit/core/algorithm/SearchStrategyModule.java
index 6551b11b..c847a31d 100644
--- a/jsprit-core/src/main/java/jsprit/core/algorithm/SearchStrategyModule.java
+++ b/jsprit-core/src/main/java/jsprit/core/algorithm/SearchStrategyModule.java
@@ -1,17 +1,17 @@
/*******************************************************************************
* Copyright (C) 2013 Stefan Schroeder
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
+ * License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
+ *
+ * You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see .
******************************************************************************/
package jsprit.core.algorithm;
@@ -21,11 +21,11 @@ import jsprit.core.problem.solution.VehicleRoutingProblemSolution;
public interface SearchStrategyModule {
-
- public VehicleRoutingProblemSolution runAndGetSolution(VehicleRoutingProblemSolution vrpSolution);
-
- public String getName();
- public void addModuleListener(SearchStrategyModuleListener moduleListener);
+ public VehicleRoutingProblemSolution runAndGetSolution(VehicleRoutingProblemSolution vrpSolution);
+
+ public String getName();
+
+ public void addModuleListener(SearchStrategyModuleListener moduleListener);
}
diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/VariablePlusFixedSolutionCostCalculatorFactory.java b/jsprit-core/src/main/java/jsprit/core/algorithm/VariablePlusFixedSolutionCostCalculatorFactory.java
index 5e02b6f0..d4b6d979 100644
--- a/jsprit-core/src/main/java/jsprit/core/algorithm/VariablePlusFixedSolutionCostCalculatorFactory.java
+++ b/jsprit-core/src/main/java/jsprit/core/algorithm/VariablePlusFixedSolutionCostCalculatorFactory.java
@@ -1,18 +1,18 @@
/*******************************************************************************
* Copyright (c) 2014 Stefan Schroeder.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
+ * License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
+ *
+ * You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see .
- *
+ *
* Contributors:
* Stefan Schroeder - initial API and implementation
******************************************************************************/
@@ -29,39 +29,38 @@ import jsprit.core.problem.vehicle.Vehicle;
* Default objective function which is the sum of all fixed vehicle and variable
* transportation costs, i.e. each is generated solution is evaluated according
* this objective function.
- *
- * @author schroeder
*
+ * @author schroeder
*/
public class VariablePlusFixedSolutionCostCalculatorFactory {
-
- private RouteAndActivityStateGetter stateManager;
-
- public VariablePlusFixedSolutionCostCalculatorFactory(RouteAndActivityStateGetter stateManager) {
- super();
- this.stateManager = stateManager;
- }
- public SolutionCostCalculator createCalculator(){
- return new SolutionCostCalculator() {
+ private RouteAndActivityStateGetter stateManager;
- @Override
- public double getCosts(VehicleRoutingProblemSolution solution) {
- double c = 0.0;
- for(VehicleRoute r : solution.getRoutes()){
- c += stateManager.getRouteState(r, InternalStates.COSTS, Double.class);
- c += getFixedCosts(r.getVehicle());
- }
+ public VariablePlusFixedSolutionCostCalculatorFactory(RouteAndActivityStateGetter stateManager) {
+ super();
+ this.stateManager = stateManager;
+ }
+
+ public SolutionCostCalculator createCalculator() {
+ return new SolutionCostCalculator() {
+
+ @Override
+ public double getCosts(VehicleRoutingProblemSolution solution) {
+ double c = 0.0;
+ for (VehicleRoute r : solution.getRoutes()) {
+ c += stateManager.getRouteState(r, InternalStates.COSTS, Double.class);
+ c += getFixedCosts(r.getVehicle());
+ }
c += solution.getUnassignedJobs().size() * c * .1;
- return c;
- }
+ return c;
+ }
private double getFixedCosts(Vehicle vehicle) {
- if(vehicle == null) return 0.0;
- if(vehicle.getType() == null) return 0.0;
+ if (vehicle == null) return 0.0;
+ if (vehicle.getType() == null) return 0.0;
return vehicle.getType().getVehicleCostParams().fix;
}
- };
- }
+ };
+ }
}
diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/VehicleRoutingAlgorithm.java b/jsprit-core/src/main/java/jsprit/core/algorithm/VehicleRoutingAlgorithm.java
index df46b466..466ff4e6 100644
--- a/jsprit-core/src/main/java/jsprit/core/algorithm/VehicleRoutingAlgorithm.java
+++ b/jsprit-core/src/main/java/jsprit/core/algorithm/VehicleRoutingAlgorithm.java
@@ -11,7 +11,7 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
- * You should have received a copy of the GNU Lesser General Public
+ * You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see .
******************************************************************************/
package jsprit.core.algorithm;
@@ -20,6 +20,7 @@ import jsprit.core.algorithm.SearchStrategy.DiscoveredSolution;
import jsprit.core.algorithm.listener.*;
import jsprit.core.algorithm.termination.PrematureAlgorithmTermination;
import jsprit.core.problem.VehicleRoutingProblem;
+import jsprit.core.problem.job.Job;
import jsprit.core.problem.solution.VehicleRoutingProblemSolution;
import jsprit.core.problem.solution.route.VehicleRoute;
import jsprit.core.problem.solution.route.activity.TourActivity;
@@ -33,9 +34,8 @@ import java.util.Collection;
/**
* Algorithm that solves a {@link VehicleRoutingProblem}.
- *
- * @author stefan schroeder
*
+ * @author stefan schroeder
*/
public class VehicleRoutingAlgorithm {
@@ -43,14 +43,14 @@ public class VehicleRoutingAlgorithm {
private Collection terminationCriteria = new ArrayList();
- void addTermination(PrematureAlgorithmTermination termination){
+ void addTermination(PrematureAlgorithmTermination termination) {
terminationCriteria.add(termination);
}
@Override
public boolean isPrematureBreak(DiscoveredSolution discoveredSolution) {
- for(PrematureAlgorithmTermination termination : terminationCriteria){
- if(termination.isPrematureBreak(discoveredSolution)){
+ for (PrematureAlgorithmTermination termination : terminationCriteria) {
+ if (termination.isPrematureBreak(discoveredSolution)) {
return true;
}
}
@@ -59,31 +59,31 @@ public class VehicleRoutingAlgorithm {
}
private static class Counter {
- private final String name;
- private long counter = 0;
- private long nextCounter = 1;
- private static final Logger log = LogManager.getLogger(Counter.class);
+ private final String name;
+ private long counter = 0;
+ private long nextCounter = 1;
+ private static final Logger log = LogManager.getLogger(Counter.class);
- public Counter(final String name) {
- this.name = name;
- }
+ public Counter(final String name) {
+ this.name = name;
+ }
- public void incCounter() {
- long i = counter++;
- long n = nextCounter;
- if (i >= n) {
- nextCounter=n*2;
+ public void incCounter() {
+ long i = counter++;
+ long n = nextCounter;
+ if (i >= n) {
+ nextCounter = n * 2;
log.info(this.name + n);
- }
- }
+ }
+ }
- public void reset() {
- counter=0;
- nextCounter=1;
- }
- }
+ public void reset() {
+ counter = 0;
+ nextCounter = 1;
+ }
+ }
- private final static Logger logger = LogManager.getLogger();
+ private final static Logger logger = LogManager.getLogger();
private final Counter counter = new Counter("iterations ");
@@ -100,63 +100,63 @@ public class VehicleRoutingAlgorithm {
private TerminationManager terminationManager = new TerminationManager();
private VehicleRoutingProblemSolution bestEver = null;
-
- public VehicleRoutingAlgorithm(VehicleRoutingProblem problem, SearchStrategyManager searchStrategyManager) {
- super();
- this.problem = problem;
- this.searchStrategyManager = searchStrategyManager;
- initialSolutions = new ArrayList();
- }
- public VehicleRoutingAlgorithm(VehicleRoutingProblem problem, Collection initialSolutions, SearchStrategyManager searchStrategyManager) {
- super();
- this.problem = problem;
- this.searchStrategyManager = searchStrategyManager;
- this.initialSolutions = initialSolutions;
- }
+ public VehicleRoutingAlgorithm(VehicleRoutingProblem problem, SearchStrategyManager searchStrategyManager) {
+ super();
+ this.problem = problem;
+ this.searchStrategyManager = searchStrategyManager;
+ initialSolutions = new ArrayList();
+ }
- /**
- * Adds solution to the collection of initial solutions.
- *
- * @param solution the solution to be added
- */
- public void addInitialSolution(VehicleRoutingProblemSolution solution){
+ public VehicleRoutingAlgorithm(VehicleRoutingProblem problem, Collection initialSolutions, SearchStrategyManager searchStrategyManager) {
+ super();
+ this.problem = problem;
+ this.searchStrategyManager = searchStrategyManager;
+ this.initialSolutions = initialSolutions;
+ }
+
+ /**
+ * Adds solution to the collection of initial solutions.
+ *
+ * @param solution the solution to be added
+ */
+ public void addInitialSolution(VehicleRoutingProblemSolution solution) {
verify(solution);
initialSolutions.add(solution);
- }
+ }
- private void verify(VehicleRoutingProblemSolution solution) {
+ private void verify(VehicleRoutingProblemSolution solution) {
int nuJobs = 0;
- for(VehicleRoute route : solution.getRoutes()){
+ for (VehicleRoute route : solution.getRoutes()) {
nuJobs += route.getTourActivities().getJobs().size();
- if(route.getVehicle().getIndex() == 0)
+ if (route.getVehicle().getIndex() == 0)
throw new IllegalStateException("vehicle used in initial solution has no index. probably a vehicle is used that has not been added to the " +
- " the VehicleRoutingProblem. only use vehicles that have already been added to the problem.");
- for(TourActivity act : route.getActivities()) {
+ " the VehicleRoutingProblem. only use vehicles that have already been added to the problem.");
+ for (TourActivity act : route.getActivities()) {
if (act.getIndex() == 0) {
throw new IllegalStateException("act in initial solution has no index. activities are created and associated to their job in VehicleRoutingProblem\n." +
- " thus if you build vehicle-routes use the jobActivityFactory from vehicle routing problem like that \n" +
- " VehicleRoute.Builder.newInstance(knownVehicle).setJobActivityFactory(vrp.getJobActivityFactory).addService(..)....build() \n" +
- " then the activities that are created to build the route are identical to the ones used in VehicleRoutingProblem");
+ " thus if you build vehicle-routes use the jobActivityFactory from vehicle routing problem like that \n" +
+ " VehicleRoute.Builder.newInstance(knownVehicle).setJobActivityFactory(vrp.getJobActivityFactory).addService(..)....build() \n" +
+ " then the activities that are created to build the route are identical to the ones used in VehicleRoutingProblem");
}
}
}
- if(nuJobs != problem.getJobs().values().size()){
- logger.warn("number of jobs in initial solution (" + nuJobs + ") is not equal nuJobs in vehicle routing problem (" + problem.getJobs().values().size() + ")" +
- "\n this might yield unintended effects, e.g. initial solution cannot be improved anymore.");
+ if (nuJobs != problem.getJobs().values().size()) {
+ logger.warn("number of jobs in initial solution ({}) is not equal nuJobs in vehicle routing problem ({})" +
+ "\n this might yield unintended effects, e.g. initial solution cannot be improved anymore.", nuJobs, problem.getJobs().values().size());
}
}
/**
- * Sets premature termination and overrides existing termination criteria. If existing ones should not be
+ * Sets premature termination and overrides existing termination criteria. If existing ones should not be
* overridden use .addTerminationCriterion(...).
- *
- * @param prematureAlgorithmTermination the termination criterion
- */
- public void setPrematureAlgorithmTermination(PrematureAlgorithmTermination prematureAlgorithmTermination){
- terminationManager = new TerminationManager();
+ *
+ * @param prematureAlgorithmTermination the termination criterion
+ */
+ public void setPrematureAlgorithmTermination(PrematureAlgorithmTermination prematureAlgorithmTermination) {
+ terminationManager = new TerminationManager();
terminationManager.addTermination(prematureAlgorithmTermination);
- }
+ }
/**
* Adds a termination criterion to the collection of already specified termination criteria. If one
@@ -164,101 +164,137 @@ public class VehicleRoutingAlgorithm {
*
* @param terminationCriterion the termination criterion
*/
- public void addTerminationCriterion(PrematureAlgorithmTermination terminationCriterion){
+ public void addTerminationCriterion(PrematureAlgorithmTermination terminationCriterion) {
terminationManager.addTermination(terminationCriterion);
}
- /**
- * Gets the {@link SearchStrategyManager}.
- *
- * @return SearchStrategyManager
- */
- public SearchStrategyManager getSearchStrategyManager() {
- return searchStrategyManager;
- }
-
- /**
- * Runs the vehicle routing algorithm and returns a number of generated solutions.
- *
- * The algorithm runs as long as it is specified in nuOfIterations and prematureBreak. In each iteration it selects a searchStrategy according
- * to searchStrategyManager and runs the strategy to improve solutions.
- *
Note that clients are allowed to observe/listen the algorithm. See {@link VehicleRoutingAlgorithmListener} and its according listeners.
- *
- * @return Collection the solutions
- * @see {@link SearchStrategyManager}, {@link VehicleRoutingAlgorithmListener}, {@link AlgorithmStartsListener}, {@link AlgorithmEndsListener}, {@link IterationStartsListener}, {@link IterationEndsListener}
- */
- public Collection searchSolutions(){
- logger.info("algorithm starts: " + "[maxIterations=" + maxIterations + "]");
- double now = System.currentTimeMillis();
- int noIterationsThisAlgoIsRunning = maxIterations;
- counter.reset();
- Collection solutions = new ArrayList(initialSolutions);
- algorithmStarts(problem,solutions);
- bestEver = Solutions.bestOf(solutions);
- logger.info("iterations start");
- for(int i=0;i< maxIterations;i++){
- iterationStarts(i+1,problem,solutions);
- logger.debug("start iteration: " + i);
- counter.incCounter();
- SearchStrategy strategy = searchStrategyManager.getRandomStrategy();
- DiscoveredSolution discoveredSolution = strategy.run(problem, solutions);
- logger.trace("discovered solution: " + discoveredSolution);
- memorizeIfBestEver(discoveredSolution);
- selectedStrategy(discoveredSolution,problem,solutions);
- if(terminationManager.isPrematureBreak(discoveredSolution)){
- logger.info("premature algorithm termination at iteration "+ (i+1));
- noIterationsThisAlgoIsRunning = (i+1);
- break;
- }
- iterationEnds(i+1,problem,solutions);
- }
- logger.info("iterations end at " + noIterationsThisAlgoIsRunning + " iterations");
- addBestEver(solutions);
- algorithmEnds(problem, solutions);
- logger.info("took " + ((System.currentTimeMillis()-now)/1000.0) + " seconds");
- return solutions;
- }
-
- private void addBestEver(Collection solutions) {
- if(bestEver != null) solutions.add(bestEver);
+ /**
+ * Gets the {@link SearchStrategyManager}.
+ *
+ * @return SearchStrategyManager
+ */
+ public SearchStrategyManager getSearchStrategyManager() {
+ return searchStrategyManager;
}
+ /**
+ * Runs the vehicle routing algorithm and returns a number of generated solutions.
+ *
+ * The algorithm runs as long as it is specified in nuOfIterations and prematureBreak. In each iteration it selects a searchStrategy according
+ * to searchStrategyManager and runs the strategy to improve solutions.
+ *
Note that clients are allowed to observe/listen the algorithm. See {@link VehicleRoutingAlgorithmListener} and its according listeners.
+ *
+ * @return Collection the solutions
+ * @see {@link SearchStrategyManager}, {@link VehicleRoutingAlgorithmListener}, {@link AlgorithmStartsListener}, {@link AlgorithmEndsListener}, {@link IterationStartsListener}, {@link IterationEndsListener}
+ */
+ public Collection searchSolutions() {
+ logger.info("algorithm starts: [maxIterations={}]", maxIterations);
+ double now = System.currentTimeMillis();
+ int noIterationsThisAlgoIsRunning = maxIterations;
+ counter.reset();
+ Collection solutions = new ArrayList(initialSolutions);
+ algorithmStarts(problem, solutions);
+ bestEver = Solutions.bestOf(solutions);
+ if (logger.isTraceEnabled()) log(solutions);
+ logger.info("iterations start");
+ for (int i = 0; i < maxIterations; i++) {
+ iterationStarts(i + 1, problem, solutions);
+ logger.debug("start iteration: {}", i);
+ counter.incCounter();
+ SearchStrategy strategy = searchStrategyManager.getRandomStrategy();
+ DiscoveredSolution discoveredSolution = strategy.run(problem, solutions);
+ if (logger.isTraceEnabled()) log(discoveredSolution);
+ memorizeIfBestEver(discoveredSolution);
+ selectedStrategy(discoveredSolution, problem, solutions);
+ if (terminationManager.isPrematureBreak(discoveredSolution)) {
+ logger.info("premature algorithm termination at iteration {}", (i + 1));
+ noIterationsThisAlgoIsRunning = (i + 1);
+ break;
+ }
+ iterationEnds(i + 1, problem, solutions);
+ }
+ logger.info("iterations end at {} iterations", noIterationsThisAlgoIsRunning);
+ addBestEver(solutions);
+ algorithmEnds(problem, solutions);
+ logger.info("took {} seconds", ((System.currentTimeMillis() - now) / 1000.0));
+ return solutions;
+ }
+
+ private void addBestEver(Collection solutions) {
+ if (bestEver != null) solutions.add(bestEver);
+ }
+
+ private void log(Collection solutions) {
+ for (VehicleRoutingProblemSolution sol : solutions) log(sol);
+ }
+
+ private void log(VehicleRoutingProblemSolution solution) {
+ logger.trace("solution costs: {}", solution.getCost());
+ for (VehicleRoute r : solution.getRoutes()) {
+ StringBuilder b = new StringBuilder();
+ b.append(r.getVehicle().getId()).append(" : ").append("[ ");
+ for (TourActivity act : r.getActivities()) {
+ if (act instanceof TourActivity.JobActivity) {
+ b.append(((TourActivity.JobActivity) act).getJob().getId()).append(" ");
+ }
+ }
+ b.append("]");
+ logger.trace(b.toString());
+ }
+ StringBuilder b = new StringBuilder();
+ b.append("unassigned : [ ");
+ for (Job j : solution.getUnassignedJobs()) {
+ b.append(j.getId()).append(" ");
+ }
+ b.append("]");
+ logger.trace(b.toString());
+ }
+
+ private void log(DiscoveredSolution discoveredSolution) {
+ logger.trace("discovered solution: {}", discoveredSolution);
+ log(discoveredSolution.getSolution());
+ }
+
+
private void memorizeIfBestEver(DiscoveredSolution discoveredSolution) {
- if(discoveredSolution == null) return;
- if(bestEver == null) bestEver = discoveredSolution.getSolution();
- else if(discoveredSolution.getSolution().getCost() < bestEver.getCost()) bestEver = discoveredSolution.getSolution();
+ if (discoveredSolution == null) return;
+ if (bestEver == null) bestEver = discoveredSolution.getSolution();
+ else if (discoveredSolution.getSolution().getCost() < bestEver.getCost())
+ bestEver = discoveredSolution.getSolution();
}
private void selectedStrategy(DiscoveredSolution discoveredSolution, VehicleRoutingProblem problem, Collection solutions) {
- algoListeners.selectedStrategy(discoveredSolution,problem,solutions);
- }
+ algoListeners.selectedStrategy(discoveredSolution, problem, solutions);
+ }
- private void algorithmEnds(VehicleRoutingProblem problem, Collection solutions) {
- algoListeners.algorithmEnds(problem, solutions);
- }
+ private void algorithmEnds(VehicleRoutingProblem problem, Collection solutions) {
+ algoListeners.algorithmEnds(problem, solutions);
+ }
- public VehicleRoutingAlgorithmListeners getAlgorithmListeners() {
- return algoListeners;
- }
-
- public void addListener(VehicleRoutingAlgorithmListener l){
- algoListeners.addListener(l);
- if(l instanceof SearchStrategyListener) searchStrategyManager.addSearchStrategyListener((SearchStrategyListener) l);
- if(l instanceof SearchStrategyModuleListener) searchStrategyManager.addSearchStrategyModuleListener((SearchStrategyModuleListener) l);
- }
+ public VehicleRoutingAlgorithmListeners getAlgorithmListeners() {
+ return algoListeners;
+ }
- private void iterationEnds(int i, VehicleRoutingProblem problem, Collection solutions) {
- algoListeners.iterationEnds(i,problem, solutions);
- }
+ public void addListener(VehicleRoutingAlgorithmListener l) {
+ algoListeners.addListener(l);
+ if (l instanceof SearchStrategyListener)
+ searchStrategyManager.addSearchStrategyListener((SearchStrategyListener) l);
+ if (l instanceof SearchStrategyModuleListener)
+ searchStrategyManager.addSearchStrategyModuleListener((SearchStrategyModuleListener) l);
+ }
- private void iterationStarts(int i, VehicleRoutingProblem problem, Collection solutions) {
- algoListeners.iterationStarts(i, problem, solutions);
- }
+ private void iterationEnds(int i, VehicleRoutingProblem problem, Collection solutions) {
+ algoListeners.iterationEnds(i, problem, solutions);
+ }
- private void algorithmStarts(VehicleRoutingProblem problem, Collection solutions) {
- algoListeners.algorithmStarts(problem, this, solutions);
- }
+ private void iterationStarts(int i, VehicleRoutingProblem problem, Collection solutions) {
+ algoListeners.iterationStarts(i, problem, solutions);
+ }
+
+ private void algorithmStarts(VehicleRoutingProblem problem, Collection solutions) {
+ algoListeners.algorithmStarts(problem, this, solutions);
+ }
/**
* Sets max number of iterations.
@@ -267,7 +303,7 @@ public class VehicleRoutingAlgorithm {
*/
public void setMaxIterations(int maxIterations) {
this.maxIterations = maxIterations;
- logger.debug("set maxIterations to " + this.maxIterations);
+ logger.debug("set maxIterations to {}", this.maxIterations);
}
/**
diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/VehicleRoutingAlgorithmBuilder.java b/jsprit-core/src/main/java/jsprit/core/algorithm/VehicleRoutingAlgorithmBuilder.java
index 9b60d5ec..75c54357 100644
--- a/jsprit-core/src/main/java/jsprit/core/algorithm/VehicleRoutingAlgorithmBuilder.java
+++ b/jsprit-core/src/main/java/jsprit/core/algorithm/VehicleRoutingAlgorithmBuilder.java
@@ -27,153 +27,151 @@ import jsprit.core.problem.solution.SolutionCostCalculator;
/**
* Builder that builds a {@link VehicleRoutingAlgorithm}.
- *
- * @author schroeder
*
+ * @author schroeder
*/
public class VehicleRoutingAlgorithmBuilder {
- private String algorithmConfigFile;
-
- private AlgorithmConfig algorithmConfig;
-
- private final VehicleRoutingProblem vrp;
+ private String algorithmConfigFile;
- private SolutionCostCalculator solutionCostCalculator;
+ private AlgorithmConfig algorithmConfig;
- private StateManager stateManager;
-
- private boolean addCoreConstraints = false;
-
- private boolean addDefaultCostCalculators = false;
+ private final VehicleRoutingProblem vrp;
- private ConstraintManager constraintManager;
+ private SolutionCostCalculator solutionCostCalculator;
- private int nuOfThreads=0;
-
- /**
- * Constructs the builder with the problem and an algorithmConfigFile. Latter is to configure and specify the ruin-and-recreate meta-heuristic.
- *
- * @param problem to solve
- * @param algorithmConfig config file of VehicleRoutingAlgorithm
- */
- public VehicleRoutingAlgorithmBuilder(VehicleRoutingProblem problem, String algorithmConfig) {
- this.vrp=problem;
- this.algorithmConfigFile=algorithmConfig;
- this.algorithmConfig=null;
- }
-
- /**
- * Constructs the builder with the problem and an algorithmConfig. Latter is to configure and specify the ruin-and-recreate meta-heuristic.
- *
- * @param problem to solve
+ private StateManager stateManager;
+
+ private boolean addCoreConstraints = false;
+
+ private boolean addDefaultCostCalculators = false;
+
+ private ConstraintManager constraintManager;
+
+ private int nuOfThreads = 0;
+
+ /**
+ * Constructs the builder with the problem and an algorithmConfigFile. Latter is to configure and specify the ruin-and-recreate meta-heuristic.
+ *
+ * @param problem to solve
* @param algorithmConfig config file of VehicleRoutingAlgorithm
- */
- public VehicleRoutingAlgorithmBuilder(VehicleRoutingProblem problem, AlgorithmConfig algorithmConfig) {
- this.vrp=problem;
- this.algorithmConfigFile=null;
- this.algorithmConfig=algorithmConfig;
- }
+ */
+ public VehicleRoutingAlgorithmBuilder(VehicleRoutingProblem problem, String algorithmConfig) {
+ this.vrp = problem;
+ this.algorithmConfigFile = algorithmConfig;
+ this.algorithmConfig = null;
+ }
- /**
- * Sets custom objective function.
- *
- * If objective function is not set, a default function is applied (which basically minimizes
- * fixed and variable transportation costs ({@link VariablePlusFixedSolutionCostCalculatorFactory}).
- *
- * @param objectiveFunction to be minimized
- * @see VariablePlusFixedSolutionCostCalculatorFactory
- */
- public void setObjectiveFunction(SolutionCostCalculator objectiveFunction) {
- this.solutionCostCalculator = objectiveFunction;
- }
+ /**
+ * Constructs the builder with the problem and an algorithmConfig. Latter is to configure and specify the ruin-and-recreate meta-heuristic.
+ *
+ * @param problem to solve
+ * @param algorithmConfig config file of VehicleRoutingAlgorithm
+ */
+ public VehicleRoutingAlgorithmBuilder(VehicleRoutingProblem problem, AlgorithmConfig algorithmConfig) {
+ this.vrp = problem;
+ this.algorithmConfigFile = null;
+ this.algorithmConfig = algorithmConfig;
+ }
- /**
- * Sets stateManager to memorize states.
- *
- * @param stateManager that memorizes your states
- * @see StateManager
- */
- public void setStateManager(StateManager stateManager) {
- this.stateManager=stateManager;
- }
+ /**
+ * Sets custom objective function.
+ *
+ * If objective function is not set, a default function is applied (which basically minimizes
+ * fixed and variable transportation costs ({@link VariablePlusFixedSolutionCostCalculatorFactory}).
+ *
+ * @param objectiveFunction to be minimized
+ * @see VariablePlusFixedSolutionCostCalculatorFactory
+ */
+ public void setObjectiveFunction(SolutionCostCalculator objectiveFunction) {
+ this.solutionCostCalculator = objectiveFunction;
+ }
- /**
- * Adds core constraints.
- *
- *
Thus, it adds vehicle-capacity, time-window and skills constraints and their
- * required stateUpdater.
- *
- */
- public void addCoreConstraints() {
- addCoreConstraints=true;
- }
+ /**
+ * Sets stateManager to memorize states.
+ *
+ * @param stateManager that memorizes your states
+ * @see StateManager
+ */
+ public void setStateManager(StateManager stateManager) {
+ this.stateManager = stateManager;
+ }
- /**
- * Adds default cost calculators used by the insertion heuristic,
- * to calculate activity insertion costs.
- * By default, marginal transportation costs are calculated. Thus when inserting
- * act_k between act_i and act_j, marginal (additional) transportation costs
- * are basically c(act_i,act_k)+c(act_k,act_j)-c(act_i,act_j).
- *
- *
Do not use this method, if you plan to control the insertion heuristic
- * entirely via hard- and soft-constraints.
- */
- public void addDefaultCostCalculators() {
- addDefaultCostCalculators=true;
- }
+ /**
+ * Adds core constraints.
+ *
+ * Thus, it adds vehicle-capacity, time-window and skills constraints and their
+ * required stateUpdater.
+ */
+ public void addCoreConstraints() {
+ addCoreConstraints = true;
+ }
- /**
- * Sets state- and constraintManager.
- *
- * @param stateManager that memorizes your states
- * @param constraintManager that manages your constraints
- * @see StateManager
- * @see ConstraintManager
- */
- public void setStateAndConstraintManager(StateManager stateManager, ConstraintManager constraintManager) {
- this.stateManager=stateManager;
- this.constraintManager=constraintManager;
- }
-
- /**
- * Sets nuOfThreads.
- *
- * @param nuOfThreads to be operated
- */
- public void setNuOfThreads(int nuOfThreads){
- this.nuOfThreads=nuOfThreads;
- }
+ /**
+ * Adds default cost calculators used by the insertion heuristic,
+ * to calculate activity insertion costs.
+ * By default, marginal transportation costs are calculated. Thus when inserting
+ * act_k between act_i and act_j, marginal (additional) transportation costs
+ * are basically c(act_i,act_k)+c(act_k,act_j)-c(act_i,act_j).
+ *
+ * Do not use this method, if you plan to control the insertion heuristic
+ * entirely via hard- and soft-constraints.
+ */
+ public void addDefaultCostCalculators() {
+ addDefaultCostCalculators = true;
+ }
- /**
- * Builds and returns the algorithm.
- *
- *
If algorithmConfigFile is set, it reads the configuration.
- *
- * @return the algorithm
- */
- public VehicleRoutingAlgorithm build() {
- if(stateManager == null) stateManager = new StateManager(vrp);
- if(constraintManager == null) constraintManager = new ConstraintManager(vrp,stateManager);
- //add core updater
- stateManager.addStateUpdater(new UpdateEndLocationIfRouteIsOpen());
+ /**
+ * Sets state- and constraintManager.
+ *
+ * @param stateManager that memorizes your states
+ * @param constraintManager that manages your constraints
+ * @see StateManager
+ * @see ConstraintManager
+ */
+ public void setStateAndConstraintManager(StateManager stateManager, ConstraintManager constraintManager) {
+ this.stateManager = stateManager;
+ this.constraintManager = constraintManager;
+ }
+
+ /**
+ * Sets nuOfThreads.
+ *
+ * @param nuOfThreads to be operated
+ */
+ public void setNuOfThreads(int nuOfThreads) {
+ this.nuOfThreads = nuOfThreads;
+ }
+
+ /**
+ * Builds and returns the algorithm.
+ *
+ * If algorithmConfigFile is set, it reads the configuration.
+ *
+ * @return the algorithm
+ */
+ public VehicleRoutingAlgorithm build() {
+ if (stateManager == null) stateManager = new StateManager(vrp);
+ if (constraintManager == null) constraintManager = new ConstraintManager(vrp, stateManager);
+ //add core updater
+ stateManager.addStateUpdater(new UpdateEndLocationIfRouteIsOpen());
// stateManager.addStateUpdater(new OpenRouteStateVerifier());
- if(addCoreConstraints){
- constraintManager.addLoadConstraint();
- constraintManager.addTimeWindowConstraint();
- constraintManager.addSkillsConstraint();
+ if (addCoreConstraints) {
+ constraintManager.addLoadConstraint();
+ constraintManager.addTimeWindowConstraint();
+ constraintManager.addSkillsConstraint();
stateManager.updateLoadStates();
- stateManager.updateTimeWindowStates();
+ stateManager.updateTimeWindowStates();
stateManager.updateSkillStates();
- }
- if(algorithmConfig==null){
- algorithmConfig = new AlgorithmConfig();
- AlgorithmConfigXmlReader xmlReader = new AlgorithmConfigXmlReader(algorithmConfig);
- xmlReader.read(algorithmConfigFile);
- }
- return VehicleRoutingAlgorithms.readAndCreateAlgorithm(vrp, algorithmConfig, nuOfThreads, solutionCostCalculator, stateManager, constraintManager, addDefaultCostCalculators);
- }
+ }
+ if (algorithmConfig == null) {
+ algorithmConfig = new AlgorithmConfig();
+ AlgorithmConfigXmlReader xmlReader = new AlgorithmConfigXmlReader(algorithmConfig);
+ xmlReader.read(algorithmConfigFile);
+ }
+ return VehicleRoutingAlgorithms.readAndCreateAlgorithm(vrp, algorithmConfig, nuOfThreads, solutionCostCalculator, stateManager, constraintManager, addDefaultCostCalculators);
+ }
+
-
}
diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/VehicleRoutingAlgorithmFactory.java b/jsprit-core/src/main/java/jsprit/core/algorithm/VehicleRoutingAlgorithmFactory.java
index 40749bdb..286bf0e2 100644
--- a/jsprit-core/src/main/java/jsprit/core/algorithm/VehicleRoutingAlgorithmFactory.java
+++ b/jsprit-core/src/main/java/jsprit/core/algorithm/VehicleRoutingAlgorithmFactory.java
@@ -1,17 +1,17 @@
/*******************************************************************************
* Copyright (C) 2013 Stefan Schroeder
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
+ * License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
+ *
+ * You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see .
******************************************************************************/
package jsprit.core.algorithm;
@@ -20,7 +20,7 @@ import jsprit.core.problem.VehicleRoutingProblem;
public interface VehicleRoutingAlgorithmFactory {
-
- public VehicleRoutingAlgorithm createAlgorithm(VehicleRoutingProblem vrp);
+
+ public VehicleRoutingAlgorithm createAlgorithm(VehicleRoutingProblem vrp);
}
diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/acceptor/AcceptNewRemoveFirst.java b/jsprit-core/src/main/java/jsprit/core/algorithm/acceptor/AcceptNewRemoveFirst.java
index c14762e3..41421e3a 100644
--- a/jsprit-core/src/main/java/jsprit/core/algorithm/acceptor/AcceptNewRemoveFirst.java
+++ b/jsprit-core/src/main/java/jsprit/core/algorithm/acceptor/AcceptNewRemoveFirst.java
@@ -11,7 +11,7 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
- * You should have received a copy of the GNU Lesser General Public
+ * You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see .
******************************************************************************/
package jsprit.core.algorithm.acceptor;
@@ -24,35 +24,33 @@ import java.util.Collection;
* @deprecated use GreedyAcceptance instead
*/
@Deprecated
-public class AcceptNewRemoveFirst implements SolutionAcceptor{
+public class AcceptNewRemoveFirst implements SolutionAcceptor {
- private final int solutionMemory;
-
- public AcceptNewRemoveFirst(int solutionMemory){
- this.solutionMemory = solutionMemory;
- }
-
- /**
- * Accepts every solution if solution memory allows. If memory occupied, than accepts new solution only if better than the worst in memory.
- * Consequently, the worst solution is removed from solutions, and the new solution added.
- *
- *
Note that this modifies Collection solutions.
- */
- @Override
- public boolean acceptSolution(Collection solutions, VehicleRoutingProblemSolution newSolution) {
- if (solutions.size() >= solutionMemory) {
- solutions.remove(solutions.iterator().next());
- }
- solutions.add(newSolution);
- return true;
- }
-
- @Override
- public String toString() {
- return "[name=acceptNewRemoveFirst]";
- }
-
+ private final int solutionMemory;
+ public AcceptNewRemoveFirst(int solutionMemory) {
+ this.solutionMemory = solutionMemory;
+ }
+
+ /**
+ * Accepts every solution if solution memory allows. If memory occupied, than accepts new solution only if better than the worst in memory.
+ * Consequently, the worst solution is removed from solutions, and the new solution added.
+ *