1
0
Fork 0
mirror of https://github.com/graphhopper/jsprit.git synced 2020-01-24 07:45:05 +01:00

merge master

This commit is contained in:
oblonski 2015-09-23 17:42:42 +02:00
commit a55ea8f3cf
506 changed files with 73608 additions and 73610 deletions

13
.editorconfig Normal file
View file

@ -0,0 +1,13 @@
root = true
[*]
indent_style = space
indent_size = 4
insert_final_newline = true
charset = utf-8
end_of_line = lf
trim_trailing_whitespace = true
max_line_length = 120
[.travis.yml]
indent_size = 2

View file

@ -1,6 +1,18 @@
Change-log Change-log
========== ==========
**v1.6.1** @ 2015-08-10
- feature [#165](https://github.com/jsprit/jsprit/issues/156)
- feature [#169](https://github.com/jsprit/jsprit/issues/159)
- bugfix [#154](https://github.com/jsprit/jsprit/issues/154)
- bugfix [#155](https://github.com/jsprit/jsprit/issues/155)
- bugfix [#158](https://github.com/jsprit/jsprit/issues/158)
- bugfix [#164](https://github.com/jsprit/jsprit/issues/164)
- bugfix [#165](https://github.com/jsprit/jsprit/issues/165)
- [detailed changelog ](https://rawgit.com/jsprit/misc-rep/master/changelog_1.6_to_1.6.1.html)
**v1.6** @ 2015-03-12 **v1.6** @ 2015-03-12
<b>! Break change !</b> <b>! Break change !</b>

View file

@ -1,6 +1,11 @@
WHATS NEW WHATS NEW
========== ==========
------------------------------ ------------------------------
<b>2015-08-10</b> new release **v1.6.1**
Jsprit results are now reproducible since every time the algorithm runs, a unique random number generator (always starting with a
predefined seed) is invoked. If one does not want this behaviour, one can always specify custom random number generators.
<b>2015-03-12</b> new release **v1.6** <b>2015-03-12</b> new release **v1.6**
When reviewing the feedback from our users, we realized that jsprit cannot solve certain kinds of problems adequately. When reviewing the feedback from our users, we realized that jsprit cannot solve certain kinds of problems adequately.

View file

@ -1,8 +1,9 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent> <parent>
<groupId>jsprit</groupId> <groupId>jsprit</groupId>
<artifactId>jsprit</artifactId> <artifactId>jsprit</artifactId>
<version>1.6.1-SNAPSHOT</version> <version>1.6.2-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>jsprit-analysis</artifactId> <artifactId>jsprit-analysis</artifactId>
@ -43,7 +44,7 @@
<dependency> <dependency>
<groupId>org.jfree</groupId> <groupId>org.jfree</groupId>
<artifactId>jfreechart</artifactId> <artifactId>jfreechart</artifactId>
<version>1.0.14</version> <version>1.0.19</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>

View file

@ -92,8 +92,7 @@ public class AlgorithmEventsRecorder implements RuinListener, IterationStartsLis
if (dgsFile.getName().endsWith("gz")) { if (dgsFile.getName().endsWith("gz")) {
gzipOs = new GZIPOutputStream(fos); gzipOs = new GZIPOutputStream(fos);
fileSink.begin(gzipOs); fileSink.begin(gzipOs);
} } else {
else{
fileSink.begin(fos); fileSink.begin(fos);
} }
graph.addSink(fileSink); graph.addSink(fileSink);
@ -151,8 +150,7 @@ public class AlgorithmEventsRecorder implements RuinListener, IterationStartsLis
Job job = ((TourActivity.JobActivity) act).getJob(); Job job = ((TourActivity.JobActivity) act).getJob();
if (job instanceof Service) { if (job instanceof Service) {
nodeId = job.getId(); nodeId = job.getId();
} } else if (job instanceof Shipment) {
else if(job instanceof Shipment){
if (act.getName().equals("pickupShipment")) nodeId = getFromNodeId((Shipment) job); if (act.getName().equals("pickupShipment")) nodeId = getFromNodeId((Shipment) job);
else nodeId = getToNodeId((Shipment) job); else nodeId = getToNodeId((Shipment) job);
} }
@ -192,7 +190,8 @@ public class AlgorithmEventsRecorder implements RuinListener, IterationStartsLis
removeEdge(enteringFromNode.getId()); removeEdge(enteringFromNode.getId());
removeEdge(enteringToNode.getId()); removeEdge(enteringToNode.getId());
if (graph.getNode(toNodeId).getLeavingEdgeSet().isEmpty()) { if (graph.getNode(toNodeId).getLeavingEdgeSet().isEmpty()) {
if(fromRoute.getVehicle().isReturnToDepot()) throw new IllegalStateException("leaving edge is missing"); if (fromRoute.getVehicle().isReturnToDepot())
throw new IllegalStateException("leaving edge is missing");
return; return;
} }
@ -203,8 +202,7 @@ public class AlgorithmEventsRecorder implements RuinListener, IterationStartsLis
if (!fromRoute.getActivities().isEmpty()) { if (!fromRoute.getActivities().isEmpty()) {
addEdge(makeEdgeId(from, to), from.getId(), to.getId()); addEdge(makeEdgeId(from, to), from.getId(), to.getId());
} }
} } else {
else{
removeNodeAndBelongingEdges(fromNodeId, fromRoute); removeNodeAndBelongingEdges(fromNodeId, fromRoute);
removeNodeAndBelongingEdges(toNodeId, fromRoute); removeNodeAndBelongingEdges(toNodeId, fromRoute);
} }
@ -215,7 +213,9 @@ public class AlgorithmEventsRecorder implements RuinListener, IterationStartsLis
if (edges.size() == 1) return edges.iterator().next(); if (edges.size() == 1) return edges.iterator().next();
else { else {
for (Edge e : edges) { for (Edge e : edges) {
if(e.getId().startsWith("shipment")){ continue; } if (e.getId().startsWith("shipment")) {
continue;
}
return e; return e;
} }
} }
@ -227,7 +227,9 @@ public class AlgorithmEventsRecorder implements RuinListener, IterationStartsLis
if (enteringEdges.size() == 1) return enteringEdges.iterator().next(); if (enteringEdges.size() == 1) return enteringEdges.iterator().next();
else { else {
for (Edge e : enteringEdges) { for (Edge e : enteringEdges) {
if(e.getId().startsWith("shipment")){ continue; } if (e.getId().startsWith("shipment")) {
continue;
}
return e; return e;
} }
} }
@ -312,8 +314,7 @@ public class AlgorithmEventsRecorder implements RuinListener, IterationStartsLis
Service service = (Service) job; Service service = (Service) job;
addNode(service.getId(), service.getLocation().getCoordinate()); addNode(service.getId(), service.getLocation().getCoordinate());
markService(service); markService(service);
} } else if (job instanceof Shipment) {
else if(job instanceof Shipment){
Shipment shipment = (Shipment) job; Shipment shipment = (Shipment) job;
String fromNodeId = getFromNodeId(shipment); String fromNodeId = getFromNodeId(shipment);
addNode(fromNodeId, shipment.getPickupLocation().getCoordinate()); addNode(fromNodeId, shipment.getPickupLocation().getCoordinate());
@ -335,8 +336,7 @@ public class AlgorithmEventsRecorder implements RuinListener, IterationStartsLis
private void markService(Service service) { private void markService(Service service) {
if (service instanceof Delivery) { if (service instanceof Delivery) {
markDelivery(service.getId()); markDelivery(service.getId());
} } else {
else {
markPickup(service.getId()); markPickup(service.getId());
} }
} }
@ -438,8 +438,7 @@ public class AlgorithmEventsRecorder implements RuinListener, IterationStartsLis
if (isFirst(insertionIndex)) { if (isFirst(insertionIndex)) {
node_i = makeStartId(data.getSelectedVehicle()); node_i = makeStartId(data.getSelectedVehicle());
} } else {
else {
TourActivity.JobActivity jobActivity = (TourActivity.JobActivity) route.getActivities().get(insertionIndex - 1); TourActivity.JobActivity jobActivity = (TourActivity.JobActivity) route.getActivities().get(insertionIndex - 1);
node_i = getNodeId(jobActivity); node_i = getNodeId(jobActivity);
} }
@ -447,8 +446,7 @@ public class AlgorithmEventsRecorder implements RuinListener, IterationStartsLis
String node_j; String node_j;
if (isLast(insertionIndex, route)) { if (isLast(insertionIndex, route)) {
node_j = makeEndId(data.getSelectedVehicle()); node_j = makeEndId(data.getSelectedVehicle());
} } else {
else {
TourActivity.JobActivity jobActivity = (TourActivity.JobActivity) route.getActivities().get(insertionIndex); TourActivity.JobActivity jobActivity = (TourActivity.JobActivity) route.getActivities().get(insertionIndex);
node_j = getNodeId(jobActivity); node_j = getNodeId(jobActivity);
} }
@ -495,8 +493,7 @@ public class AlgorithmEventsRecorder implements RuinListener, IterationStartsLis
private void markInserted(Job job) { private void markInserted(Job job) {
if (job instanceof Service) { if (job instanceof Service) {
markService((Service) job); markService((Service) job);
} } else {
else{
markShipment((Shipment) job); markShipment((Shipment) job);
} }
} }

View file

@ -136,11 +136,9 @@ public class AlgorithmEventsViewer {
} }
if (step == AlgorithmEventsRecorder.RUIN) { if (step == AlgorithmEventsRecorder.RUIN) {
delayContainer.delay = ruinDelay; delayContainer.delay = ruinDelay;
} } else if (step == AlgorithmEventsRecorder.CLEAR_SOLUTION) {
else if(step == AlgorithmEventsRecorder.CLEAR_SOLUTION){
delayContainer.delay = delay; delayContainer.delay = delay;
} } else if (step == AlgorithmEventsRecorder.BEFORE_RUIN_RENDER_SOLUTION) {
else if(step == AlgorithmEventsRecorder.BEFORE_RUIN_RENDER_SOLUTION){
delayContainer.delay = delay; delayContainer.delay = delay;
} }
} }

View file

@ -30,11 +30,10 @@ import java.util.Collection;
/** /**
* VehicleRoutingAlgorithm-Listener to record the solution-search-progress. * VehicleRoutingAlgorithm-Listener to record the solution-search-progress.
* * <p/>
* <p>Register this listener in VehicleRoutingAlgorithm. * <p>Register this listener in VehicleRoutingAlgorithm.
* *
* @author stefan schroeder * @author stefan schroeder
*
*/ */
public class AlgorithmSearchProgressChartListener implements IterationEndsListener, AlgorithmEndsListener, AlgorithmStartsListener { public class AlgorithmSearchProgressChartListener implements IterationEndsListener, AlgorithmEndsListener, AlgorithmStartsListener {

View file

@ -39,12 +39,11 @@ public class ComputationalLaboratory {
/** /**
* Listener-interface to listen to calculation. * Listener-interface to listen to calculation.
* * <p/>
* <p>Note that calculations are run concurrently, i.e. a unique task that is distributed to an available thread is * <p>Note that calculations are run concurrently, i.e. a unique task that is distributed to an available thread is
* {algorithm, instance, run}. * {algorithm, instance, run}.
* *
* @author schroeder * @author schroeder
*
*/ */
public static interface CalculationListener extends LabListener { public static interface CalculationListener extends LabListener {
@ -65,7 +64,6 @@ public class ComputationalLaboratory {
* Collects whatever indicators you require by algorithmName, instanceName, run and indicator. * Collects whatever indicators you require by algorithmName, instanceName, run and indicator.
* *
* @author schroeder * @author schroeder
*
*/ */
public static class DataCollector { public static class DataCollector {
@ -82,6 +80,7 @@ public class ComputationalLaboratory {
this.run = run; this.run = run;
this.indicatorName = indicatorName; this.indicatorName = indicatorName;
} }
@Override @Override
public int hashCode() { public int hashCode() {
final int prime = 31; final int prime = 31;
@ -100,6 +99,7 @@ public class ComputationalLaboratory {
result = prime * result + run; result = prime * result + run;
return result; return result;
} }
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (this == obj) if (this == obj)
@ -128,15 +128,19 @@ public class ComputationalLaboratory {
return false; return false;
return true; return true;
} }
public String getInstanceName() { public String getInstanceName() {
return instanceName; return instanceName;
} }
public String getAlgorithmName() { public String getAlgorithmName() {
return algorithmName; return algorithmName;
} }
public int getRun() { public int getRun() {
return run; return run;
} }
public String getIndicatorName() { public String getIndicatorName() {
return indicatorName; return indicatorName;
} }
@ -153,6 +157,7 @@ public class ComputationalLaboratory {
private ConcurrentHashMap<Key, Double> data = new ConcurrentHashMap<ComputationalLaboratory.DataCollector.Key, Double>(); private ConcurrentHashMap<Key, Double> data = new ConcurrentHashMap<ComputationalLaboratory.DataCollector.Key, Double>();
private ConcurrentHashMap<Key, VehicleRoutingProblemSolution> solutions = new ConcurrentHashMap<ComputationalLaboratory.DataCollector.Key, VehicleRoutingProblemSolution>(); private ConcurrentHashMap<Key, VehicleRoutingProblemSolution> solutions = new ConcurrentHashMap<ComputationalLaboratory.DataCollector.Key, VehicleRoutingProblemSolution>();
/** /**
* Adds a single date by instanceName, algorithmName, run and indicatorName. * Adds a single date by instanceName, algorithmName, run and indicatorName.
* <p>If there is already an entry for this instance, algorithm, run and indicatorName, it is overwritten. * <p>If there is already an entry for this instance, algorithm, run and indicatorName, it is overwritten.
@ -164,7 +169,8 @@ public class ComputationalLaboratory {
* @param value * @param value
*/ */
public void addDate(String instanceName, String algorithmName, int run, String indicatorName, double 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."); 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); Key key = new Key(instanceName, algorithmName, run, indicatorName);
data.put(key, value); data.put(key, value);
} }
@ -285,7 +291,8 @@ public class ComputationalLaboratory {
* @throws IllegalStateException if there is already an algorithmFactory with the same name * @throws IllegalStateException if there is already an algorithmFactory with the same name
*/ */
public void addAlgorithmFactory(String name, VehicleRoutingAlgorithmFactory factory) { 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."); 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)); algorithms.add(new Algorithm(name, factory));
algorithmNames.add(name); algorithmNames.add(name);
} }
@ -306,7 +313,8 @@ public class ComputationalLaboratory {
* @throws IllegalStateException if there is already an instance with the same name. * @throws IllegalStateException if there is already an instance with the same name.
*/ */
public void addInstance(String name, VehicleRoutingProblem problem) { 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."); 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)); benchmarkInstances.add(new BenchmarkInstance(name, problem, null, null));
instanceNames.add(name); instanceNames.add(name);
} }
@ -318,7 +326,8 @@ public class ComputationalLaboratory {
* @throws IllegalStateException if there is already an instance with the same name. * @throws IllegalStateException if there is already an instance with the same name.
*/ */
public void addInstance(BenchmarkInstance instance) { 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."); 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); benchmarkInstances.add(instance);
instanceNames.add(instance.name); instanceNames.add(instance.name);
} }
@ -372,7 +381,7 @@ public class ComputationalLaboratory {
/** /**
* Runs experiments. * Runs experiments.
* * <p/>
* <p>If nuThreads > 1 it runs them concurrently, i.e. individual runs are distributed to available threads. Therefore * <p>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. * a unique task is defined by its algorithmName, instanceName and its runNumber.
* <p>If you have one algorithm called "myAlgorithm" and one instance called "myInstance", and you need to run "myAlgorithm" on "myInstance" three times * <p>If you have one algorithm called "myAlgorithm" and one instance called "myInstance", and you need to run "myAlgorithm" on "myInstance" three times
@ -380,8 +389,8 @@ public class ComputationalLaboratory {
* <p>You can register whatever analysisTool you require by implementing and registering CalculationListener. Then your tool is informed just * <p>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. * 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 * @throws IllegalStateException if either no algorithm or no instance has been specified
* @see CalculationListener
*/ */
public void run() { public void run() {
if (algorithms.isEmpty()) { if (algorithms.isEmpty()) {

View file

@ -41,7 +41,6 @@ public class ConcurrentBenchmarker {
} }
private String algorithmConfig = null; private String algorithmConfig = null;
private List<BenchmarkInstance> benchmarkInstances = new ArrayList<BenchmarkInstance>(); private List<BenchmarkInstance> benchmarkInstances = new ArrayList<BenchmarkInstance>();
@ -63,7 +62,9 @@ public class ConcurrentBenchmarker {
private VehicleRoutingAlgorithmFactory algorithmFactory; private VehicleRoutingAlgorithmFactory algorithmFactory;
public void setCost(Cost cost){ this.cost = cost; } public void setCost(Cost cost) {
this.cost = cost;
}
public ConcurrentBenchmarker(String algorithmConfig) { public ConcurrentBenchmarker(String algorithmConfig) {
super(); super();
@ -165,8 +166,7 @@ public class ConcurrentBenchmarker {
private VehicleRoutingAlgorithm createAlgorithm(BenchmarkInstance p) { private VehicleRoutingAlgorithm createAlgorithm(BenchmarkInstance p) {
if (algorithmConfig != null) { if (algorithmConfig != null) {
return VehicleRoutingAlgorithms.readAndCreateAlgorithm(p.vrp, algorithmConfig); return VehicleRoutingAlgorithms.readAndCreateAlgorithm(p.vrp, algorithmConfig);
} } else {
else{
return algorithmFactory.createAlgorithm(p.vrp); return algorithmFactory.createAlgorithm(p.vrp);
} }

View file

@ -113,7 +113,6 @@ public class GraphStreamViewer {
"}"; "}";
@SuppressWarnings("UnusedDeclaration") @SuppressWarnings("UnusedDeclaration")
public static String SIMPLE_WHITE = public static String SIMPLE_WHITE =
"node {" + "node {" +
@ -308,7 +307,7 @@ public class GraphStreamViewer {
/** /**
* Sets the camera-view. Center describes the center-focus of the camera and zoomFactor its * Sets the camera-view. Center describes the center-focus of the camera and zoomFactor its
* zoomFactor. * zoomFactor.
* * <p/>
* <p>a zoomFactor < 1 zooms in and > 1 out. * <p>a zoomFactor < 1 zooms in and > 1 out.
* *
* @param centerX x coordinate of center * @param centerX x coordinate of center
@ -392,8 +391,7 @@ public class GraphStreamViewer {
for (Job j : vrp.getJobs().values()) { for (Job j : vrp.getJobs().values()) {
if (j instanceof Service) { if (j instanceof Service) {
renderService(g, (Service) j, label); renderService(g, (Service) j, label);
} } else if (j instanceof Shipment) {
else if(j instanceof Shipment){
renderShipment(g, (Shipment) j, label, renderShipments); renderShipment(g, (Shipment) j, label, renderShipments);
} }
sleep(renderDelay_in_ms); sleep(renderDelay_in_ms);
@ -583,22 +581,20 @@ public class GraphStreamViewer {
if (label.equals(Label.ACTIVITY)) { if (label.equals(Label.ACTIVITY)) {
Node actNode = g.getNode(currIdentifier); Node actNode = g.getNode(currIdentifier);
actNode.addAttribute("ui.label", act.getName()); actNode.addAttribute("ui.label", act.getName());
} } else if (label.equals(Label.JOB_NAME)) {
else if(label.equals(Label.JOB_NAME)){
Node actNode = g.getNode(currIdentifier); Node actNode = g.getNode(currIdentifier);
actNode.addAttribute("ui.label", job.getName()); 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); Node actNode = g.getNode(currIdentifier);
actNode.addAttribute("ui.label", Time.parseSecondsToTime(act.getArrTime())); 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); Node actNode = g.getNode(currIdentifier);
actNode.addAttribute("ui.label", Time.parseSecondsToTime(act.getEndTime())); actNode.addAttribute("ui.label", Time.parseSecondsToTime(act.getEndTime()));
} }
g.addEdge(makeEdgeId(routeId, vehicle_edgeId), prevIdentifier, currIdentifier, true); g.addEdge(makeEdgeId(routeId, vehicle_edgeId), prevIdentifier, currIdentifier, true);
if (act instanceof PickupActivity) g.getNode(currIdentifier).addAttribute("ui.class", "pickupInRoute"); if (act instanceof PickupActivity) g.getNode(currIdentifier).addAttribute("ui.class", "pickupInRoute");
else if (act instanceof DeliveryActivity) g.getNode(currIdentifier).addAttribute("ui.class", "deliveryInRoute"); else if (act instanceof DeliveryActivity)
g.getNode(currIdentifier).addAttribute("ui.class", "deliveryInRoute");
prevIdentifier = currIdentifier; prevIdentifier = currIdentifier;
vehicle_edgeId++; vehicle_edgeId++;
sleep(renderDelay_in_ms); sleep(renderDelay_in_ms);

View file

@ -53,7 +53,6 @@ import java.util.*;
* <p>Note that every item to be rendered need to have coordinates. * <p>Note that every item to be rendered need to have coordinates.
* *
* @author schroeder * @author schroeder
*
*/ */
public class Plotter { public class Plotter {
@ -124,6 +123,7 @@ public class Plotter {
double minY; double minY;
double maxX; double maxX;
double maxY; double maxY;
public BoundingBox(double minX, double minY, double maxX, double maxY) { public BoundingBox(double minX, double minY, double maxX, double maxY) {
super(); super();
this.minX = minX; this.minX = minX;
@ -143,8 +143,8 @@ public class Plotter {
/** /**
* Label to label ID (=jobId), SIZE (=jobSize=jobCapacityDimensions) * Label to label ID (=jobId), SIZE (=jobSize=jobCapacityDimensions)
* @author schroeder
* *
* @author schroeder
*/ */
public static enum Label { public static enum Label {
ID, SIZE, @SuppressWarnings("UnusedDeclaration")NO_LABEL ID, SIZE, @SuppressWarnings("UnusedDeclaration")NO_LABEL
@ -224,6 +224,7 @@ public class Plotter {
/** /**
* Sets a label. * Sets a label.
*
* @param label of jobs * @param label of jobs
* @return plotter * @return plotter
*/ */
@ -274,11 +275,9 @@ public class Plotter {
if (!pngFileName.endsWith(".png")) filename += ".png"; if (!pngFileName.endsWith(".png")) filename += ".png";
if (plotSolutionAsWell) { if (plotSolutionAsWell) {
plot(vrp, routes, filename, plotTitle); plot(vrp, routes, filename, plotTitle);
} } else if (!(vrp.getInitialVehicleRoutes().isEmpty())) {
else if(!(vrp.getInitialVehicleRoutes().isEmpty())){
plot(vrp, vrp.getInitialVehicleRoutes(), filename, plotTitle); plot(vrp, vrp.getInitialVehicleRoutes(), filename, plotTitle);
} } else {
else{
plot(vrp, null, filename, plotTitle); plot(vrp, null, filename, plotTitle);
} }
} }
@ -428,8 +427,7 @@ public class Plotter {
if (boundingBox == null) { if (boundingBox == null) {
xAxis.setRangeWithMargins(getDomainRange(problem)); xAxis.setRangeWithMargins(getDomainRange(problem));
yAxis.setRangeWithMargins(getRange(problem)); yAxis.setRangeWithMargins(getRange(problem));
} } else {
else{
xAxis.setRangeWithMargins(new Range(boundingBox.minX, boundingBox.maxX)); xAxis.setRangeWithMargins(new Range(boundingBox.minX, boundingBox.maxX));
yAxis.setRangeWithMargins(new Range(boundingBox.minY, boundingBox.maxY)); yAxis.setRangeWithMargins(new Range(boundingBox.minY, boundingBox.maxY));
} }
@ -500,8 +498,7 @@ public class Plotter {
if (first) { if (first) {
first = false; first = false;
shipmentSeries = new XYSeries(ship, false, true); shipmentSeries = new XYSeries(ship, false, true);
} } else {
else{
shipmentSeries = new XYSeries(sCounter, false, true); shipmentSeries = new XYSeries(sCounter, false, true);
sCounter++; sCounter++;
} }
@ -530,8 +527,7 @@ public class Plotter {
addLabel(s, dataItem2); addLabel(s, dataItem2);
markItem(dataItem2, Activity.DELIVERY); markItem(dataItem2, Activity.DELIVERY);
containsDeliveryAct = true; containsDeliveryAct = true;
} } else if (job instanceof Pickup) {
else if(job instanceof Pickup){
Pickup service = (Pickup) job; Pickup service = (Pickup) job;
Coordinate coord = getCoordinate(service.getLocation().getCoordinate()); Coordinate coord = getCoordinate(service.getLocation().getCoordinate());
XYDataItem dataItem = new XYDataItem(coord.getX() * scalingFactor, coord.getY() * scalingFactor); XYDataItem dataItem = new XYDataItem(coord.getX() * scalingFactor, coord.getY() * scalingFactor);
@ -539,8 +535,7 @@ public class Plotter {
addLabel(service, dataItem); addLabel(service, dataItem);
markItem(dataItem, Activity.PICKUP); markItem(dataItem, Activity.PICKUP);
containsPickupAct = true; containsPickupAct = true;
} } else if (job instanceof Delivery) {
else if(job instanceof Delivery){
Delivery service = (Delivery) job; Delivery service = (Delivery) job;
Coordinate coord = getCoordinate(service.getLocation().getCoordinate()); Coordinate coord = getCoordinate(service.getLocation().getCoordinate());
XYDataItem dataItem = new XYDataItem(coord.getX() * scalingFactor, coord.getY() * scalingFactor); XYDataItem dataItem = new XYDataItem(coord.getX() * scalingFactor, coord.getY() * scalingFactor);
@ -548,8 +543,7 @@ public class Plotter {
addLabel(service, dataItem); addLabel(service, dataItem);
markItem(dataItem, Activity.DELIVERY); markItem(dataItem, Activity.DELIVERY);
containsDeliveryAct = true; containsDeliveryAct = true;
} } else if (job instanceof Service) {
else if(job instanceof Service){
Service service = (Service) job; Service service = (Service) job;
Coordinate coord = getCoordinate(service.getLocation().getCoordinate()); Coordinate coord = getCoordinate(service.getLocation().getCoordinate());
XYDataItem dataItem = new XYDataItem(coord.getX() * scalingFactor, coord.getY() * scalingFactor); XYDataItem dataItem = new XYDataItem(coord.getX() * scalingFactor, coord.getY() * scalingFactor);
@ -557,8 +551,7 @@ public class Plotter {
addLabel(service, dataItem); addLabel(service, dataItem);
markItem(dataItem, Activity.SERVICE); markItem(dataItem, Activity.SERVICE);
containsServiceAct = true; containsServiceAct = true;
} } else {
else{
throw new IllegalStateException("job instanceof " + job.getClass().toString() + ". this is not supported."); throw new IllegalStateException("job instanceof " + job.getClass().toString() + ". this is not supported.");
} }
} }
@ -566,8 +559,7 @@ public class Plotter {
private void addLabel(Job job, XYDataItem dataItem) { private void addLabel(Job job, XYDataItem dataItem) {
if (this.label.equals(Label.SIZE)) { if (this.label.equals(Label.SIZE)) {
labelsByDataItem.put(dataItem, getSizeString(job)); labelsByDataItem.put(dataItem, getSizeString(job));
} } else if (this.label.equals(Label.ID)) {
else if(this.label.equals(Label.ID)){
labelsByDataItem.put(dataItem, String.valueOf(job.getId())); labelsByDataItem.put(dataItem, String.valueOf(job.getId()));
} }
} }
@ -580,8 +572,7 @@ public class Plotter {
if (firstDim) { if (firstDim) {
builder.append(String.valueOf(job.getSize().get(i))); builder.append(String.valueOf(job.getSize().get(i)));
firstDim = false; firstDim = false;
} } else {
else {
builder.append(","); builder.append(",");
builder.append(String.valueOf(job.getSize().get(i))); builder.append(String.valueOf(job.getSize().get(i)));
} }

View file

@ -32,9 +32,7 @@ import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
/** /**
*
* @author schroeder * @author schroeder
*
*/ */
public class XYLineChartBuilder { public class XYLineChartBuilder {
@ -58,7 +56,6 @@ public class XYLineChartBuilder {
* @param chartTitle appears on top of the XYLineChart * @param chartTitle appears on top of the XYLineChart
* @param xDomainName appears below the xAxis * @param xDomainName appears below the xAxis
* @param yDomainName appears beside the yAxis * @param yDomainName appears beside the yAxis
*
* @return the builder * @return the builder
*/ */
public static XYLineChartBuilder newInstance(String chartTitle, String xDomainName, String yDomainName) { public static XYLineChartBuilder newInstance(String chartTitle, String xDomainName, String yDomainName) {
@ -95,6 +92,7 @@ public class XYLineChartBuilder {
/** /**
* Builds and returns JFreeChart. * Builds and returns JFreeChart.
*
* @return * @return
*/ */
public JFreeChart build() { public JFreeChart build() {

View file

@ -16,10 +16,10 @@
******************************************************************************/ ******************************************************************************/
package jsprit.analysis.util; package jsprit.analysis.util;
import java.util.Collection;
import jsprit.core.util.BenchmarkResult; import jsprit.core.util.BenchmarkResult;
import java.util.Collection;
public interface BenchmarkWriter { public interface BenchmarkWriter {
public void write(Collection<BenchmarkResult> results); public void write(Collection<BenchmarkResult> results);
} }

View file

@ -16,14 +16,14 @@
******************************************************************************/ ******************************************************************************/
package jsprit.analysis.util; package jsprit.analysis.util;
import jsprit.core.util.BenchmarkResult;
import java.io.BufferedWriter; import java.io.BufferedWriter;
import java.io.File; import java.io.File;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.util.Collection; 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;
@ -169,15 +169,13 @@ public class HtmlBenchmarkTableWriter implements BenchmarkWriter{
if (sum_res_star != null) { if (sum_res_star != null) {
writer.write(date(Double.valueOf(round(sum_res_star.doubleValue() / (double) results.size(), 2)).toString()) + newline()); 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; delta_res = (sum_avg_result / sum_res_star - 1) * 100;
} } else writer.write(date("null") + newline());
else writer.write(date("null") + newline());
//bestKnownVeh //bestKnownVeh
Double delta_veh = null; Double delta_veh = null;
if (sum_veh_star != null) { if (sum_veh_star != null) {
writer.write(date(Double.valueOf(round(sum_veh_star.doubleValue() / (double) results.size(), 2)).toString()) + newline()); 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(); delta_veh = (sum_avg_veh - sum_veh_star) / (double) results.size();
} } else writer.write(date("null") + newline());
else writer.write(date("null") + newline());
writer.write(closeRow() + newline()); writer.write(closeRow() + newline());
writer.write(closeTable() + newline()); writer.write(closeTable() + newline());
@ -255,5 +253,4 @@ public class HtmlBenchmarkTableWriter implements BenchmarkWriter{
} }
} }

View file

@ -1,4 +1,3 @@
<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~ Copyright (C) 2014 Stefan Schroeder ~ Copyright (C) 2014 Stefan Schroeder
~ ~
@ -16,11 +15,12 @@
~ License along with this library. If not, see <http://www.gnu.org/licenses />. ~ License along with this library. If not, see <http://www.gnu.org/licenses />.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~--> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent> <parent>
<groupId>jsprit</groupId> <groupId>jsprit</groupId>
<artifactId>jsprit</artifactId> <artifactId>jsprit</artifactId>
<version>1.6.1-SNAPSHOT</version> <version>1.6.2-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>jsprit-core</artifactId> <artifactId>jsprit-core</artifactId>
@ -55,8 +55,37 @@
</plugin> </plugin>
</plugins> </plugins>
</pluginManagement> </pluginManagement>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
<configuration>
<excludedGroups>jsprit.core.IntegrationTest</excludedGroups>
</configuration>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.18.1</version>
<configuration>
<includes>
<include>**/*.java</include>
</includes>
<groups>jsprit.core.IntegrationTest</groups>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build> </build>
<dependencies> <dependencies>
<dependency> <dependency>
@ -77,8 +106,8 @@
<dependency> <dependency>
<groupId>xerces</groupId> <groupId>xerces</groupId>
<artifactId>xerces</artifactId> <artifactId>xercesImpl</artifactId>
<version>2.4.0</version> <version>2.11.0</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>

View file

@ -25,6 +25,7 @@ import jsprit.core.algorithm.recreate.VehicleSwitched;
import jsprit.core.algorithm.state.*; import jsprit.core.algorithm.state.*;
import jsprit.core.problem.VehicleRoutingProblem; import jsprit.core.problem.VehicleRoutingProblem;
import jsprit.core.problem.constraint.ConstraintManager; import jsprit.core.problem.constraint.ConstraintManager;
import jsprit.core.problem.constraint.SwitchNotFeasible;
import jsprit.core.problem.solution.SolutionCostCalculator; import jsprit.core.problem.solution.SolutionCostCalculator;
import jsprit.core.problem.solution.VehicleRoutingProblemSolution; import jsprit.core.problem.solution.VehicleRoutingProblemSolution;
import jsprit.core.problem.solution.route.VehicleRoute; import jsprit.core.problem.solution.route.VehicleRoute;
@ -89,10 +90,11 @@ public class PrettyAlgorithmBuilder {
constraintManager.addTimeWindowConstraint(); constraintManager.addTimeWindowConstraint();
constraintManager.addLoadConstraint(); constraintManager.addLoadConstraint();
constraintManager.addSkillsConstraint(); constraintManager.addSkillsConstraint();
constraintManager.addConstraint(new SwitchNotFeasible(stateManager));
stateManager.updateLoadStates(); stateManager.updateLoadStates();
stateManager.updateTimeWindowStates(); stateManager.updateTimeWindowStates();
UpdateVehicleDependentPracticalTimeWindows tw_updater = new UpdateVehicleDependentPracticalTimeWindows(stateManager, vrp.getTransportCosts()); UpdateVehicleDependentPracticalTimeWindows twUpdater = new UpdateVehicleDependentPracticalTimeWindows(stateManager, vrp.getTransportCosts());
tw_updater.setVehiclesToUpdate(new UpdateVehicleDependentPracticalTimeWindows.VehiclesToUpdate() { twUpdater.setVehiclesToUpdate(new UpdateVehicleDependentPracticalTimeWindows.VehiclesToUpdate() {
Map<VehicleTypeKey, Vehicle> uniqueTypes = new HashMap<VehicleTypeKey, Vehicle>(); Map<VehicleTypeKey, Vehicle> uniqueTypes = new HashMap<VehicleTypeKey, Vehicle>();
@ -109,12 +111,14 @@ public class PrettyAlgorithmBuilder {
vehicles.addAll(uniqueTypes.values()); vehicles.addAll(uniqueTypes.values());
return vehicles; return vehicles;
} }
}); });
stateManager.addStateUpdater(tw_updater); stateManager.addStateUpdater(twUpdater);
stateManager.updateSkillStates(); stateManager.updateSkillStates();
stateManager.addStateUpdater(new UpdateEndLocationIfRouteIsOpen()); stateManager.addStateUpdater(new UpdateEndLocationIfRouteIsOpen());
stateManager.addStateUpdater(new UpdateActivityTimes(vrp.getTransportCosts(), ActivityTimeTracker.ActivityPolicy.AS_SOON_AS_TIME_WINDOW_OPENS)); 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 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); vra.addListener(stateManager);
@ -136,8 +140,10 @@ public class PrettyAlgorithmBuilder {
vra.addListener(new AlgorithmStartsListener() { vra.addListener(new AlgorithmStartsListener() {
@Override @Override
public void informAlgorithmStarts(VehicleRoutingProblem problem, VehicleRoutingAlgorithm algorithm, Collection<VehicleRoutingProblemSolution> solutions) { public void informAlgorithmStarts(VehicleRoutingProblem problem, VehicleRoutingAlgorithm algorithm, Collection<VehicleRoutingProblemSolution> solutions) {
if (solutions.isEmpty()) {
solutions.add(new InsertionInitialSolutionFactory(iniInsertionStrategy, iniObjFunction).createSolution(vrp)); solutions.add(new InsertionInitialSolutionFactory(iniInsertionStrategy, iniObjFunction).createSolution(vrp));
} }
}
}); });
} }
addArbitraryListener(vra); addArbitraryListener(vra);

View file

@ -60,7 +60,9 @@ public class SearchStrategy {
return strategyId; return strategyId;
} }
public String getStrategyId() { return strategyId; } public String getStrategyId() {
return strategyId;
}
@Override @Override
public String toString() { public String toString() {
@ -88,7 +90,7 @@ public class SearchStrategy {
this.solutionAcceptor = solutionAcceptor; this.solutionAcceptor = solutionAcceptor;
this.solutionCostCalculator = solutionCostCalculator; this.solutionCostCalculator = solutionCostCalculator;
this.id = id; this.id = id;
logger.debug("initialise " + this); logger.debug("initialise {}", this);
} }
public String getId() { public String getId() {
@ -124,7 +126,7 @@ public class SearchStrategy {
/** /**
* Runs the search-strategy and its according modules, and returns DiscoveredSolution. * Runs the search-strategy and its according modules, and returns DiscoveredSolution.
* * <p/>
* <p>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 * <p>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}. * ({@link jsprit.core.algorithm.SearchStrategyModule}) on the selectedSolution and 3) accepting the new solution according to {@link jsprit.core.algorithm.acceptor.SolutionAcceptor}.
* <p> Note that after 1) the selected solution is copied, thus the original solution is not modified. * <p> Note that after 1) the selected solution is copied, thus the original solution is not modified.
@ -159,7 +161,7 @@ public class SearchStrategy {
public void addModule(SearchStrategyModule module) { public void addModule(SearchStrategyModule module) {
if (module == null) throw new IllegalStateException("module to be added is null."); if (module == null) throw new IllegalStateException("module to be added is null.");
searchStrategyModules.add(module); searchStrategyModules.add(module);
logger.debug("module added [module=" + module + "][#modules=" + searchStrategyModules.size() + "]"); logger.debug("module added [module={}][#modules={}]", module, searchStrategyModules.size());
} }
public void addModuleListener(SearchStrategyModuleListener moduleListener) { public void addModuleListener(SearchStrategyModuleListener moduleListener) {

View file

@ -55,6 +55,7 @@ public class SearchStrategyManager {
* Returns the probabilities. * Returns the probabilities.
* [schroeder (2014.11.21): Now they are actually no propabilities anymore but weights. The resulting 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] * are calculated here with the sum of weights]
*
* @return list of probabilities * @return list of probabilities
*/ */
@Deprecated @Deprecated
@ -62,7 +63,9 @@ public class SearchStrategyManager {
return Collections.unmodifiableList(weights); return Collections.unmodifiableList(weights);
} }
public List<Double> getWeights(){ return Collections.unmodifiableList(weights); } public List<Double> getWeights() {
return Collections.unmodifiableList(weights);
}
public double getWeight(String strategyId) { public double getWeight(String strategyId) {
return weights.get(id2index.get(strategyId)); return weights.get(id2index.get(strategyId));
@ -70,6 +73,7 @@ public class SearchStrategyManager {
/** /**
* adds a new search strategy with a certain weight. * adds a new search strategy with a certain weight.
*
* @param strategy strategy to be added * @param strategy strategy to be added
* @param weight of corresponding strategy to be added * @param weight of corresponding strategy to be added
* @throws java.lang.IllegalStateException if strategy is null OR weight < 0 * @throws java.lang.IllegalStateException if strategy is null OR weight < 0
@ -112,7 +116,8 @@ public class SearchStrategyManager {
* @throws java.lang.IllegalStateException if randomNumberGenerator is null OR no search strategy can be found * @throws java.lang.IllegalStateException if randomNumberGenerator is null OR no search strategy can be found
*/ */
public SearchStrategy getRandomStrategy() { public SearchStrategy getRandomStrategy() {
if(random == null) throw new IllegalStateException("randomizer is null. make sure you set random object correctly"); if (random == null)
throw new IllegalStateException("randomizer is null. make sure you set random object correctly");
double randomFig = random.nextDouble(); double randomFig = random.nextDouble();
double sumProbabilities = 0.0; double sumProbabilities = 0.0;
for (int i = 0; i < weights.size(); i++) { for (int i = 0; i < weights.size(); i++) {

View file

@ -31,7 +31,6 @@ import jsprit.core.problem.vehicle.Vehicle;
* this objective function. * this objective function.
* *
* @author schroeder * @author schroeder
*
*/ */
public class VariablePlusFixedSolutionCostCalculatorFactory { public class VariablePlusFixedSolutionCostCalculatorFactory {

View file

@ -36,7 +36,6 @@ import java.util.Collection;
* Algorithm that solves a {@link VehicleRoutingProblem}. * Algorithm that solves a {@link VehicleRoutingProblem}.
* *
* @author stefan schroeder * @author stefan schroeder
*
*/ */
public class VehicleRoutingAlgorithm { public class VehicleRoutingAlgorithm {
@ -143,8 +142,8 @@ public class VehicleRoutingAlgorithm {
} }
} }
if (nuJobs != problem.getJobs().values().size()) { 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() + ")" + 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."); "\n this might yield unintended effects, e.g. initial solution cannot be improved anymore.", nuJobs, problem.getJobs().values().size());
} }
} }
@ -180,7 +179,7 @@ public class VehicleRoutingAlgorithm {
/** /**
* Runs the vehicle routing algorithm and returns a number of generated solutions. * Runs the vehicle routing algorithm and returns a number of generated solutions.
* * <p/>
* <p>The algorithm runs as long as it is specified in nuOfIterations and prematureBreak. In each iteration it selects a searchStrategy according * <p>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. * to searchStrategyManager and runs the strategy to improve solutions.
* <p>Note that clients are allowed to observe/listen the algorithm. See {@link VehicleRoutingAlgorithmListener} and its according listeners. * <p>Note that clients are allowed to observe/listen the algorithm. See {@link VehicleRoutingAlgorithmListener} and its according listeners.
@ -189,7 +188,7 @@ public class VehicleRoutingAlgorithm {
* @see {@link SearchStrategyManager}, {@link VehicleRoutingAlgorithmListener}, {@link AlgorithmStartsListener}, {@link AlgorithmEndsListener}, {@link IterationStartsListener}, {@link IterationEndsListener} * @see {@link SearchStrategyManager}, {@link VehicleRoutingAlgorithmListener}, {@link AlgorithmStartsListener}, {@link AlgorithmEndsListener}, {@link IterationStartsListener}, {@link IterationEndsListener}
*/ */
public Collection<VehicleRoutingProblemSolution> searchSolutions() { public Collection<VehicleRoutingProblemSolution> searchSolutions() {
logger.info("algorithm starts: " + "[maxIterations=" + maxIterations + "]"); logger.info("algorithm starts: [maxIterations={}]", maxIterations);
double now = System.currentTimeMillis(); double now = System.currentTimeMillis();
int noIterationsThisAlgoIsRunning = maxIterations; int noIterationsThisAlgoIsRunning = maxIterations;
counter.reset(); counter.reset();
@ -200,7 +199,7 @@ public class VehicleRoutingAlgorithm {
logger.info("iterations start"); logger.info("iterations start");
for (int i = 0; i < maxIterations; i++) { for (int i = 0; i < maxIterations; i++) {
iterationStarts(i + 1, problem, solutions); iterationStarts(i + 1, problem, solutions);
logger.debug("start iteration: " + i); logger.debug("start iteration: {}", i);
counter.incCounter(); counter.incCounter();
SearchStrategy strategy = searchStrategyManager.getRandomStrategy(); SearchStrategy strategy = searchStrategyManager.getRandomStrategy();
DiscoveredSolution discoveredSolution = strategy.run(problem, solutions); DiscoveredSolution discoveredSolution = strategy.run(problem, solutions);
@ -208,25 +207,29 @@ public class VehicleRoutingAlgorithm {
memorizeIfBestEver(discoveredSolution); memorizeIfBestEver(discoveredSolution);
selectedStrategy(discoveredSolution, problem, solutions); selectedStrategy(discoveredSolution, problem, solutions);
if (terminationManager.isPrematureBreak(discoveredSolution)) { if (terminationManager.isPrematureBreak(discoveredSolution)) {
logger.info("premature algorithm termination at iteration "+ (i+1)); logger.info("premature algorithm termination at iteration {}", (i + 1));
noIterationsThisAlgoIsRunning = (i + 1); noIterationsThisAlgoIsRunning = (i + 1);
break; break;
} }
iterationEnds(i + 1, problem, solutions); iterationEnds(i + 1, problem, solutions);
} }
logger.info("iterations end at " + noIterationsThisAlgoIsRunning + " iterations"); logger.info("iterations end at {} iterations", noIterationsThisAlgoIsRunning);
addBestEver(solutions); addBestEver(solutions);
algorithmEnds(problem, solutions); algorithmEnds(problem, solutions);
logger.info("took " + ((System.currentTimeMillis()-now)/1000.0) + " seconds"); logger.info("took {} seconds", ((System.currentTimeMillis() - now) / 1000.0));
return solutions; return solutions;
} }
private void addBestEver(Collection<VehicleRoutingProblemSolution> solutions) {
if (bestEver != null) solutions.add(bestEver);
}
private void log(Collection<VehicleRoutingProblemSolution> solutions) { private void log(Collection<VehicleRoutingProblemSolution> solutions) {
for (VehicleRoutingProblemSolution sol : solutions) log(sol); for (VehicleRoutingProblemSolution sol : solutions) log(sol);
} }
private void log(VehicleRoutingProblemSolution solution) { private void log(VehicleRoutingProblemSolution solution) {
logger.trace("solution costs: " + solution.getCost()); logger.trace("solution costs: {}", solution.getCost());
for (VehicleRoute r : solution.getRoutes()) { for (VehicleRoute r : solution.getRoutes()) {
StringBuilder b = new StringBuilder(); StringBuilder b = new StringBuilder();
b.append(r.getVehicle().getId()).append(" : ").append("[ "); b.append(r.getVehicle().getId()).append(" : ").append("[ ");
@ -248,18 +251,16 @@ public class VehicleRoutingAlgorithm {
} }
private void log(DiscoveredSolution discoveredSolution) { private void log(DiscoveredSolution discoveredSolution) {
logger.trace("discovered solution: " + discoveredSolution); logger.trace("discovered solution: {}", discoveredSolution);
log(discoveredSolution.getSolution()); log(discoveredSolution.getSolution());
} }
private void addBestEver(Collection<VehicleRoutingProblemSolution> solutions) {
if(bestEver != null) solutions.add(bestEver);
}
private void memorizeIfBestEver(DiscoveredSolution discoveredSolution) { private void memorizeIfBestEver(DiscoveredSolution discoveredSolution) {
if (discoveredSolution == null) return; if (discoveredSolution == null) return;
if (bestEver == null) bestEver = discoveredSolution.getSolution(); if (bestEver == null) bestEver = discoveredSolution.getSolution();
else if(discoveredSolution.getSolution().getCost() < bestEver.getCost()) bestEver = discoveredSolution.getSolution(); else if (discoveredSolution.getSolution().getCost() < bestEver.getCost())
bestEver = discoveredSolution.getSolution();
} }
@ -277,8 +278,10 @@ public class VehicleRoutingAlgorithm {
public void addListener(VehicleRoutingAlgorithmListener l) { public void addListener(VehicleRoutingAlgorithmListener l) {
algoListeners.addListener(l); algoListeners.addListener(l);
if(l instanceof SearchStrategyListener) searchStrategyManager.addSearchStrategyListener((SearchStrategyListener) l); if (l instanceof SearchStrategyListener)
if(l instanceof SearchStrategyModuleListener) searchStrategyManager.addSearchStrategyModuleListener((SearchStrategyModuleListener) l); searchStrategyManager.addSearchStrategyListener((SearchStrategyListener) l);
if (l instanceof SearchStrategyModuleListener)
searchStrategyManager.addSearchStrategyModuleListener((SearchStrategyModuleListener) l);
} }
private void iterationEnds(int i, VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions) { private void iterationEnds(int i, VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions) {
@ -300,7 +303,7 @@ public class VehicleRoutingAlgorithm {
*/ */
public void setMaxIterations(int maxIterations) { public void setMaxIterations(int maxIterations) {
this.maxIterations = maxIterations; this.maxIterations = maxIterations;
logger.debug("set maxIterations to " + this.maxIterations); logger.debug("set maxIterations to {}", this.maxIterations);
} }
/** /**

View file

@ -29,7 +29,6 @@ import jsprit.core.problem.solution.SolutionCostCalculator;
* Builder that builds a {@link VehicleRoutingAlgorithm}. * Builder that builds a {@link VehicleRoutingAlgorithm}.
* *
* @author schroeder * @author schroeder
*
*/ */
public class VehicleRoutingAlgorithmBuilder { public class VehicleRoutingAlgorithmBuilder {
@ -77,7 +76,7 @@ public class VehicleRoutingAlgorithmBuilder {
/** /**
* Sets custom objective function. * Sets custom objective function.
* * <p/>
* <p>If objective function is not set, a default function is applied (which basically minimizes * <p>If objective function is not set, a default function is applied (which basically minimizes
* fixed and variable transportation costs ({@link VariablePlusFixedSolutionCostCalculatorFactory}). * fixed and variable transportation costs ({@link VariablePlusFixedSolutionCostCalculatorFactory}).
* *
@ -100,10 +99,9 @@ public class VehicleRoutingAlgorithmBuilder {
/** /**
* Adds core constraints. * Adds core constraints.
* * <p/>
* <p>Thus, it adds vehicle-capacity, time-window and skills constraints and their * <p>Thus, it adds vehicle-capacity, time-window and skills constraints and their
* required stateUpdater. * required stateUpdater.
*
*/ */
public void addCoreConstraints() { public void addCoreConstraints() {
addCoreConstraints = true; addCoreConstraints = true;
@ -115,7 +113,7 @@ public class VehicleRoutingAlgorithmBuilder {
* By default, marginal transportation costs are calculated. Thus when inserting * By default, marginal transportation costs are calculated. Thus when inserting
* act_k between act_i and act_j, marginal (additional) transportation costs * 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). * are basically c(act_i,act_k)+c(act_k,act_j)-c(act_i,act_j).
* * <p/>
* <p>Do not use this method, if you plan to control the insertion heuristic * <p>Do not use this method, if you plan to control the insertion heuristic
* entirely via hard- and soft-constraints. * entirely via hard- and soft-constraints.
*/ */
@ -147,7 +145,7 @@ public class VehicleRoutingAlgorithmBuilder {
/** /**
* Builds and returns the algorithm. * Builds and returns the algorithm.
* * <p/>
* <p>If algorithmConfigFile is set, it reads the configuration. * <p>If algorithmConfigFile is set, it reads the configuration.
* *
* @return the algorithm * @return the algorithm

View file

@ -35,7 +35,7 @@ public class AcceptNewRemoveFirst implements SolutionAcceptor{
/** /**
* Accepts every solution if solution memory allows. If memory occupied, than accepts new solution only if better than the worst in memory. * 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. * Consequently, the worst solution is removed from solutions, and the new solution added.
* * <p/>
* <p>Note that this modifies Collection<VehicleRoutingProblemSolution> solutions. * <p>Note that this modifies Collection<VehicleRoutingProblemSolution> solutions.
*/ */
@Override @Override
@ -53,6 +53,4 @@ public class AcceptNewRemoveFirst implements SolutionAcceptor{
} }
} }

View file

@ -57,11 +57,10 @@ public class ExperimentalSchrimpfAcceptance implements SolutionAcceptor, Iterati
this.alpha = alpha; this.alpha = alpha;
this.nOfRandomWalks = nOfWarmupIterations; this.nOfRandomWalks = nOfWarmupIterations;
this.solutionMemory = solutionMemory; this.solutionMemory = solutionMemory;
logger.info("initialise " + this); logger.info("initialise {}", this);
} }
@Override @Override
public boolean acceptSolution(Collection<VehicleRoutingProblemSolution> solutions, VehicleRoutingProblemSolution newSolution) { public boolean acceptSolution(Collection<VehicleRoutingProblemSolution> solutions, VehicleRoutingProblemSolution newSolution) {
boolean solutionAccepted = false; boolean solutionAccepted = false;
@ -79,8 +78,7 @@ public class ExperimentalSchrimpfAcceptance implements SolutionAcceptor, Iterati
solutions.remove(worst); solutions.remove(worst);
solutions.add(newSolution); solutions.add(newSolution);
solutionAccepted = true; solutionAccepted = true;
} } else if (newSolution.getRoutes().size() == worst.getRoutes().size() && newSolution.getCost() < worst.getCost() + threshold) {
else if(newSolution.getRoutes().size() == worst.getRoutes().size() && newSolution.getCost() < worst.getCost() + threshold){
solutions.remove(worst); solutions.remove(worst);
solutions.add(newSolution); solutions.add(newSolution);
solutionAccepted = true; solutionAccepted = true;
@ -96,7 +94,7 @@ public class ExperimentalSchrimpfAcceptance implements SolutionAcceptor, Iterati
private double getThreshold(int iteration) { private double getThreshold(int iteration) {
double scheduleVariable = (double) iteration / (double) nOfTotalIterations; double scheduleVariable = (double) iteration / (double) nOfTotalIterations;
// logger.debug("iter="+iteration+" totalIter="+nOfTotalIterations+" scheduling="+scheduleVariable); // logger.debug("iter={} totalIter={} scheduling={}", iteration, nOfTotalIterations, scheduleVariable);
double currentThreshold = initialThreshold * Math.exp(-Math.log(2) * scheduleVariable / alpha); double currentThreshold = initialThreshold * Math.exp(-Math.log(2) * scheduleVariable / alpha);
return currentThreshold; return currentThreshold;
} }
@ -126,7 +124,7 @@ public class ExperimentalSchrimpfAcceptance implements SolutionAcceptor, Iterati
@Override @Override
public void informIterationEnds(int iteration, VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions) { public void informIterationEnds(int iteration, VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions) {
double result = Solutions.bestOf(solutions).getCost(); double result = Solutions.bestOf(solutions).getCost();
// logger.info("result="+result); // logger.info("result={}", result);
results[iteration - 1] = result; results[iteration - 1] = result;
} }
@ -138,8 +136,8 @@ public class ExperimentalSchrimpfAcceptance implements SolutionAcceptor, Iterati
initialThreshold = standardDeviation / 2; initialThreshold = standardDeviation / 2;
logger.info("warmup done"); logger.info("warmup done");
logger.info("total time: " + ((System.currentTimeMillis()-now)/1000.0) + "s"); logger.info("total time: {}s", ((System.currentTimeMillis() - now) / 1000.0));
logger.info("initial threshold: " + initialThreshold); logger.info("initial threshold: {}", initialThreshold);
logger.info("---------------------------------------------------------------------"); logger.info("---------------------------------------------------------------------");
} }

View file

@ -23,7 +23,7 @@ import java.util.Collection;
/** /**
* Acceptor that accepts solutions to be memorized only better solutions. * Acceptor that accepts solutions to be memorized only better solutions.
* * <p/>
* <p>If there is enough memory, every solution will be accepted. If there is no memory anymore and the solution * <p>If there is enough memory, every solution will be accepted. If there is no memory anymore and the solution
* to be evaluated is better than the worst, the worst will be replaced by the new solution.</p> * to be evaluated is better than the worst, the worst will be replaced by the new solution.</p>
*/ */
@ -38,7 +38,7 @@ public class GreedyAcceptance implements SolutionAcceptor{
/** /**
* Accepts every solution if solution memory allows. If memory occupied, than accepts new solution only if better than the worst in memory. * 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. * Consequently, the worst solution is removed from solutions, and the new solution added.
* * <p/>
* <p>Note that this modifies Collection<VehicleRoutingProblemSolution> solutions. * <p>Note that this modifies Collection<VehicleRoutingProblemSolution> solutions.
*/ */
@Override @Override
@ -68,6 +68,4 @@ public class GreedyAcceptance implements SolutionAcceptor{
} }
} }

View file

@ -33,7 +33,7 @@ public class GreedyAcceptance_minVehFirst implements SolutionAcceptor{
/** /**
* Accepts every solution if solution memory allows. If memory occupied, than accepts new solution only if better than the worst in memory. * 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. * Consequently, the worst solution is removed from solutions, and the new solution added.
* * <p/>
* <p>Note that this modifies Collection<VehicleRoutingProblemSolution> solutions. * <p>Note that this modifies Collection<VehicleRoutingProblemSolution> solutions.
*/ */
@Override @Override
@ -52,8 +52,7 @@ public class GreedyAcceptance_minVehFirst implements SolutionAcceptor{
solutions.remove(worstSolution); solutions.remove(worstSolution);
solutions.add(newSolution); solutions.add(newSolution);
solutionAccepted = true; solutionAccepted = true;
} } else if (newSolution.getRoutes().size() == worstSolution.getRoutes().size() && newSolution.getCost() < worstSolution.getCost()) {
else if(newSolution.getRoutes().size() == worstSolution.getRoutes().size() && newSolution.getCost() < worstSolution.getCost()){
solutions.remove(worstSolution); solutions.remove(worstSolution);
solutions.add(newSolution); solutions.add(newSolution);
solutionAccepted = true; solutionAccepted = true;
@ -68,6 +67,4 @@ public class GreedyAcceptance_minVehFirst implements SolutionAcceptor{
} }
} }

View file

@ -29,21 +29,21 @@ import java.util.Collection;
/** /**
* ThresholdAcceptance-Function defined by Schrimpf et al. (2000). * ThresholdAcceptance-Function defined by Schrimpf et al. (2000).
* * <p/>
* <p>The <b>idea</b> can be described as follows: Most problems do not only have one unique minimum (maximum) but * <p>The <b>idea</b> can be described as follows: Most problems do not only have one unique minimum (maximum) but
* a number of local minima (maxima). To avoid to get stuck in a local minimum at the beginning of a search * a number of local minima (maxima). To avoid to get stuck in a local minimum at the beginning of a search
* this threshold-acceptance function accepts also worse solution at the beginning (in contrary to a greedy * this threshold-acceptance function accepts also worse solution at the beginning (in contrary to a greedy
* approach which only accepts better solutions), and converges to a greedy approach at the end. <br> * approach which only accepts better solutions), and converges to a greedy approach at the end. <br>
* The difficulty is to define (i) an appropriate initial threshold and (ii) a corresponding function describing * The difficulty is to define (i) an appropriate initial threshold and (ii) a corresponding function describing
* how the threshold converges to zero, i.e. the greedy threshold. * how the threshold converges to zero, i.e. the greedy threshold.
* * <p/>
* <p>ad i) The initial threshold is determined by a random walk through the search space. * <p>ad i) The initial threshold is determined by a random walk through the search space.
* The random walk currently runs with the following algorithm: src/main/resources/randomWalk.xml. It runs * The random walk currently runs with the following algorithm: src/main/resources/randomWalk.xml. It runs
* as long as it is specified in nuOfWarmupIterations. In the first iteration or walk respectively the algorithm generates a solution. * as long as it is specified in nuOfWarmupIterations. In the first iteration or walk respectively the algorithm generates a solution.
* This solution in turn is the basis of the next walk yielding to another solution value ... and so on. * This solution in turn is the basis of the next walk yielding to another solution value ... and so on.
* Each solution value is memorized since the initial threshold is essentially a function of the standard deviation of these solution values. * Each solution value is memorized since the initial threshold is essentially a function of the standard deviation of these solution values.
* To be more precise: initial threshold = stddev(solution values) / 2. * To be more precise: initial threshold = stddev(solution values) / 2.
* * <p/>
* <p>ad ii) The threshold of iteration i is determined as follows: * <p>ad ii) The threshold of iteration i is determined as follows:
* threshold(i) = initialThreshold * Math.exp(-Math.log(2) * (i / nuOfTotalIterations) / alpha) * threshold(i) = initialThreshold * Math.exp(-Math.log(2) * (i / nuOfTotalIterations) / alpha)
* To get a better understanding of the threshold-function go to Wolfram Alpha and plot the following line * To get a better understanding of the threshold-function go to Wolfram Alpha and plot the following line
@ -55,15 +55,13 @@ import java.util.Collection;
* alpha = 0.1<br> * alpha = 0.1<br>
* x corresponds to i iterations and<br> * x corresponds to i iterations and<br>
* y to the threshold(i) * y to the threshold(i)
* * <p/>
* <p>Gerhard Schrimpf, Johannes Schneider, Hermann Stamm- Wilbrandt, and Gunter Dueck (2000). * <p>Gerhard Schrimpf, Johannes Schneider, Hermann Stamm- Wilbrandt, and Gunter Dueck (2000).
* Record breaking optimization results using the ruin and recreate principle. * Record breaking optimization results using the ruin and recreate principle.
* Journal of Computational Physics, 159(2):139 171, 2000. ISSN 0021-9991. doi: 10.1006/jcph.1999. 6413. * Journal of Computational Physics, 159(2):139 171, 2000. ISSN 0021-9991. doi: 10.1006/jcph.1999. 6413.
* URL http://www.sciencedirect.com/science/article/ pii/S0021999199964136 * URL http://www.sciencedirect.com/science/article/ pii/S0021999199964136
* *
*
* @author schroeder * @author schroeder
*
*/ */
public class SchrimpfAcceptance implements SolutionAcceptor, IterationStartsListener, AlgorithmStartsListener { public class SchrimpfAcceptance implements SolutionAcceptor, IterationStartsListener, AlgorithmStartsListener {
@ -83,7 +81,7 @@ public class SchrimpfAcceptance implements SolutionAcceptor, IterationStartsList
public SchrimpfAcceptance(int solutionMemory, double alpha) { public SchrimpfAcceptance(int solutionMemory, double alpha) {
this.alpha = alpha; this.alpha = alpha;
this.solutionMemory = solutionMemory; this.solutionMemory = solutionMemory;
logger.debug("initialise " + this); logger.debug("initialise {}", this);
} }
@Override @Override
@ -102,8 +100,7 @@ public class SchrimpfAcceptance implements SolutionAcceptor, IterationStartsList
if (worst == null) { if (worst == null) {
solutions.add(newSolution); solutions.add(newSolution);
solutionAccepted = true; solutionAccepted = true;
} } else if (newSolution.getCost() < worst.getCost() + threshold) {
else if(newSolution.getCost() < worst.getCost() + threshold){
solutions.remove(worst); solutions.remove(worst);
solutions.add(newSolution); solutions.add(newSolution);
solutionAccepted = true; solutionAccepted = true;

View file

@ -67,7 +67,7 @@ public class SchrimpfInitialThresholdGenerator implements AlgorithmStartsListene
@Override @Override
public void informIterationEnds(int iteration, VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions) { public void informIterationEnds(int iteration, VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions) {
double result = Solutions.bestOf(solutions).getCost(); double result = Solutions.bestOf(solutions).getCost();
// logger.info("result="+result); // logger.info("result={}", result);
results[iteration - 1] = result; results[iteration - 1] = result;
} }
@ -80,8 +80,8 @@ public class SchrimpfInitialThresholdGenerator implements AlgorithmStartsListene
schrimpfAcceptance.setInitialThreshold(initialThreshold); schrimpfAcceptance.setInitialThreshold(initialThreshold);
logger.info("took " + ((System.currentTimeMillis()-now)/1000.0) + " seconds"); logger.info("took {} seconds", ((System.currentTimeMillis() - now) / 1000.0));
logger.debug("initial threshold: " + initialThreshold); logger.debug("initial threshold: {}", initialThreshold);
logger.info("---------------------------------------------------------------------"); logger.info("---------------------------------------------------------------------");
} }

View file

@ -1,4 +1,3 @@
/******************************************************************************* /*******************************************************************************
* Copyright (C) 2014 Stefan Schroeder * Copyright (C) 2014 Stefan Schroeder
* *
@ -26,15 +25,13 @@ import java.util.Collection;
/** /**
* Acceptor that decides whether the newSolution is accepted or not. * Acceptor that decides whether the newSolution is accepted or not.
* *
*
* @author stefan * @author stefan
*
*/ */
public interface SolutionAcceptor { public interface SolutionAcceptor {
/** /**
* Accepts solution or not, and returns true if a new solution has been accepted. * Accepts solution or not, and returns true if a new solution has been accepted.
* * <p/>
* <p>If the solution is accepted, it is added to solutions, i.e. the solutions-collections is modified. * <p>If the solution is accepted, it is added to solutions, i.e. the solutions-collections is modified.
* *
* @param solutions collection of existing solutions * @param solutions collection of existing solutions

View file

@ -26,25 +26,23 @@ import jsprit.core.util.Resource;
import java.net.URL; import java.net.URL;
/** /**
* Factory that creates the {@link VehicleRoutingAlgorithm} as proposed by Schrimpf et al., 2000 with the following parameters: * Factory that creates the {@link VehicleRoutingAlgorithm} as proposed by Schrimpf et al., 2000 with the following parameters:
* * <p/>
* <p> * <p/>
* R&R_random (prob=0.5, F=0.5); * R&R_random (prob=0.5, F=0.5);
* R&R_radial (prob=0.5, F=0.3); * R&R_radial (prob=0.5, F=0.3);
* threshold-accepting with exponentialDecayFunction (alpha=0.1, warmup-iterations=100); * threshold-accepting with exponentialDecayFunction (alpha=0.1, warmup-iterations=100);
* nuOfIterations=2000 * nuOfIterations=2000
* * <p/>
* <p>Gerhard Schrimpf, Johannes Schneider, Hermann Stamm- Wilbrandt, and Gunter Dueck. * <p>Gerhard Schrimpf, Johannes Schneider, Hermann Stamm- Wilbrandt, and Gunter Dueck.
* Record breaking optimization results using the ruin and recreate principle. * Record breaking optimization results using the ruin and recreate principle.
* Journal of Computational Physics, 159(2):139 171, 2000. ISSN 0021-9991. doi: 10.1006/jcph.1999. 6413. * Journal of Computational Physics, 159(2):139 171, 2000. ISSN 0021-9991. doi: 10.1006/jcph.1999. 6413.
* URL http://www.sciencedirect.com/science/article/ pii/S0021999199964136 * URL http://www.sciencedirect.com/science/article/ pii/S0021999199964136
* * <p/>
* <p>algorithm-xml-config is available at src/main/resources/schrimpf.xml. * <p>algorithm-xml-config is available at src/main/resources/schrimpf.xml.
* *
* @author stefan schroeder * @author stefan schroeder
*
*/ */
public class GreedySchrimpfFactory { public class GreedySchrimpfFactory {
@ -62,5 +60,4 @@ public class GreedySchrimpfFactory {
} }
} }

View file

@ -62,8 +62,7 @@ class InsertionNoiseMaker implements SoftActivityConstraint, IterationStartsList
List<Location> locs = new ArrayList<Location>(); List<Location> locs = new ArrayList<Location>();
if (j instanceof Service) { if (j instanceof Service) {
locs.add(((Service) j).getLocation()); locs.add(((Service) j).getLocation());
} } else if (j instanceof Shipment) {
else if(j instanceof Shipment){
locs.add(((Shipment) j).getPickupLocation()); locs.add(((Shipment) j).getPickupLocation());
locs.add(((Shipment) j).getDeliveryLocation()); locs.add(((Shipment) j).getDeliveryLocation());
} }
@ -74,8 +73,7 @@ class InsertionNoiseMaker implements SoftActivityConstraint, IterationStartsList
public void informIterationStarts(int i, VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions) { public void informIterationStarts(int i, VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions) {
if (random.nextDouble() < noiseProbability) { if (random.nextDouble() < noiseProbability) {
makeNoise = true; makeNoise = true;
} } else makeNoise = false;
else makeNoise = false;
} }
@Override @Override

View file

@ -245,13 +245,15 @@ public class Jsprit {
} }
public RuinShareFactoryImpl(int minShare, int maxShare) { public RuinShareFactoryImpl(int minShare, int maxShare) {
if(maxShare < minShare) throw new IllegalArgumentException("maxShare must be equal or greater than minShare"); if (maxShare < minShare)
throw new IllegalArgumentException("maxShare must be equal or greater than minShare");
this.minShare = minShare; this.minShare = minShare;
this.maxShare = maxShare; this.maxShare = maxShare;
} }
public RuinShareFactoryImpl(int minShare, int maxShare, Random random) { public RuinShareFactoryImpl(int minShare, int maxShare, Random random) {
if(maxShare < minShare) throw new IllegalArgumentException("maxShare must be equal or greater than minShare"); if (maxShare < minShare)
throw new IllegalArgumentException("maxShare must be equal or greater than minShare");
this.minShare = minShare; this.minShare = minShare;
this.maxShare = maxShare; this.maxShare = maxShare;
this.random = random; this.random = random;
@ -297,8 +299,7 @@ public class Jsprit {
VehicleFleetManager fm; VehicleFleetManager fm;
if (vrp.getFleetSize().equals(VehicleRoutingProblem.FleetSize.INFINITE)) { if (vrp.getFleetSize().equals(VehicleRoutingProblem.FleetSize.INFINITE)) {
fm = new InfiniteFleetManagerFactory(vrp.getVehicles()).createFleetManager(); fm = new InfiniteFleetManagerFactory(vrp.getVehicles()).createFleetManager();
} } else fm = new FiniteFleetManagerFactory(vrp.getVehicles()).createFleetManager();
else fm = new FiniteFleetManagerFactory(vrp.getVehicles()).createFleetManager();
if (stateManager == null) { if (stateManager == null) {
stateManager = new StateManager(vrp); stateManager = new StateManager(vrp);
@ -356,8 +357,7 @@ public class Jsprit {
if (random.nextDouble() < toDouble(getProperty(Parameter.RUIN_WORST_NOISE_PROB.toString()))) { if (random.nextDouble() < toDouble(getProperty(Parameter.RUIN_WORST_NOISE_PROB.toString()))) {
return toDouble(getProperty(Parameter.RUIN_WORST_NOISE_LEVEL.toString())) return toDouble(getProperty(Parameter.RUIN_WORST_NOISE_LEVEL.toString()))
* noiseMaker.maxCosts * random.nextDouble(); * noiseMaker.maxCosts * random.nextDouble();
} } else return 0.;
else return 0.;
} }
}); });
} }
@ -392,8 +392,7 @@ public class Jsprit {
scorer = getRegretScorer(vrp); scorer = getRegretScorer(vrp);
regretInsertion.setScoringFunction(scorer); regretInsertion.setScoringFunction(scorer);
regret = regretInsertion; regret = regretInsertion;
} } else {
else {
RegretInsertion regretInsertion = (RegretInsertion) new InsertionBuilder(vrp, fm, stateManager, constraintManager) RegretInsertion regretInsertion = (RegretInsertion) new InsertionBuilder(vrp, fm, stateManager, constraintManager)
.setInsertionStrategy(InsertionBuilder.Strategy.REGRET) .setInsertionStrategy(InsertionBuilder.Strategy.REGRET)
.setAllowVehicleSwitch(toBoolean(getProperty(Parameter.VEHICLE_SWITCH.toString()))) .setAllowVehicleSwitch(toBoolean(getProperty(Parameter.VEHICLE_SWITCH.toString())))
@ -413,8 +412,7 @@ public class Jsprit {
.setAllowVehicleSwitch(toBoolean(getProperty(Parameter.VEHICLE_SWITCH.toString()))) .setAllowVehicleSwitch(toBoolean(getProperty(Parameter.VEHICLE_SWITCH.toString())))
.build(); .build();
best = bestInsertion; best = bestInsertion;
} } else {
else{
BestInsertionConcurrent bestInsertion = (BestInsertionConcurrent) new InsertionBuilder(vrp, fm, stateManager, constraintManager) BestInsertionConcurrent bestInsertion = (BestInsertionConcurrent) new InsertionBuilder(vrp, fm, stateManager, constraintManager)
.setInsertionStrategy(InsertionBuilder.Strategy.BEST) .setInsertionStrategy(InsertionBuilder.Strategy.BEST)
.considerFixedCosts(Double.valueOf(properties.getProperty(Parameter.FIXED_COST_PARAM.toString()))) .considerFixedCosts(Double.valueOf(properties.getProperty(Parameter.FIXED_COST_PARAM.toString())))
@ -477,8 +475,7 @@ public class Jsprit {
.withStrategy(clusters_best, toDouble(getProperty(Strategy.CLUSTER_BEST.toString()))); .withStrategy(clusters_best, toDouble(getProperty(Strategy.CLUSTER_BEST.toString())));
if (getProperty(Parameter.CONSTRUCTION.toString()).equals(Construction.BEST_INSERTION.toString())) { if (getProperty(Parameter.CONSTRUCTION.toString()).equals(Construction.BEST_INSERTION.toString())) {
prettyBuilder.constructInitialSolutionWith(best, objectiveFunction); prettyBuilder.constructInitialSolutionWith(best, objectiveFunction);
} } else {
else{
prettyBuilder.constructInitialSolutionWith(regret, objectiveFunction); prettyBuilder.constructInitialSolutionWith(regret, objectiveFunction);
} }

View file

@ -26,25 +26,23 @@ import jsprit.core.util.Resource;
import java.net.URL; import java.net.URL;
/** /**
* Factory that creates the {@link VehicleRoutingAlgorithm} as proposed by Schrimpf et al., 2000 with the following parameters: * Factory that creates the {@link VehicleRoutingAlgorithm} as proposed by Schrimpf et al., 2000 with the following parameters:
* * <p/>
* <p> * <p/>
* R&R_random (prob=0.5, F=0.5); * R&R_random (prob=0.5, F=0.5);
* R&R_radial (prob=0.5, F=0.3); * R&R_radial (prob=0.5, F=0.3);
* threshold-accepting with exponentialDecayFunction (alpha=0.1, warmup-iterations=100); * threshold-accepting with exponentialDecayFunction (alpha=0.1, warmup-iterations=100);
* nuOfIterations=2000 * nuOfIterations=2000
* * <p/>
* <p>Gerhard Schrimpf, Johannes Schneider, Hermann Stamm- Wilbrandt, and Gunter Dueck. * <p>Gerhard Schrimpf, Johannes Schneider, Hermann Stamm- Wilbrandt, and Gunter Dueck.
* Record breaking optimization results using the ruin and recreate principle. * Record breaking optimization results using the ruin and recreate principle.
* Journal of Computational Physics, 159(2):139 171, 2000. ISSN 0021-9991. doi: 10.1006/jcph.1999. 6413. * Journal of Computational Physics, 159(2):139 171, 2000. ISSN 0021-9991. doi: 10.1006/jcph.1999. 6413.
* URL http://www.sciencedirect.com/science/article/ pii/S0021999199964136 * URL http://www.sciencedirect.com/science/article/ pii/S0021999199964136
* * <p/>
* <p>algorithm-xml-config is available at src/main/resources/schrimpf.xml. * <p>algorithm-xml-config is available at src/main/resources/schrimpf.xml.
* *
* @author stefan schroeder * @author stefan schroeder
*
*/ */
public class SchrimpfFactory { public class SchrimpfFactory {
@ -62,5 +60,4 @@ public class SchrimpfFactory {
} }
} }

View file

@ -70,8 +70,7 @@ public class AlgorithmConfigXmlReader {
}; };
algorithmConfig.getXMLConfiguration().setEntityResolver(resolver); algorithmConfig.getXMLConfiguration().setEntityResolver(resolver);
algorithmConfig.getXMLConfiguration().setSchemaValidation(true); algorithmConfig.getXMLConfiguration().setSchemaValidation(true);
} } else {
else{
log.warn("cannot find schema-xsd file (algorithm_xml_schema.xsd). try to read xml without xml-file-validation."); log.warn("cannot find schema-xsd file (algorithm_xml_schema.xsd). try to read xml without xml-file-validation.");
} }
} }

View file

@ -56,21 +56,20 @@ class InsertionFactory {
String level = config.getString("level"); String level = config.getString("level");
if (level.equals("local")) { if (level.equals("local")) {
iBuilder.setLocalLevel(addDefaultCostCalculators); iBuilder.setLocalLevel(addDefaultCostCalculators);
} } else if (level.equals("route")) {
else if(level.equals("route")){
int forwardLooking = 0; int forwardLooking = 0;
int memory = 1; int memory = 1;
String forward = config.getString("level[@forwardLooking]"); String forward = config.getString("level[@forwardLooking]");
String mem = config.getString("level[@memory]"); String mem = config.getString("level[@memory]");
if (forward != null) forwardLooking = Integer.parseInt(forward); if (forward != null) forwardLooking = Integer.parseInt(forward);
else log.warn("parameter route[@forwardLooking] is missing. by default it is 0 which equals to local level"); else
log.warn("parameter route[@forwardLooking] is missing. by default it is 0 which equals to local level");
if (mem != null) memory = Integer.parseInt(mem); if (mem != null) memory = Integer.parseInt(mem);
else log.warn("parameter route[@memory] is missing. by default it is 1"); else log.warn("parameter route[@memory] is missing. by default it is 1");
iBuilder.setRouteLevel(forwardLooking, memory, addDefaultCostCalculators); iBuilder.setRouteLevel(forwardLooking, memory, addDefaultCostCalculators);
} } else
else throw new IllegalStateException("level " + level + " is not known. currently it only knows \"local\" or \"route\""); throw new IllegalStateException("level " + level + " is not known. currently it only knows \"local\" or \"route\"");
} } else iBuilder.setLocalLevel(addDefaultCostCalculators);
else iBuilder.setLocalLevel(addDefaultCostCalculators);
if (config.containsKey("considerFixedCosts") || config.containsKey("considerFixedCost")) { if (config.containsKey("considerFixedCosts") || config.containsKey("considerFixedCost")) {
if (addDefaultCostCalculators) { if (addDefaultCostCalculators) {
@ -81,14 +80,14 @@ class InsertionFactory {
String weight = config.getString("considerFixedCosts[@weight]"); String weight = config.getString("considerFixedCosts[@weight]");
if (weight == null) weight = config.getString("considerFixedCost[@weight]"); if (weight == null) weight = config.getString("considerFixedCost[@weight]");
if (weight != null) fixedCostWeight = Double.parseDouble(weight); if (weight != null) fixedCostWeight = Double.parseDouble(weight);
else throw new IllegalStateException("fixedCostsParameter 'weight' must be set, e.g. <considerFixedCosts weight=1.0>true</considerFixedCosts>.\n" + else
throw new IllegalStateException("fixedCostsParameter 'weight' must be set, e.g. <considerFixedCosts weight=1.0>true</considerFixedCosts>.\n" +
"this has to be changed in algorithm-config-xml-file."); "this has to be changed in algorithm-config-xml-file.");
iBuilder.considerFixedCosts(fixedCostWeight); iBuilder.considerFixedCosts(fixedCostWeight);
} } else if (val.equals("false")) {
else if(val.equals("false")){
} } else
else throw new IllegalStateException("considerFixedCosts must either be true or false, i.e. <considerFixedCosts weight=1.0>true</considerFixedCosts> or \n<considerFixedCosts weight=1.0>false</considerFixedCosts>. " + throw new IllegalStateException("considerFixedCosts must either be true or false, i.e. <considerFixedCosts weight=1.0>true</considerFixedCosts> or \n<considerFixedCosts weight=1.0>false</considerFixedCosts>. " +
"if latter, you can also omit the tag. this has to be changed in algorithm-config-xml-file"); "if latter, you can also omit the tag. this has to be changed in algorithm-config-xml-file");
} }
} }
@ -106,8 +105,7 @@ class InsertionFactory {
iBuilder.setInsertionStrategy(InsertionBuilder.Strategy.REGRET); iBuilder.setInsertionStrategy(InsertionBuilder.Strategy.REGRET);
} }
return iBuilder.build(); return iBuilder.build();
} } else throw new IllegalStateException("cannot create insertionStrategy, since it has no name.");
else throw new IllegalStateException("cannot create insertionStrategy, since it has no name.");
} }

View file

@ -42,6 +42,7 @@ import jsprit.core.algorithm.termination.VariationCoefficientTermination;
import jsprit.core.problem.VehicleRoutingProblem; import jsprit.core.problem.VehicleRoutingProblem;
import jsprit.core.problem.VehicleRoutingProblem.FleetSize; import jsprit.core.problem.VehicleRoutingProblem.FleetSize;
import jsprit.core.problem.constraint.ConstraintManager; import jsprit.core.problem.constraint.ConstraintManager;
import jsprit.core.problem.constraint.SwitchNotFeasible;
import jsprit.core.problem.solution.SolutionCostCalculator; import jsprit.core.problem.solution.SolutionCostCalculator;
import jsprit.core.problem.solution.VehicleRoutingProblemSolution; import jsprit.core.problem.solution.VehicleRoutingProblemSolution;
import jsprit.core.problem.solution.route.VehicleRoute; import jsprit.core.problem.solution.route.VehicleRoute;
@ -151,7 +152,6 @@ public class VehicleRoutingAlgorithms {
} }
@Override @Override
public Class<SolutionSelector> getType() { public Class<SolutionSelector> getType() {
return SolutionSelector.class; return SolutionSelector.class;
@ -195,7 +195,6 @@ public class VehicleRoutingAlgorithms {
} }
@Override @Override
public Class<SearchStrategyModule> getType() { public Class<SearchStrategyModule> getType() {
return SearchStrategyModule.class; return SearchStrategyModule.class;
@ -239,7 +238,6 @@ public class VehicleRoutingAlgorithms {
} }
@Override @Override
public Class<RuinStrategy> getType() { public Class<RuinStrategy> getType() {
return RuinStrategy.class; return RuinStrategy.class;
@ -283,7 +281,6 @@ public class VehicleRoutingAlgorithms {
} }
@Override @Override
public Class<InsertionStrategy> getType() { public Class<InsertionStrategy> getType() {
return InsertionStrategy.class; return InsertionStrategy.class;
@ -325,6 +322,7 @@ public class VehicleRoutingAlgorithms {
result = prime * result + ((name == null) ? 0 : name.hashCode()); result = prime * result + ((name == null) ? 0 : name.hashCode());
return result; return result;
} }
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (this == obj) if (this == obj)
@ -351,7 +349,8 @@ public class VehicleRoutingAlgorithms {
private static Logger log = LogManager.getLogger(VehicleRoutingAlgorithms.class.getName()); private static Logger log = LogManager.getLogger(VehicleRoutingAlgorithms.class.getName());
private VehicleRoutingAlgorithms(){} private VehicleRoutingAlgorithms() {
}
/** /**
* Creates a {@link jsprit.core.algorithm.VehicleRoutingAlgorithm} from a AlgorithConfig based on the input vrp. * Creates a {@link jsprit.core.algorithm.VehicleRoutingAlgorithm} from a AlgorithConfig based on the input vrp.
@ -363,6 +362,7 @@ public class VehicleRoutingAlgorithms {
public static VehicleRoutingAlgorithm createAlgorithm(final VehicleRoutingProblem vrp, final AlgorithmConfig algorithmConfig) { public static VehicleRoutingAlgorithm createAlgorithm(final VehicleRoutingProblem vrp, final AlgorithmConfig algorithmConfig) {
return createAlgo(vrp, algorithmConfig.getXMLConfiguration(), 0, null); return createAlgo(vrp, algorithmConfig.getXMLConfiguration(), 0, null);
} }
public static VehicleRoutingAlgorithm createAlgorithm(final VehicleRoutingProblem vrp, int nThreads, final AlgorithmConfig algorithmConfig) { public static VehicleRoutingAlgorithm createAlgorithm(final VehicleRoutingProblem vrp, int nThreads, final AlgorithmConfig algorithmConfig) {
return createAlgo(vrp, algorithmConfig.getXMLConfiguration(), nThreads, null); return createAlgo(vrp, algorithmConfig.getXMLConfiguration(), nThreads, null);
} }
@ -380,6 +380,7 @@ public class VehicleRoutingAlgorithms {
xmlReader.read(configURL); xmlReader.read(configURL);
return createAlgo(vrp, algorithmConfig.getXMLConfiguration(), 0, null); return createAlgo(vrp, algorithmConfig.getXMLConfiguration(), 0, null);
} }
public static VehicleRoutingAlgorithm readAndCreateAlgorithm(final VehicleRoutingProblem vrp, int nThreads, final URL configURL) { public static VehicleRoutingAlgorithm readAndCreateAlgorithm(final VehicleRoutingProblem vrp, int nThreads, final URL configURL) {
AlgorithmConfig algorithmConfig = new AlgorithmConfig(); AlgorithmConfig algorithmConfig = new AlgorithmConfig();
AlgorithmConfigXmlReader xmlReader = new AlgorithmConfigXmlReader(algorithmConfig); AlgorithmConfigXmlReader xmlReader = new AlgorithmConfigXmlReader(algorithmConfig);
@ -459,8 +460,7 @@ public class VehicleRoutingAlgorithms {
final StateManager stateManager; final StateManager stateManager;
if (stateMan != null) { if (stateMan != null) {
stateManager = stateMan; stateManager = stateMan;
} } else {
else{
stateManager = new StateManager(vrp); stateManager = new StateManager(vrp);
} }
stateManager.updateLoadStates(); stateManager.updateLoadStates();
@ -479,6 +479,7 @@ public class VehicleRoutingAlgorithms {
constraintManager.addTimeWindowConstraint(); constraintManager.addTimeWindowConstraint();
constraintManager.addLoadConstraint(); constraintManager.addLoadConstraint();
constraintManager.addSkillsConstraint(); constraintManager.addSkillsConstraint();
constraintManager.addConstraint(new SwitchNotFeasible(stateManager));
return readAndCreateAlgorithm(vrp, config, nuOfThreads, null, stateManager, constraintManager, true); return readAndCreateAlgorithm(vrp, config, nuOfThreads, null, stateManager, constraintManager, true);
} }
@ -529,8 +530,7 @@ public class VehicleRoutingAlgorithms {
} }
} }
}); });
} } else executorService = null;
else executorService = null;
//create fleetmanager //create fleetmanager
@ -540,8 +540,7 @@ public class VehicleRoutingAlgorithms {
final boolean switchAllowed; final boolean switchAllowed;
if (switchString != null) { if (switchString != null) {
switchAllowed = Boolean.parseBoolean(switchString); switchAllowed = Boolean.parseBoolean(switchString);
} } else switchAllowed = true;
else switchAllowed = true;
ActivityTimeTracker.ActivityPolicy activityPolicy; ActivityTimeTracker.ActivityPolicy activityPolicy;
if (stateManager.timeWindowUpdateIsActivated()) { if (stateManager.timeWindowUpdateIsActivated()) {
UpdateVehicleDependentPracticalTimeWindows timeWindowUpdater = new UpdateVehicleDependentPracticalTimeWindows(stateManager, vrp.getTransportCosts()); UpdateVehicleDependentPracticalTimeWindows timeWindowUpdater = new UpdateVehicleDependentPracticalTimeWindows(stateManager, vrp.getTransportCosts());
@ -564,8 +563,7 @@ public class VehicleRoutingAlgorithms {
}); });
stateManager.addStateUpdater(timeWindowUpdater); stateManager.addStateUpdater(timeWindowUpdater);
activityPolicy = ActivityTimeTracker.ActivityPolicy.AS_SOON_AS_TIME_WINDOW_OPENS; activityPolicy = ActivityTimeTracker.ActivityPolicy.AS_SOON_AS_TIME_WINDOW_OPENS;
} } else {
else{
activityPolicy = ActivityTimeTracker.ActivityPolicy.AS_SOON_AS_ARRIVED; activityPolicy = ActivityTimeTracker.ActivityPolicy.AS_SOON_AS_ARRIVED;
} }
stateManager.addStateUpdater(new UpdateActivityTimes(vrp.getTransportCosts(), activityPolicy)); stateManager.addStateUpdater(new UpdateActivityTimes(vrp.getTransportCosts(), activityPolicy));
@ -578,7 +576,8 @@ public class VehicleRoutingAlgorithms {
PrettyAlgorithmBuilder prettyAlgorithmBuilder = PrettyAlgorithmBuilder.newInstance(vrp, vehicleFleetManager, stateManager, constraintManager); PrettyAlgorithmBuilder prettyAlgorithmBuilder = PrettyAlgorithmBuilder.newInstance(vrp, vehicleFleetManager, stateManager, constraintManager);
//construct initial solution creator //construct initial solution creator
final InsertionStrategy initialInsertionStrategy = createInitialSolution(config, vrp, vehicleFleetManager, stateManager, algorithmListeners, definedClasses, executorService, nuOfThreads, costCalculator, constraintManager, addDefaultCostCalculators); final InsertionStrategy initialInsertionStrategy = createInitialSolution(config, vrp, vehicleFleetManager, stateManager, algorithmListeners, definedClasses, executorService, nuOfThreads, costCalculator, constraintManager, addDefaultCostCalculators);
if(initialInsertionStrategy != null) prettyAlgorithmBuilder.constructInitialSolutionWith(initialInsertionStrategy,costCalculator); if (initialInsertionStrategy != null)
prettyAlgorithmBuilder.constructInitialSolutionWith(initialInsertionStrategy, costCalculator);
//construct algorithm, i.e. search-strategies and its modules //construct algorithm, i.e. search-strategies and its modules
int solutionMemory = config.getInt("strategy.memory"); int solutionMemory = config.getInt("strategy.memory");
@ -605,7 +604,8 @@ public class VehicleRoutingAlgorithms {
//define prematureBreak //define prematureBreak
PrematureAlgorithmTermination prematureAlgorithmTermination = getPrematureTermination(config, algorithmListeners); PrematureAlgorithmTermination prematureAlgorithmTermination = getPrematureTermination(config, algorithmListeners);
if(prematureAlgorithmTermination != null) metaAlgorithm.setPrematureAlgorithmTermination(prematureAlgorithmTermination); if (prematureAlgorithmTermination != null)
metaAlgorithm.setPrematureAlgorithmTermination(prematureAlgorithmTermination);
else { else {
List<HierarchicalConfiguration> terminationCriteria = config.configurationsAt("terminationCriteria.termination"); List<HierarchicalConfiguration> terminationCriteria = config.configurationsAt("terminationCriteria.termination");
for (HierarchicalConfiguration terminationConfig : terminationCriteria) { for (HierarchicalConfiguration terminationConfig : terminationCriteria) {
@ -634,8 +634,7 @@ public class VehicleRoutingAlgorithms {
if (vrp.getFleetSize().equals(FleetSize.INFINITE)) { if (vrp.getFleetSize().equals(FleetSize.INFINITE)) {
return new InfiniteFleetManagerFactory(vrp.getVehicles()).createFleetManager(); return new InfiniteFleetManagerFactory(vrp.getVehicles()).createFleetManager();
} } else if (vrp.getFleetSize().equals(FleetSize.FINITE)) {
else if(vrp.getFleetSize().equals(FleetSize.FINITE)){
return new FiniteFleetManagerFactory(vrp.getVehicles()).createFleetManager(); return new FiniteFleetManagerFactory(vrp.getVehicles()).createFleetManager();
} }
throw new IllegalStateException("fleet size can only be infinite or finite. " + throw new IllegalStateException("fleet size can only be infinite or finite. " +
@ -716,7 +715,8 @@ public class VehicleRoutingAlgorithms {
throw new IllegalStateException("prematureBreak basedOn " + basedOn + " is not defined"); throw new IllegalStateException("prematureBreak basedOn " + basedOn + " is not defined");
} }
private static String getName(HierarchicalConfiguration strategyConfig) { if(strategyConfig.containsKey("[@name]")){ private static String getName(HierarchicalConfiguration strategyConfig) {
if (strategyConfig.containsKey("[@name]")) {
return strategyConfig.getString("[@name]"); return strategyConfig.getString("[@name]");
} }
return ""; return "";
@ -746,7 +746,8 @@ public class VehicleRoutingAlgorithms {
private static SolutionSelector getSelector(HierarchicalConfiguration strategyConfig, VehicleRoutingProblem vrp, Set<PrioritizedVRAListener> algorithmListeners, TypedMap definedSelectors) { private static SolutionSelector getSelector(HierarchicalConfiguration strategyConfig, VehicleRoutingProblem vrp, Set<PrioritizedVRAListener> algorithmListeners, TypedMap definedSelectors) {
String selectorName = strategyConfig.getString("selector[@name]"); String selectorName = strategyConfig.getString("selector[@name]");
if(selectorName == null) throw new IllegalStateException("no solutionSelector defined. define either \"selectRandomly\" or \"selectBest\""); if (selectorName == null)
throw new IllegalStateException("no solutionSelector defined. define either \"selectRandomly\" or \"selectBest\"");
String selectorId = strategyConfig.getString("selector[@id]"); String selectorId = strategyConfig.getString("selector[@id]");
if (selectorId == null) selectorId = "noId"; if (selectorId == null) selectorId = "noId";
ModKey modKey = makeKey(selectorName, selectorId); ModKey modKey = makeKey(selectorName, selectorId);
@ -807,8 +808,7 @@ public class VehicleRoutingAlgorithms {
if (nuWarmupIterations != null) { if (nuWarmupIterations != null) {
SchrimpfInitialThresholdGenerator iniThresholdGenerator = new SchrimpfInitialThresholdGenerator(schrimpf, Integer.parseInt(nuWarmupIterations)); SchrimpfInitialThresholdGenerator iniThresholdGenerator = new SchrimpfInitialThresholdGenerator(schrimpf, Integer.parseInt(nuWarmupIterations));
algorithmListeners.add(new PrioritizedVRAListener(Priority.LOW, iniThresholdGenerator)); algorithmListeners.add(new PrioritizedVRAListener(Priority.LOW, iniThresholdGenerator));
} } else {
else{
double threshold = strategyConfig.getDouble("acceptor.initialThreshold"); double threshold = strategyConfig.getDouble("acceptor.initialThreshold");
schrimpf.setInitialThreshold(threshold); schrimpf.setInitialThreshold(threshold);
} }
@ -823,8 +823,7 @@ public class VehicleRoutingAlgorithms {
algorithmListeners.add(new PrioritizedVRAListener(Priority.LOW, schrimpf)); algorithmListeners.add(new PrioritizedVRAListener(Priority.LOW, schrimpf));
typedMap.put(acceptorKey, schrimpf); typedMap.put(acceptorKey, schrimpf);
return schrimpf; return schrimpf;
} } else {
else{
throw new IllegalStateException("solution acceptor " + acceptorName + " is not known"); throw new IllegalStateException("solution acceptor " + acceptorName + " is not known");
} }
} }
@ -852,15 +851,15 @@ public class VehicleRoutingAlgorithms {
ModKey ruinKey = makeKey(ruin_name, ruin_id); ModKey ruinKey = makeKey(ruin_name, ruin_id);
if (ruin_name.equals("randomRuin")) { if (ruin_name.equals("randomRuin")) {
ruin = getRandomRuin(vrp, routeStates, definedClasses, ruinKey, shareToRuin); ruin = getRandomRuin(vrp, routeStates, definedClasses, ruinKey, shareToRuin);
} } else if (ruin_name.equals("radialRuin")) {
else if(ruin_name.equals("radialRuin")){
JobDistance jobDistance = new AvgServiceAndShipmentDistance(vrp.getTransportCosts()); JobDistance jobDistance = new AvgServiceAndShipmentDistance(vrp.getTransportCosts());
ruin = getRadialRuin(vrp, routeStates, definedClasses, ruinKey, shareToRuin, jobDistance); ruin = getRadialRuin(vrp, routeStates, definedClasses, ruinKey, shareToRuin, jobDistance);
} } else
else throw new IllegalStateException("ruin[@name] " + ruin_name + " is not known. Use either randomRuin or radialRuin."); throw new IllegalStateException("ruin[@name] " + ruin_name + " is not known. Use either randomRuin or radialRuin.");
String insertionName = moduleConfig.getString("insertion[@name]"); String insertionName = moduleConfig.getString("insertion[@name]");
if(insertionName == null) throw new IllegalStateException("module.insertion[@name] is missing. set it to \"regretInsertion\" or \"bestInsertion\""); if (insertionName == null)
throw new IllegalStateException("module.insertion[@name] is missing. set it to \"regretInsertion\" or \"bestInsertion\"");
String insertionId = moduleConfig.getString("insertion[@id]"); String insertionId = moduleConfig.getString("insertion[@id]");
if (insertionId == null) insertionId = "noId"; if (insertionId == null) insertionId = "noId";
ModKey insertionKey = makeKey(insertionName, insertionId); ModKey insertionKey = makeKey(insertionName, insertionId);
@ -911,6 +910,4 @@ public class VehicleRoutingAlgorithms {
} }
} }

View file

@ -22,8 +22,6 @@ import jsprit.core.problem.solution.VehicleRoutingProblemSolution;
import java.util.Collection; import java.util.Collection;
public interface AlgorithmEndsListener extends VehicleRoutingAlgorithmListener { public interface AlgorithmEndsListener extends VehicleRoutingAlgorithmListener {
void informAlgorithmEnds(VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions); void informAlgorithmEnds(VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions);

View file

@ -23,8 +23,6 @@ import jsprit.core.problem.solution.VehicleRoutingProblemSolution;
import java.util.Collection; import java.util.Collection;
public interface AlgorithmStartsListener extends VehicleRoutingAlgorithmListener { public interface AlgorithmStartsListener extends VehicleRoutingAlgorithmListener {
void informAlgorithmStarts(VehicleRoutingProblem problem, VehicleRoutingAlgorithm algorithm, Collection<VehicleRoutingProblemSolution> solutions); void informAlgorithmStarts(VehicleRoutingProblem problem, VehicleRoutingAlgorithm algorithm, Collection<VehicleRoutingProblemSolution> solutions);

View file

@ -22,9 +22,6 @@ import jsprit.core.problem.solution.VehicleRoutingProblemSolution;
import java.util.Collection; import java.util.Collection;
public interface IterationEndsListener extends VehicleRoutingAlgorithmListener { public interface IterationEndsListener extends VehicleRoutingAlgorithmListener {
public void informIterationEnds(int i, VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions); public void informIterationEnds(int i, VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions);

View file

@ -22,8 +22,6 @@ import jsprit.core.problem.solution.VehicleRoutingProblemSolution;
import java.util.Collection; import java.util.Collection;
public interface IterationStartsListener extends VehicleRoutingAlgorithmListener { public interface IterationStartsListener extends VehicleRoutingAlgorithmListener {
public void informIterationStarts(int i, VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions); public void informIterationStarts(int i, VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions);

View file

@ -23,8 +23,6 @@ import jsprit.core.problem.solution.VehicleRoutingProblemSolution;
import java.util.Collection; import java.util.Collection;
public interface StrategySelectedListener extends VehicleRoutingAlgorithmListener { public interface StrategySelectedListener extends VehicleRoutingAlgorithmListener {
void informSelectedStrategy(SearchStrategy.DiscoveredSolution discoveredSolution, VehicleRoutingProblem vehicleRoutingProblem, Collection<VehicleRoutingProblemSolution> vehicleRoutingProblemSolutions); void informSelectedStrategy(SearchStrategy.DiscoveredSolution discoveredSolution, VehicleRoutingProblem vehicleRoutingProblem, Collection<VehicleRoutingProblemSolution> vehicleRoutingProblemSolutions);

View file

@ -24,22 +24,23 @@ import jsprit.core.problem.solution.VehicleRoutingProblemSolution;
import java.util.*; import java.util.*;
public class VehicleRoutingAlgorithmListeners { public class VehicleRoutingAlgorithmListeners {
public static class PrioritizedVRAListener { public static class PrioritizedVRAListener {
Priority priority; Priority priority;
VehicleRoutingAlgorithmListener l; VehicleRoutingAlgorithmListener l;
public PrioritizedVRAListener(Priority priority, VehicleRoutingAlgorithmListener l) { public PrioritizedVRAListener(Priority priority, VehicleRoutingAlgorithmListener l) {
super(); super();
this.priority = priority; this.priority = priority;
this.l = l; this.l = l;
} }
public Priority getPriority() { public Priority getPriority() {
return priority; return priority;
} }
public VehicleRoutingAlgorithmListener getListener() { public VehicleRoutingAlgorithmListener getListener() {
return l; return l;
} }
@ -89,14 +90,11 @@ public class VehicleRoutingAlgorithmListeners {
if (o1 == o2) return 0; if (o1 == o2) return 0;
if (o1.getPriority() == Priority.HIGH && o2.getPriority() != Priority.HIGH) { if (o1.getPriority() == Priority.HIGH && o2.getPriority() != Priority.HIGH) {
return -1; return -1;
} } else if (o2.getPriority() == Priority.HIGH && o1.getPriority() != Priority.HIGH) {
else if(o2.getPriority() == Priority.HIGH && o1.getPriority() != Priority.HIGH){
return 1; return 1;
} } else if (o1.getPriority() == Priority.MEDIUM && o2.getPriority() != Priority.MEDIUM) {
else if(o1.getPriority() == Priority.MEDIUM && o2.getPriority() != Priority.MEDIUM){
return -1; return -1;
} } else if (o2.getPriority() == Priority.MEDIUM && o1.getPriority() != Priority.MEDIUM) {
else if(o2.getPriority() == Priority.MEDIUM && o1.getPriority() != Priority.MEDIUM){
return 1; return 1;
} }
return 1; return 1;
@ -114,7 +112,9 @@ public class VehicleRoutingAlgorithmListeners {
public void remove(PrioritizedVRAListener listener) { public void remove(PrioritizedVRAListener listener) {
boolean removed = algorithmListeners.remove(listener); boolean removed = algorithmListeners.remove(listener);
if(!removed){ throw new IllegalStateException("cannot remove listener"); } if (!removed) {
throw new IllegalStateException("cannot remove listener");
}
} }
public void addListener(VehicleRoutingAlgorithmListener listener, Priority priority) { public void addListener(VehicleRoutingAlgorithmListener listener, Priority priority) {
@ -143,7 +143,6 @@ public class VehicleRoutingAlgorithmListeners {
} }
public void iterationStarts(int i, VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions) { public void iterationStarts(int i, VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions) {
for (PrioritizedVRAListener l : algorithmListeners) { for (PrioritizedVRAListener l : algorithmListeners) {
if (l.getListener() instanceof IterationStartsListener) { if (l.getListener() instanceof IterationStartsListener) {
@ -153,7 +152,6 @@ public class VehicleRoutingAlgorithmListeners {
} }
public void algorithmStarts(VehicleRoutingProblem problem, VehicleRoutingAlgorithm algorithm, Collection<VehicleRoutingProblemSolution> solutions) { public void algorithmStarts(VehicleRoutingProblem problem, VehicleRoutingAlgorithm algorithm, Collection<VehicleRoutingProblemSolution> solutions) {
for (PrioritizedVRAListener l : algorithmListeners) { for (PrioritizedVRAListener l : algorithmListeners) {
if (l.getListener() instanceof AlgorithmStartsListener) { if (l.getListener() instanceof AlgorithmStartsListener) {

View file

@ -110,7 +110,7 @@ public abstract class AbstractInsertionStrategy implements InsertionStrategy{
} }
protected void insertJob(Job unassignedJob, InsertionData iData, VehicleRoute inRoute) { protected void insertJob(Job unassignedJob, InsertionData iData, VehicleRoute inRoute) {
logger.trace("insert: [jobId=" + unassignedJob.getId() + "]" + iData ); logger.trace("insert: [jobId={}]{}", unassignedJob.getId(), iData);
insertionsListeners.informBeforeJobInsertion(unassignedJob, iData, inRoute); insertionsListeners.informBeforeJobInsertion(unassignedJob, iData, inRoute);
if (!(inRoute.getVehicle().getId().equals(iData.getSelectedVehicle().getId()))) { if (!(inRoute.getVehicle().getId().equals(iData.getSelectedVehicle().getId()))) {
insertionsListeners.informVehicleSwitched(inRoute, inRoute.getVehicle(), iData.getSelectedVehicle()); insertionsListeners.informVehicleSwitched(inRoute, inRoute.getVehicle(), iData.getSelectedVehicle());

View file

@ -1,4 +1,3 @@
/******************************************************************************* /*******************************************************************************
* Copyright (C) 2014 Stefan Schroeder * Copyright (C) 2014 Stefan Schroeder
* *
@ -27,17 +26,20 @@ public interface ActivityInsertionCostsCalculator {
private double additionalCosts; private double additionalCosts;
private double additionalTime; private double additionalTime;
public ActivityInsertionCosts(double additionalCosts, double additionalTime) { public ActivityInsertionCosts(double additionalCosts, double additionalTime) {
super(); super();
this.additionalCosts = additionalCosts; this.additionalCosts = additionalCosts;
this.additionalTime = additionalTime; this.additionalTime = additionalTime;
} }
/** /**
* @return the additionalCosts * @return the additionalCosts
*/ */
public double getAdditionalCosts() { public double getAdditionalCosts() {
return additionalCosts; return additionalCosts;
} }
/** /**
* @return the additionalTime * @return the additionalTime
*/ */
@ -46,7 +48,6 @@ public interface ActivityInsertionCostsCalculator {
} }
} }
public double getCosts(JobInsertionContext iContext, TourActivity prevAct, TourActivity nextAct, TourActivity newAct, double depTimeAtPrevAct); public double getCosts(JobInsertionContext iContext, TourActivity prevAct, TourActivity nextAct, TourActivity newAct, double depTimeAtPrevAct);

View file

@ -25,11 +25,10 @@ import jsprit.core.problem.vehicle.Vehicle;
/** /**
* Estimates additional access/egress costs when operating route with a new vehicle that has different start/end-location. * Estimates additional access/egress costs when operating route with a new vehicle that has different start/end-location.
* * <p/>
* <p>If two vehicles have the same start/end-location and departure-time .getCosts(...) must return zero. * <p>If two vehicles have the same start/end-location and departure-time .getCosts(...) must return zero.
* *
* @author schroeder * @author schroeder
*
*/ */
class AdditionalAccessEgressCalculator { class AdditionalAccessEgressCalculator {
@ -37,11 +36,10 @@ class AdditionalAccessEgressCalculator {
/** /**
* Constructs the estimator that estimates additional access/egress costs when operating route with a new vehicle that has different start/end-location. * Constructs the estimator that estimates additional access/egress costs when operating route with a new vehicle that has different start/end-location.
* * <p/>
* <p>If two vehicles have the same start/end-location and departure-time .getCosts(...) must return zero. * <p>If two vehicles have the same start/end-location and departure-time .getCosts(...) must return zero.
* *
* @author schroeder * @author schroeder
*
*/ */
public AdditionalAccessEgressCalculator(VehicleRoutingTransportCosts routingCosts) { public AdditionalAccessEgressCalculator(VehicleRoutingTransportCosts routingCosts) {
this.routingCosts = routingCosts; this.routingCosts = routingCosts;

View file

@ -27,7 +27,6 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
final class AuxilliaryCostCalculator { final class AuxilliaryCostCalculator {
private final VehicleRoutingTransportCosts routingCosts; private final VehicleRoutingTransportCosts routingCosts;
@ -41,7 +40,6 @@ final class AuxilliaryCostCalculator {
} }
/** /**
*
* @param path activity path to get the costs for * @param path activity path to get the costs for
* @param depTime departure time at first activity in path * @param depTime departure time at first activity in path
* @param driver driver of vehicle * @param driver driver of vehicle

View file

@ -30,13 +30,10 @@ import java.util.Collections;
import java.util.List; import java.util.List;
/** /**
* Best insertion that insert the job where additional costs are minimal. * Best insertion that insert the job where additional costs are minimal.
* *
* @author stefan schroeder * @author stefan schroeder
*
*/ */
public final class BestInsertion extends AbstractInsertionStrategy { public final class BestInsertion extends AbstractInsertionStrategy {
@ -56,7 +53,7 @@ public final class BestInsertion extends AbstractInsertionStrategy{
public BestInsertion(JobInsertionCostsCalculator jobInsertionCalculator, VehicleRoutingProblem vehicleRoutingProblem) { public BestInsertion(JobInsertionCostsCalculator jobInsertionCalculator, VehicleRoutingProblem vehicleRoutingProblem) {
super(vehicleRoutingProblem); super(vehicleRoutingProblem);
bestInsertionCostCalculator = jobInsertionCalculator; bestInsertionCostCalculator = jobInsertionCalculator;
logger.debug("initialise " + this); logger.debug("initialise {}", this);
} }
@Override @Override

View file

@ -77,7 +77,9 @@ public class BestInsertionBuilder {
this.forwaredLooking = forwardLooking; this.forwaredLooking = forwardLooking;
this.memory = memory; this.memory = memory;
return this; return this;
}; }
;
public BestInsertionBuilder setRouteLevel(int forwardLooking, int memory, boolean addDefaultMarginalCostCalculation) { public BestInsertionBuilder setRouteLevel(int forwardLooking, int memory, boolean addDefaultMarginalCostCalculation) {
local = false; local = false;
@ -85,12 +87,16 @@ public class BestInsertionBuilder {
this.memory = memory; this.memory = memory;
this.addDefaultCostCalc = addDefaultMarginalCostCalculation; this.addDefaultCostCalc = addDefaultMarginalCostCalculation;
return this; return this;
}; }
;
public BestInsertionBuilder setLocalLevel() { public BestInsertionBuilder setLocalLevel() {
local = true; local = true;
return this; return this;
}; }
;
/** /**
* If addDefaulMarginalCostCalculation is false, no calculator is set which implicitly assumes that marginal cost calculation * If addDefaulMarginalCostCalculation is false, no calculator is set which implicitly assumes that marginal cost calculation
@ -114,7 +120,9 @@ public class BestInsertionBuilder {
public BestInsertionBuilder setActivityInsertionCostCalculator(ActivityInsertionCostsCalculator activityInsertionCostsCalculator) { public BestInsertionBuilder setActivityInsertionCostCalculator(ActivityInsertionCostsCalculator activityInsertionCostsCalculator) {
this.actInsertionCostsCalculator = activityInsertionCostsCalculator; this.actInsertionCostsCalculator = activityInsertionCostsCalculator;
return this; return this;
}; }
;
public BestInsertionBuilder setConcurrentMode(ExecutorService executor, int nuOfThreads) { public BestInsertionBuilder setConcurrentMode(ExecutorService executor, int nuOfThreads) {
this.executor = executor; this.executor = executor;
@ -129,8 +137,7 @@ public class BestInsertionBuilder {
JobInsertionCostsCalculatorBuilder calcBuilder = new JobInsertionCostsCalculatorBuilder(iListeners, algorithmListeners); JobInsertionCostsCalculatorBuilder calcBuilder = new JobInsertionCostsCalculatorBuilder(iListeners, algorithmListeners);
if (local) { if (local) {
calcBuilder.setLocalLevel(addDefaultCostCalc); calcBuilder.setLocalLevel(addDefaultCostCalc);
} } else {
else {
calcBuilder.setRouteLevel(forwaredLooking, memory, addDefaultCostCalc); calcBuilder.setRouteLevel(forwaredLooking, memory, addDefaultCostCalc);
} }
calcBuilder.setConstraintManager(constraintManager); calcBuilder.setConstraintManager(constraintManager);
@ -149,8 +156,7 @@ public class BestInsertionBuilder {
InsertionStrategy bestInsertion; InsertionStrategy bestInsertion;
if (executor == null) { if (executor == null) {
bestInsertion = new BestInsertion(jobInsertions, vrp); bestInsertion = new BestInsertion(jobInsertions, vrp);
} } else {
else{
bestInsertion = new BestInsertionConcurrent(jobInsertions, executor, nuOfThreads, vrp); bestInsertion = new BestInsertionConcurrent(jobInsertions, executor, nuOfThreads, vrp);
} }
for (InsertionListener l : iListeners) bestInsertion.addListener(l); for (InsertionListener l : iListeners) bestInsertion.addListener(l);
@ -158,9 +164,9 @@ public class BestInsertionBuilder {
} }
/** /**
* @deprecated this is experimental and can disappear.
* @param timeSlice the time slice * @param timeSlice the time slice
* @param nNeighbors number of neighbors * @param nNeighbors number of neighbors
* @deprecated this is experimental and can disappear.
*/ */
@Deprecated @Deprecated
public void experimentalTimeScheduler(double timeSlice, int nNeighbors) { public void experimentalTimeScheduler(double timeSlice, int nNeighbors) {
@ -174,6 +180,4 @@ public class BestInsertionBuilder {
} }
} }

View file

@ -30,12 +30,8 @@ import java.util.*;
import java.util.concurrent.*; import java.util.concurrent.*;
/** /**
*
* @author stefan schroeder * @author stefan schroeder
*
*/ */
public final class BestInsertionConcurrent extends AbstractInsertionStrategy { public final class BestInsertionConcurrent extends AbstractInsertionStrategy {
@ -94,7 +90,7 @@ public final class BestInsertionConcurrent extends AbstractInsertionStrategy{
this.nuOfBatches = nuOfBatches; this.nuOfBatches = nuOfBatches;
bestInsertionCostCalculator = jobInsertionCalculator; bestInsertionCostCalculator = jobInsertionCalculator;
completionService = new ExecutorCompletionService<Insertion>(executorService); completionService = new ExecutorCompletionService<Insertion>(executorService);
logger.debug("initialise " + this); logger.debug("initialise {}", this);
} }
@Override @Override
@ -133,10 +129,9 @@ public final class BestInsertionConcurrent extends AbstractInsertionStrategy{
} }
} catch (InterruptedException e) { } catch (InterruptedException e) {
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
} } catch (ExecutionException e) {
catch (ExecutionException e) {
e.printStackTrace(); e.printStackTrace();
logger.error(e.getCause().toString()); logger.error("Exception", e);
System.exit(1); System.exit(1);
} }
VehicleRoute newRoute = VehicleRoute.emptyRoute(); VehicleRoute newRoute = VehicleRoute.emptyRoute();
@ -180,8 +175,7 @@ public final class BestInsertionConcurrent extends AbstractInsertionStrategy{
for (int i = 0; i < nOfNewRoutes; i++) { for (int i = 0; i < nOfNewRoutes; i++) {
vehicleRoutes.add(VehicleRoute.emptyRoute()); vehicleRoutes.add(VehicleRoute.emptyRoute());
} }
} } else {
else{
vehicleRoutes.add(VehicleRoute.emptyRoute()); vehicleRoutes.add(VehicleRoute.emptyRoute());
} }
/* /*

View file

@ -20,10 +20,12 @@ class CalculatesServiceInsertionWithTimeScheduling implements JobInsertionCostsC
public static class KnowledgeInjection implements InsertionStartsListener { public static class KnowledgeInjection implements InsertionStartsListener {
private CalculatesServiceInsertionWithTimeScheduling c; private CalculatesServiceInsertionWithTimeScheduling c;
public KnowledgeInjection(CalculatesServiceInsertionWithTimeScheduling c) { public KnowledgeInjection(CalculatesServiceInsertionWithTimeScheduling c) {
super(); super();
this.c = c; this.c = c;
} }
@Override @Override
public void informInsertionStarts(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs) { public void informInsertionStarts(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs) {
List<Double> knowledge = new ArrayList<Double>(); List<Double> knowledge = new ArrayList<Double>();
@ -70,8 +72,7 @@ class CalculatesServiceInsertionWithTimeScheduling implements JobInsertionCostsC
if (!departureTimeKnowledge.isEmpty()) { if (!departureTimeKnowledge.isEmpty()) {
departureTime = departureTimeKnowledge.get(random.nextInt(departureTimeKnowledge.size())); departureTime = departureTimeKnowledge.get(random.nextInt(departureTimeKnowledge.size()));
} }
} } else if (!currentRoute.getVehicle().getId().equals(newVehicle.getId())) {
else if(!currentRoute.getVehicle().getId().equals(newVehicle.getId())){
departureTime = currentRoute.getDepartureTime(); departureTime = currentRoute.getDepartureTime();
} }

View file

@ -57,8 +57,7 @@ class CalculatesServiceInsertionWithTimeSchedulingInSlices implements JobInserti
double currentStart; double currentStart;
if (currentRoute.getStart() == null) { if (currentRoute.getStart() == null) {
currentStart = newVehicleDepartureTime; currentStart = newVehicleDepartureTime;
} } else currentStart = currentRoute.getStart().getEndTime();
else currentStart = currentRoute.getStart().getEndTime();
vehicleDepartureTimes.add(currentStart); vehicleDepartureTimes.add(currentStart);
// double earliestDeparture = newVehicle.getEarliestDeparture(); // double earliestDeparture = newVehicle.getEarliestDeparture();

View file

@ -75,8 +75,7 @@ class Inserter {
} }
TourActivity activity = vehicleRoutingProblem.copyAndGetActivities(job).get(0); TourActivity activity = vehicleRoutingProblem.copyAndGetActivities(job).get(0);
route.getTourActivities().addActivity(iData.getDeliveryInsertionIndex(), activity); route.getTourActivities().addActivity(iData.getDeliveryInsertionIndex(), activity);
} } else delegator.handleJobInsertion(job, iData, route);
else delegator.handleJobInsertion(job, iData, route);
} }
private void setEndLocation(VehicleRoute route, Service service) { private void setEndLocation(VehicleRoute route, Service service) {
@ -115,8 +114,7 @@ class Inserter {
} }
route.getTourActivities().addActivity(iData.getDeliveryInsertionIndex(), deliverShipment); route.getTourActivities().addActivity(iData.getDeliveryInsertionIndex(), deliverShipment);
route.getTourActivities().addActivity(iData.getPickupInsertionIndex(), pickupShipment); route.getTourActivities().addActivity(iData.getPickupInsertionIndex(), pickupShipment);
} } else delegator.handleJobInsertion(job, iData, route);
else delegator.handleJobInsertion(job, iData, route);
} }
private void setEndLocation(VehicleRoute route, Shipment shipment) { private void setEndLocation(VehicleRoute route, Shipment shipment) {
@ -145,7 +143,8 @@ class Inserter {
public void insertJob(Job job, InsertionData insertionData, VehicleRoute vehicleRoute) { public void insertJob(Job job, InsertionData insertionData, VehicleRoute vehicleRoute) {
insertionListeners.informBeforeJobInsertion(job, insertionData, vehicleRoute); insertionListeners.informBeforeJobInsertion(job, insertionData, vehicleRoute);
if(insertionData == null || (insertionData instanceof NoInsertionFound)) throw new IllegalStateException("insertionData null. cannot insert job."); if (insertionData == null || (insertionData instanceof NoInsertionFound))
throw new IllegalStateException("insertionData null. cannot insert job.");
if (job == null) throw new IllegalStateException("cannot insert null-job"); if (job == null) throw new IllegalStateException("cannot insert null-job");
if (!(vehicleRoute.getVehicle().getId().equals(insertionData.getSelectedVehicle().getId()))) { if (!(vehicleRoute.getVehicle().getId().equals(insertionData.getSelectedVehicle().getId()))) {
insertionListeners.informVehicleSwitched(vehicleRoute, vehicleRoute.getVehicle(), insertionData.getSelectedVehicle()); insertionListeners.informVehicleSwitched(vehicleRoute, vehicleRoute.getVehicle(), insertionData.getSelectedVehicle());

View file

@ -140,8 +140,7 @@ public class InsertionBuilder {
JobInsertionCostsCalculatorBuilder calcBuilder = new JobInsertionCostsCalculatorBuilder(iListeners, algorithmListeners); JobInsertionCostsCalculatorBuilder calcBuilder = new JobInsertionCostsCalculatorBuilder(iListeners, algorithmListeners);
if (local) { if (local) {
calcBuilder.setLocalLevel(addDefaultCostCalc); calcBuilder.setLocalLevel(addDefaultCostCalc);
} } else {
else {
calcBuilder.setRouteLevel(forwaredLooking, memory, addDefaultCostCalc); calcBuilder.setRouteLevel(forwaredLooking, memory, addDefaultCostCalc);
} }
calcBuilder.setConstraintManager(constraintManager); calcBuilder.setConstraintManager(constraintManager);
@ -165,24 +164,21 @@ public class InsertionBuilder {
} else { } else {
insertion = new BestInsertionConcurrent(costCalculator, executor, nuOfThreads, vrp); insertion = new BestInsertionConcurrent(costCalculator, executor, nuOfThreads, vrp);
} }
} } else if (strategy.equals(Strategy.REGRET)) {
else if(strategy.equals(Strategy.REGRET)){
if (executor == null) { if (executor == null) {
insertion = new RegretInsertion(costCalculator, vrp); insertion = new RegretInsertion(costCalculator, vrp);
} } else {
else {
insertion = new RegretInsertionConcurrent(costCalculator, vrp, executor); insertion = new RegretInsertionConcurrent(costCalculator, vrp, executor);
} }
} } else throw new IllegalStateException("you should never get here");
else throw new IllegalStateException("you should never get here");
for (InsertionListener l : iListeners) insertion.addListener(l); for (InsertionListener l : iListeners) insertion.addListener(l);
return insertion; return insertion;
} }
/** /**
* @deprecated this is experimental and can disappear.
* @param timeSlice the time slice * @param timeSlice the time slice
* @param nNeighbors number of neighbors * @param nNeighbors number of neighbors
* @deprecated this is experimental and can disappear.
*/ */
@Deprecated @Deprecated
public void experimentalTimeScheduler(double timeSlice, int nNeighbors) { public void experimentalTimeScheduler(double timeSlice, int nNeighbors) {
@ -197,6 +193,4 @@ public class InsertionBuilder {
} }
} }

View file

@ -27,7 +27,6 @@ import java.util.List;
* and departureTime of vehicle at vehicle's start location (e.g. depot). * and departureTime of vehicle at vehicle's start location (e.g. depot).
* *
* @author stefan * @author stefan
*
*/ */
public class InsertionData { public class InsertionData {
@ -162,5 +161,4 @@ public class InsertionData {
} }
} }

View file

@ -23,18 +23,17 @@ import jsprit.core.problem.solution.route.VehicleRoute;
import java.util.Collection; import java.util.Collection;
/** /**
* Basic interface for insertion strategies * Basic interface for insertion strategies
* *
* @author stefan schroeder * @author stefan schroeder
*
*/ */
public interface InsertionStrategy { public interface InsertionStrategy {
/** /**
* Inserts unassigned jobs into vehicle routes. * Inserts unassigned jobs into vehicle routes.
*
* @param vehicleRoutes existing vehicle routes * @param vehicleRoutes existing vehicle routes
* @param unassignedJobs jobs to be inserted * @param unassignedJobs jobs to be inserted
*/ */

View file

@ -46,7 +46,7 @@ final class JobInsertionConsideringFixCostsCalculator implements JobInsertionCos
super(); super();
this.standardServiceInsertion = standardInsertionCalculator; this.standardServiceInsertion = standardInsertionCalculator;
this.stateGetter = stateGetter; this.stateGetter = stateGetter;
logger.debug("inialise " + this); logger.debug("inialise {}", this);
} }
@Override @Override
@ -77,7 +77,7 @@ final class JobInsertionConsideringFixCostsCalculator implements JobInsertionCos
public void setWeightOfFixCost(double weight) { public void setWeightOfFixCost(double weight) {
weight_deltaFixCost = weight; weight_deltaFixCost = weight;
logger.debug("set weightOfFixCostSaving to " + weight); logger.debug("set weightOfFixCostSaving to {}", weight);
} }
@Override @Override

View file

@ -66,7 +66,6 @@ class LocalActivityInsertionCostsCalculator implements ActivityInsertionCostsCal
double newAct_endTime = CalculationUtils.getActivityEndTime(newAct_arrTime, newAct); double newAct_endTime = CalculationUtils.getActivityEndTime(newAct_arrTime, newAct);
double act_costs_newAct = activityCosts.getActivityCost(newAct, newAct_arrTime, iFacts.getNewDriver(), iFacts.getNewVehicle()); double act_costs_newAct = activityCosts.getActivityCost(newAct, newAct_arrTime, iFacts.getNewDriver(), iFacts.getNewVehicle());
// if(newAct instanceof BreakActivity) act_costs_newAct = 0.;
if(isEnd(nextAct) && !toDepot(iFacts.getNewVehicle())) return tp_costs_prevAct_newAct; if(isEnd(nextAct) && !toDepot(iFacts.getNewVehicle())) return tp_costs_prevAct_newAct;
@ -75,7 +74,6 @@ class LocalActivityInsertionCostsCalculator implements ActivityInsertionCostsCal
double nextAct_arrTime = newAct_endTime + tp_time_newAct_nextAct; double nextAct_arrTime = newAct_endTime + tp_time_newAct_nextAct;
double endTime_nextAct_new = CalculationUtils.getActivityEndTime(nextAct_arrTime, nextAct); double endTime_nextAct_new = CalculationUtils.getActivityEndTime(nextAct_arrTime, nextAct);
double act_costs_nextAct = activityCosts.getActivityCost(nextAct, nextAct_arrTime, iFacts.getNewDriver(), iFacts.getNewVehicle()); double act_costs_nextAct = activityCosts.getActivityCost(nextAct, nextAct_arrTime, iFacts.getNewDriver(), iFacts.getNewVehicle());
// if(nextAct instanceof BreakActivity) act_costs_nextAct = 0;
double totalCosts = tp_costs_prevAct_newAct + tp_costs_newAct_nextAct + solutionCompletenessRatio * activityCostsWeight * (act_costs_newAct + act_costs_nextAct); double totalCosts = tp_costs_prevAct_newAct + tp_costs_newAct_nextAct + solutionCompletenessRatio * activityCostsWeight * (act_costs_newAct + act_costs_nextAct);
@ -89,7 +87,6 @@ class LocalActivityInsertionCostsCalculator implements ActivityInsertionCostsCal
double arrTime_nextAct = depTimeAtPrevAct + routingCosts.getTransportTime(prevAct.getLocation(), nextAct.getLocation(), prevAct.getEndTime(), iFacts.getRoute().getDriver(), iFacts.getRoute().getVehicle()); double arrTime_nextAct = depTimeAtPrevAct + routingCosts.getTransportTime(prevAct.getLocation(), nextAct.getLocation(), prevAct.getEndTime(), iFacts.getRoute().getDriver(), iFacts.getRoute().getVehicle());
double endTime_nextAct_old = CalculationUtils.getActivityEndTime(arrTime_nextAct,nextAct); double endTime_nextAct_old = CalculationUtils.getActivityEndTime(arrTime_nextAct,nextAct);
double actCost_nextAct = activityCosts.getActivityCost(nextAct, arrTime_nextAct, iFacts.getRoute().getDriver(), iFacts.getRoute().getVehicle()); double actCost_nextAct = activityCosts.getActivityCost(nextAct, arrTime_nextAct, iFacts.getRoute().getDriver(), iFacts.getRoute().getVehicle());
// if(nextAct instanceof BreakActivity) actCost_nextAct = 0;
double endTimeDelay_nextAct = Math.max(0, endTime_nextAct_new - endTime_nextAct_old); double endTimeDelay_nextAct = Math.max(0, endTime_nextAct_new - endTime_nextAct_old);
Double futureWaiting = stateManager.getActivityState(nextAct, iFacts.getRoute().getVehicle(), InternalStates.FUTURE_WAITING, Double.class); Double futureWaiting = stateManager.getActivityState(nextAct, iFacts.getRoute().getVehicle(), InternalStates.FUTURE_WAITING, Double.class);

View file

@ -207,7 +207,7 @@ public class RegretInsertion extends AbstractInsertionStrategy {
this.scoringFunction = new DefaultScorer(vehicleRoutingProblem); this.scoringFunction = new DefaultScorer(vehicleRoutingProblem);
this.insertionCostsCalculator = jobInsertionCalculator; this.insertionCostsCalculator = jobInsertionCalculator;
this.vrp = vehicleRoutingProblem; this.vrp = vehicleRoutingProblem;
logger.debug("initialise " + this); logger.debug("initialise {}", this);
} }
@Override @Override

View file

@ -33,14 +33,13 @@ import java.util.concurrent.*;
/** /**
* Insertion based on regret approach. * Insertion based on regret approach.
* * <p/>
* <p>Basically calculates the insertion cost of the firstBest and the secondBest alternative. The score is then calculated as difference * <p>Basically calculates the insertion cost of the firstBest and the secondBest alternative. The score is then calculated as difference
* between secondBest and firstBest, plus additional scoring variables that can defined in this.ScoringFunction. * between secondBest and firstBest, plus additional scoring variables that can defined in this.ScoringFunction.
* The idea is that if the cost of the secondBest alternative is way higher than the first best, it seems to be important to insert this * The idea is that if the cost of the secondBest alternative is way higher than the first best, it seems to be important to insert this
* customer immediatedly. If difference is not that high, it might not impact solution if this customer is inserted later. * customer immediatedly. If difference is not that high, it might not impact solution if this customer is inserted later.
* *
* @author stefan schroeder * @author stefan schroeder
*
*/ */
public class RegretInsertionConcurrent extends AbstractInsertionStrategy { public class RegretInsertionConcurrent extends AbstractInsertionStrategy {
@ -55,7 +54,7 @@ public class RegretInsertionConcurrent extends AbstractInsertionStrategy {
/** /**
* Sets the scoring function. * Sets the scoring function.
* * <p/>
* <p>By default, the this.TimeWindowScorer is used. * <p>By default, the this.TimeWindowScorer is used.
* *
* @param scoringFunction to score * @param scoringFunction to score
@ -81,9 +80,10 @@ public class RegretInsertionConcurrent extends AbstractInsertionStrategy {
/** /**
* Runs insertion. * Runs insertion.
* * <p/>
* <p>Before inserting a job, all unassigned jobs are scored according to its best- and secondBest-insertion plus additional scoring variables. * <p>Before inserting a job, all unassigned jobs are scored according to its best- and secondBest-insertion plus additional scoring variables.
* *
* @throws java.lang.RuntimeException if smth went wrong with thread execution
*/ */
@Override @Override
public Collection<Job> insertUnassignedJobs(Collection<VehicleRoute> routes, Collection<Job> unassignedJobs) { public Collection<Job> insertUnassignedJobs(Collection<VehicleRoute> routes, Collection<Job> unassignedJobs) {
@ -133,28 +133,18 @@ public class RegretInsertionConcurrent extends AbstractInsertionStrategy {
} }
if (bestScoredJob == null) { if (bestScoredJob == null) {
bestScoredJob = sJob; bestScoredJob = sJob;
} } else if (sJob.getScore() > bestScoredJob.getScore()) {
else if(sJob.getScore() > bestScoredJob.getScore()){
bestScoredJob = sJob; bestScoredJob = sJob;
} }
} }
} } catch (InterruptedException e) {
catch(InterruptedException e){
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
} } catch (ExecutionException e) {
catch (ExecutionException e) { throw new RuntimeException(e);
e.printStackTrace();
logger.error(e.getCause().toString());
System.exit(1);
} }
return bestScoredJob; return bestScoredJob;
} }
} }

View file

@ -1,4 +1,3 @@
/******************************************************************************* /*******************************************************************************
* Copyright (C) 2014 Stefan Schroeder * Copyright (C) 2014 Stefan Schroeder
* *
@ -52,11 +51,15 @@ class RouteLevelActivityInsertionCostsEstimator implements ActivityInsertionCost
@Override @Override
public double getCosts(JobInsertionContext iFacts, TourActivity prevAct, TourActivity nextAct, TourActivity newAct, double depTimeAtPrevAct) { public double getCosts(JobInsertionContext iFacts, TourActivity prevAct, TourActivity nextAct, TourActivity newAct, double depTimeAtPrevAct) {
List<TourActivity> path = new ArrayList<TourActivity>(); List<TourActivity> path = new ArrayList<TourActivity>();
path.add(prevAct); path.add(newAct); path.add(nextAct); path.add(prevAct);
path.add(newAct);
path.add(nextAct);
int actIndex; int actIndex;
if (prevAct instanceof Start) actIndex = 0; if (prevAct instanceof Start) actIndex = 0;
else actIndex = iFacts.getRoute().getTourActivities().getActivities().indexOf(nextAct); else actIndex = iFacts.getRoute().getTourActivities().getActivities().indexOf(nextAct);
if(nuOfActivities2LookForward > 0 && !(nextAct instanceof End)){ path.addAll(getForwardLookingPath(iFacts.getRoute(),actIndex)); } if (nuOfActivities2LookForward > 0 && !(nextAct instanceof End)) {
path.addAll(getForwardLookingPath(iFacts.getRoute(), actIndex));
}
/* /*
* calculates the path costs with new vehicle, c(forwardPath,newVehicle). * calculates the path costs with new vehicle, c(forwardPath,newVehicle).
@ -69,8 +72,7 @@ class RouteLevelActivityInsertionCostsEstimator implements ActivityInsertionCost
Double cost_at_act; Double cost_at_act;
if (act instanceof End) { if (act instanceof End) {
cost_at_act = stateManager.getRouteState(vehicleRoute, InternalStates.COSTS, Double.class); cost_at_act = stateManager.getRouteState(vehicleRoute, InternalStates.COSTS, Double.class);
} } else {
else{
cost_at_act = stateManager.getActivityState(act, InternalStates.COSTS, Double.class); cost_at_act = stateManager.getActivityState(act, InternalStates.COSTS, Double.class);
} }
if (cost_at_act == null) cost_at_act = 0.; if (cost_at_act == null) cost_at_act = 0.;

View file

@ -39,7 +39,6 @@ import java.util.Iterator;
* Calculator that calculates the best insertion position for a {@link Service}. * Calculator that calculates the best insertion position for a {@link Service}.
* *
* @author schroeder * @author schroeder
*
*/ */
final class ServiceInsertionCalculator implements JobInsertionCostsCalculator { final class ServiceInsertionCalculator implements JobInsertionCostsCalculator {
@ -70,7 +69,7 @@ final class ServiceInsertionCalculator implements JobInsertionCostsCalculator{
softRouteConstraint = constraintManager; softRouteConstraint = constraintManager;
this.additionalTransportCostsCalculator = additionalTransportCostsCalculator; this.additionalTransportCostsCalculator = additionalTransportCostsCalculator;
additionalAccessEgressCalculator = new AdditionalAccessEgressCalculator(routingCosts); additionalAccessEgressCalculator = new AdditionalAccessEgressCalculator(routingCosts);
logger.debug("initialise " + this); logger.debug("initialise {}", this);
} }
public void setJobActivityFactory(JobActivityFactory jobActivityFactory) { public void setJobActivityFactory(JobActivityFactory jobActivityFactory) {
@ -85,7 +84,6 @@ final class ServiceInsertionCalculator implements JobInsertionCostsCalculator{
/** /**
* Calculates the marginal cost of inserting job i locally. This is based on the * Calculates the marginal cost of inserting job i locally. This is based on the
* assumption that cost changes can entirely covered by only looking at the predecessor i-1 and its successor i+1. * assumption that cost changes can entirely covered by only looking at the predecessor i-1 and its successor i+1.
*
*/ */
@Override @Override
public InsertionData getInsertionData(final VehicleRoute currentRoute, final Job jobToInsert, final Vehicle newVehicle, double newVehicleDepartureTime, final Driver newDriver, final double bestKnownCosts) { public InsertionData getInsertionData(final VehicleRoute currentRoute, final Job jobToInsert, final Vehicle newVehicle, double newVehicleDepartureTime, final Driver newDriver, final double bestKnownCosts) {
@ -139,8 +137,7 @@ final class ServiceInsertionCalculator implements JobInsertionCostsCalculator{
bestCost = additionalICostsAtRouteLevel + additionalICostsAtActLevel + additionalTransportationCosts; bestCost = additionalICostsAtRouteLevel + additionalICostsAtActLevel + additionalTransportationCosts;
insertionIndex = actIndex; insertionIndex = actIndex;
} }
} } else if (status.equals(ConstraintsStatus.NOT_FULFILLED_BREAK)) {
else if(status.equals(ConstraintsStatus.NOT_FULFILLED_BREAK)){
break; break;
} }
double nextActArrTime = prevActStartTime + transportCosts.getTransportTime(prevAct.getLocation(), nextAct.getLocation(), prevActStartTime, newDriver, newVehicle); double nextActArrTime = prevActStartTime + transportCosts.getTransportTime(prevAct.getLocation(), nextAct.getLocation(), prevActStartTime, newDriver, newVehicle);

View file

@ -45,8 +45,6 @@ import java.util.List;
import java.util.PriorityQueue; import java.util.PriorityQueue;
final class ServiceInsertionOnRouteLevelCalculator implements JobInsertionCostsCalculator { final class ServiceInsertionOnRouteLevelCalculator implements JobInsertionCostsCalculator {
private static final Logger logger = LogManager.getLogger(ServiceInsertionOnRouteLevelCalculator.class); private static final Logger logger = LogManager.getLogger(ServiceInsertionOnRouteLevelCalculator.class);
@ -81,7 +79,7 @@ final class ServiceInsertionOnRouteLevelCalculator implements JobInsertionCostsC
public void setMemorySize(int memorySize) { public void setMemorySize(int memorySize) {
this.memorySize = memorySize; this.memorySize = memorySize;
logger.debug("set [solutionMemory="+memorySize+"]"); logger.debug("set [solutionMemory={}]", memorySize);
} }
public ServiceInsertionOnRouteLevelCalculator(VehicleRoutingTransportCosts vehicleRoutingCosts, VehicleRoutingActivityCosts costFunc, ActivityInsertionCostsCalculator activityInsertionCostsCalculator, HardRouteConstraint hardRouteLevelConstraint, HardActivityConstraint hardActivityLevelConstraint) { public ServiceInsertionOnRouteLevelCalculator(VehicleRoutingTransportCosts vehicleRoutingCosts, VehicleRoutingActivityCosts costFunc, ActivityInsertionCostsCalculator activityInsertionCostsCalculator, HardRouteConstraint hardRouteLevelConstraint, HardActivityConstraint hardActivityLevelConstraint) {
@ -92,7 +90,7 @@ final class ServiceInsertionOnRouteLevelCalculator implements JobInsertionCostsC
this.hardRouteLevelConstraint = hardRouteLevelConstraint; this.hardRouteLevelConstraint = hardRouteLevelConstraint;
this.hardActivityLevelConstraint = hardActivityLevelConstraint; this.hardActivityLevelConstraint = hardActivityLevelConstraint;
auxilliaryPathCostCalculator = new AuxilliaryCostCalculator(transportCosts, activityCosts); auxilliaryPathCostCalculator = new AuxilliaryCostCalculator(transportCosts, activityCosts);
logger.debug("initialise " + this); logger.debug("initialise {}", this);
} }
@ -102,7 +100,7 @@ final class ServiceInsertionOnRouteLevelCalculator implements JobInsertionCostsC
void setNuOfActsForwardLooking(int nOfActsForwardLooking) { void setNuOfActsForwardLooking(int nOfActsForwardLooking) {
this.nuOfActsForwardLooking = nOfActsForwardLooking; this.nuOfActsForwardLooking = nOfActsForwardLooking;
logger.debug("set [forwardLooking="+nOfActsForwardLooking+"]"); logger.debug("set [forwardLooking={}]", nOfActsForwardLooking);
} }
@Override @Override
@ -115,13 +113,13 @@ final class ServiceInsertionOnRouteLevelCalculator implements JobInsertionCostsC
* have local effects but affects the entire route). * have local effects but affects the entire route).
* Calculation is conducted by two steps. In the first step, promising insertion positions are identified by appromiximating their * Calculation is conducted by two steps. In the first step, promising insertion positions are identified by appromiximating their
* marginal insertion cost. In the second step, marginal cost of the best M positions are calculated exactly. * marginal insertion cost. In the second step, marginal cost of the best M positions are calculated exactly.
*
*
*/ */
@Override @Override
public InsertionData getInsertionData(final VehicleRoute currentRoute, final Job jobToInsert, final Vehicle newVehicle, double newVehicleDepartureTime, final Driver newDriver, final double best_known_insertion_costs) { public InsertionData getInsertionData(final VehicleRoute currentRoute, final Job jobToInsert, final Vehicle newVehicle, double newVehicleDepartureTime, final Driver newDriver, final double best_known_insertion_costs) {
if(jobToInsert == null) throw new IllegalStateException("job is null. cannot calculate the insertion of a null-job."); if (jobToInsert == null)
if(newVehicle == null || newVehicle instanceof NoVehicle) throw new IllegalStateException("no vehicle given. set para vehicle!"); throw new IllegalStateException("job is null. cannot calculate the insertion of a null-job.");
if (newVehicle == null || newVehicle instanceof NoVehicle)
throw new IllegalStateException("no vehicle given. set para vehicle!");
JobInsertionContext insertionContext = new JobInsertionContext(currentRoute, jobToInsert, newVehicle, newDriver, newVehicleDepartureTime); JobInsertionContext insertionContext = new JobInsertionContext(currentRoute, jobToInsert, newVehicle, newDriver, newVehicleDepartureTime);
if (!hardRouteLevelConstraint.fulfilled(insertionContext)) { if (!hardRouteLevelConstraint.fulfilled(insertionContext)) {
@ -182,8 +180,7 @@ final class ServiceInsertionOnRouteLevelCalculator implements JobInsertionCostsC
if (insertion_cost_approximation < best_known_insertion_costs) { if (insertion_cost_approximation < best_known_insertion_costs) {
bestInsertionsQueue.add(new InsertionData(insertion_cost_approximation, InsertionData.NO_INDEX, actIndex, newVehicle, newDriver)); bestInsertionsQueue.add(new InsertionData(insertion_cost_approximation, InsertionData.NO_INDEX, actIndex, newVehicle, newDriver));
} }
} } else if (hardActivityConstraintsStatus.equals(ConstraintsStatus.NOT_FULFILLED_BREAK)) {
else if(hardActivityConstraintsStatus.equals(ConstraintsStatus.NOT_FULFILLED_BREAK)){
loopBroken = true; loopBroken = true;
break; break;
} }
@ -250,8 +247,7 @@ final class ServiceInsertionOnRouteLevelCalculator implements JobInsertionCostsC
best_insertion_index = insertion.getDeliveryInsertionIndex(); best_insertion_index = insertion.getDeliveryInsertionIndex();
best_insertion_costs = insertion.getInsertionCost(); best_insertion_costs = insertion.getInsertionCost();
} }
} } else {
else{
for (int i = 0; i < memorySize; i++) { for (int i = 0; i < memorySize; i++) {
InsertionData data = bestInsertionsQueue.poll(); InsertionData data = bestInsertionsQueue.poll();
@ -293,8 +289,7 @@ final class ServiceInsertionOnRouteLevelCalculator implements JobInsertionCostsC
if (start == null) { if (start == null) {
start = new Start(newVehicle.getStartLocation(), newVehicle.getEarliestDeparture(), Double.MAX_VALUE); start = new Start(newVehicle.getStartLocation(), newVehicle.getEarliestDeparture(), Double.MAX_VALUE);
start.setEndTime(newVehicleDepartureTime); start.setEndTime(newVehicleDepartureTime);
} } else {
else{
start.setLocation(Location.newInstance(newVehicle.getStartLocation().getId())); start.setLocation(Location.newInstance(newVehicle.getStartLocation().getId()));
start.setTheoreticalEarliestOperationStartTime(newVehicle.getEarliestDeparture()); start.setTheoreticalEarliestOperationStartTime(newVehicle.getEarliestDeparture());
start.setTheoreticalLatestOperationStartTime(Double.MAX_VALUE); start.setTheoreticalLatestOperationStartTime(Double.MAX_VALUE);
@ -303,8 +298,7 @@ final class ServiceInsertionOnRouteLevelCalculator implements JobInsertionCostsC
if (end == null) { if (end == null) {
end = new End(newVehicle.getEndLocation(), 0.0, newVehicle.getLatestArrival()); end = new End(newVehicle.getEndLocation(), 0.0, newVehicle.getLatestArrival());
} } else {
else{
end.setLocation(Location.newInstance(newVehicle.getEndLocation().getId())); end.setLocation(Location.newInstance(newVehicle.getEndLocation().getId()));
end.setTheoreticalEarliestOperationStartTime(0.0); end.setTheoreticalEarliestOperationStartTime(0.0);
end.setTheoreticalLatestOperationStartTime(newVehicle.getLatestArrival()); end.setTheoreticalLatestOperationStartTime(newVehicle.getLatestArrival());
@ -315,8 +309,7 @@ final class ServiceInsertionOnRouteLevelCalculator implements JobInsertionCostsC
Double prevCost; Double prevCost;
if (act instanceof End) { if (act instanceof End) {
prevCost = stateManager.getRouteState(vehicleRoute, InternalStates.COSTS, Double.class); prevCost = stateManager.getRouteState(vehicleRoute, InternalStates.COSTS, Double.class);
} } else prevCost = stateManager.getActivityState(act, InternalStates.COSTS, Double.class);
else prevCost = stateManager.getActivityState(act, InternalStates.COSTS,Double.class);
if (prevCost == null) prevCost = 0.; if (prevCost == null) prevCost = 0.;
return prevCost; return prevCost;
} }
@ -328,8 +321,7 @@ final class ServiceInsertionOnRouteLevelCalculator implements JobInsertionCostsC
public int compare(InsertionData o1, InsertionData o2) { public int compare(InsertionData o1, InsertionData o2) {
if (o1.getInsertionCost() < o2.getInsertionCost()) { if (o1.getInsertionCost() < o2.getInsertionCost()) {
return -1; return -1;
} } else {
else {
return 1; return 1;
} }

View file

@ -37,8 +37,6 @@ import org.apache.logging.log4j.Logger;
import java.util.List; import java.util.List;
final class ShipmentInsertionCalculator implements JobInsertionCostsCalculator { final class ShipmentInsertionCalculator implements JobInsertionCostsCalculator {
private static final Logger logger = LogManager.getLogger(ShipmentInsertionCalculator.class); private static final Logger logger = LogManager.getLogger(ShipmentInsertionCalculator.class);
@ -68,7 +66,7 @@ final class ShipmentInsertionCalculator implements JobInsertionCostsCalculator{
this.softRouteConstraint = constraintManager; this.softRouteConstraint = constraintManager;
this.transportCosts = routingCosts; this.transportCosts = routingCosts;
additionalAccessEgressCalculator = new AdditionalAccessEgressCalculator(routingCosts); additionalAccessEgressCalculator = new AdditionalAccessEgressCalculator(routingCosts);
logger.debug("initialise " + this); logger.debug("initialise {}", this);
} }
public void setJobActivityFactory(JobActivityFactory activityFactory) { public void setJobActivityFactory(JobActivityFactory activityFactory) {
@ -83,7 +81,6 @@ final class ShipmentInsertionCalculator implements JobInsertionCostsCalculator{
/** /**
* Calculates the marginal cost of inserting job i locally. This is based on the * Calculates the marginal cost of inserting job i locally. This is based on the
* assumption that cost changes can entirely covered by only looking at the predecessor i-1 and its successor i+1. * assumption that cost changes can entirely covered by only looking at the predecessor i-1 and its successor i+1.
*
*/ */
@Override @Override
public InsertionData getInsertionData(final VehicleRoute currentRoute, final Job jobToInsert, final Vehicle newVehicle, double newVehicleDepartureTime, final Driver newDriver, final double bestKnownCosts) { public InsertionData getInsertionData(final VehicleRoute currentRoute, final Job jobToInsert, final Vehicle newVehicle, double newVehicleDepartureTime, final Driver newDriver, final double bestKnownCosts) {
@ -131,12 +128,11 @@ final class ShipmentInsertionCalculator implements JobInsertionCostsCalculator{
TourActivity nextAct; TourActivity nextAct;
if (i < activities.size()) { if (i < activities.size()) {
nextAct = activities.get(i); nextAct = activities.get(i);
} } else {
else{
nextAct = end; nextAct = end;
tourEnd = true; tourEnd = true;
} }
// logger.info("activity: " + i + ", act-size: " + activities.size()); // logger.info("activity: {}, act-size: {}", i, activities.size());
ConstraintsStatus pickupShipmentConstraintStatus = hardActivityLevelConstraint.fulfilled(insertionContext, prevAct, pickupShipment, nextAct, prevActEndTime); ConstraintsStatus pickupShipmentConstraintStatus = hardActivityLevelConstraint.fulfilled(insertionContext, prevAct, pickupShipment, nextAct, prevActEndTime);
if (pickupShipmentConstraintStatus.equals(ConstraintsStatus.NOT_FULFILLED)) { if (pickupShipmentConstraintStatus.equals(ConstraintsStatus.NOT_FULFILLED)) {
double nextActArrTime = prevActEndTime + transportCosts.getTransportTime(prevAct.getLocation(), nextAct.getLocation(), prevActEndTime, newDriver, newVehicle); double nextActArrTime = prevActEndTime + transportCosts.getTransportTime(prevAct.getLocation(), nextAct.getLocation(), prevActEndTime, newDriver, newVehicle);
@ -144,8 +140,7 @@ final class ShipmentInsertionCalculator implements JobInsertionCostsCalculator{
prevAct = nextAct; prevAct = nextAct;
i++; i++;
continue; continue;
} } else if (pickupShipmentConstraintStatus.equals(ConstraintsStatus.NOT_FULFILLED_BREAK)) {
else if(pickupShipmentConstraintStatus.equals(ConstraintsStatus.NOT_FULFILLED_BREAK)){
break; break;
} }
double additionalPickupICosts = softActivityConstraint.getCosts(insertionContext, prevAct, pickupShipment, nextAct, prevActEndTime); double additionalPickupICosts = softActivityConstraint.getCosts(insertionContext, prevAct, pickupShipment, nextAct, prevActEndTime);
@ -174,8 +169,7 @@ final class ShipmentInsertionCalculator implements JobInsertionCostsCalculator{
TourActivity nextAct_deliveryLoop; TourActivity nextAct_deliveryLoop;
if (j < activities.size()) { if (j < activities.size()) {
nextAct_deliveryLoop = activities.get(j); nextAct_deliveryLoop = activities.get(j);
} } else {
else{
nextAct_deliveryLoop = end; nextAct_deliveryLoop = end;
tourEnd_deliveryLoop = true; tourEnd_deliveryLoop = true;
} }
@ -191,8 +185,7 @@ final class ShipmentInsertionCalculator implements JobInsertionCostsCalculator{
pickupInsertionIndex = i; pickupInsertionIndex = i;
deliveryInsertionIndex = j; deliveryInsertionIndex = j;
} }
} } else if (deliverShipmentConstraintStatus.equals(ConstraintsStatus.NOT_FULFILLED_BREAK)) {
else if(deliverShipmentConstraintStatus.equals(ConstraintsStatus.NOT_FULFILLED_BREAK)){
break; break;
} }
//update prevAct and endTime //update prevAct and endTime

View file

@ -54,8 +54,7 @@ public class VariableTransportCostCalculator implements SoftActivityConstraint{
if (iFacts.getRoute().isEmpty()) { if (iFacts.getRoute().isEmpty()) {
double tp_costs_prevAct_nextAct = routingCosts.getTransportCost(prevAct.getLocation(), nextAct.getLocation(), depTimeAtPrevAct, iFacts.getNewDriver(), iFacts.getNewVehicle()); double tp_costs_prevAct_nextAct = routingCosts.getTransportCost(prevAct.getLocation(), nextAct.getLocation(), depTimeAtPrevAct, iFacts.getNewDriver(), iFacts.getNewVehicle());
oldCosts = tp_costs_prevAct_nextAct; oldCosts = tp_costs_prevAct_nextAct;
} } else {
else{
double tp_costs_prevAct_nextAct = routingCosts.getTransportCost(prevAct.getLocation(), nextAct.getLocation(), prevAct.getEndTime(), iFacts.getRoute().getDriver(), iFacts.getRoute().getVehicle()); double tp_costs_prevAct_nextAct = routingCosts.getTransportCost(prevAct.getLocation(), nextAct.getLocation(), prevAct.getEndTime(), iFacts.getRoute().getDriver(), iFacts.getRoute().getVehicle());
oldCosts = tp_costs_prevAct_nextAct; oldCosts = tp_costs_prevAct_nextAct;
} }

View file

@ -47,11 +47,10 @@ final class VehicleTypeDependentJobInsertionCalculator implements JobInsertionCo
/** /**
* true if a vehicle(-type) is allowed to take over the whole route that was previously served by another vehicle * true if a vehicle(-type) is allowed to take over the whole route that was previously served by another vehicle
* * <p/>
* <p>vehicleSwitch allowed makes sense if fleet consists of vehicles with different capacities such that one * <p>vehicleSwitch allowed makes sense if fleet consists of vehicles with different capacities such that one
* can start with a small vehicle, but as the number of customers grows bigger vehicles can be operated, i.e. * can start with a small vehicle, but as the number of customers grows bigger vehicles can be operated, i.e.
* bigger vehicles can take over the route that was previously served by a small vehicle. * bigger vehicles can take over the route that was previously served by a small vehicle.
*
*/ */
private boolean vehicleSwitchAllowed = false; private boolean vehicleSwitchAllowed = false;
@ -104,14 +103,13 @@ final class VehicleTypeDependentJobInsertionCalculator implements JobInsertionCo
if (vehicleSwitchAllowed && !isVehicleWithInitialRoute(selectedVehicle)) { if (vehicleSwitchAllowed && !isVehicleWithInitialRoute(selectedVehicle)) {
relevantVehicles.addAll(fleetManager.getAvailableVehicles(selectedVehicle)); relevantVehicles.addAll(fleetManager.getAvailableVehicles(selectedVehicle));
} }
} } else { //if no vehicle has been assigned, i.e. it is an empty route
else{ //if no vehicle has been assigned, i.e. it is an empty route
relevantVehicles.addAll(fleetManager.getAvailableVehicles()); relevantVehicles.addAll(fleetManager.getAvailableVehicles());
} }
for (Vehicle v : relevantVehicles) { for (Vehicle v : relevantVehicles) {
double depTime = v.getEarliestDeparture(); double depTime;
// if(v == selectedVehicle) depTime = currentRoute.getDepartureTime(); if (v == selectedVehicle) depTime = currentRoute.getDepartureTime();
// else depTime = v.getEarliestDeparture(); else depTime = v.getEarliestDeparture();
InsertionData iData = insertionCalculator.getInsertionData(currentRoute, jobToInsert, v, depTime, selectedDriver, bestKnownCost_); InsertionData iData = insertionCalculator.getInsertionData(currentRoute, jobToInsert, v, depTime, selectedDriver, bestKnownCost_);
if (iData instanceof NoInsertionFound) { if (iData instanceof NoInsertionFound) {
continue; continue;

View file

@ -21,7 +21,6 @@ import jsprit.core.problem.solution.route.VehicleRoute;
import java.util.Collection; import java.util.Collection;
public interface InsertionEndsListener extends InsertionListener { public interface InsertionEndsListener extends InsertionListener {
public void informInsertionEnds(Collection<VehicleRoute> vehicleRoutes); public void informInsertionEnds(Collection<VehicleRoute> vehicleRoutes);

View file

@ -19,11 +19,7 @@ package jsprit.core.algorithm.recreate.listener;
import jsprit.core.algorithm.listener.SearchStrategyModuleListener; import jsprit.core.algorithm.listener.SearchStrategyModuleListener;
public interface InsertionListener extends SearchStrategyModuleListener { public interface InsertionListener extends SearchStrategyModuleListener {
} }

View file

@ -22,7 +22,6 @@ import jsprit.core.problem.solution.route.VehicleRoute;
import java.util.Collection; import java.util.Collection;
public interface InsertionStartsListener extends InsertionListener { public interface InsertionStartsListener extends InsertionListener {
public void informInsertionStarts(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs); public void informInsertionStarts(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs);

View file

@ -20,10 +20,6 @@ import jsprit.core.problem.job.Job;
import jsprit.core.problem.solution.route.VehicleRoute; import jsprit.core.problem.solution.route.VehicleRoute;
public interface JobInsertedListener extends InsertionListener { public interface JobInsertedListener extends InsertionListener {
public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime); public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime);

View file

@ -63,7 +63,7 @@ public abstract class AbstractRuinStrategy implements RuinStrategy{
public Collection<Job> ruin(Collection<VehicleRoute> vehicleRoutes) { public Collection<Job> ruin(Collection<VehicleRoute> vehicleRoutes) {
ruinListeners.ruinStarts(vehicleRoutes); ruinListeners.ruinStarts(vehicleRoutes);
Collection<Job> unassigned = ruinRoutes(vehicleRoutes); Collection<Job> unassigned = ruinRoutes(vehicleRoutes);
logger.trace("ruin: " + "[ruined=" + unassigned.size() + "]"); logger.trace("ruin: [ruined={}]", unassigned.size());
ruinListeners.ruinEnds(vehicleRoutes, unassigned); ruinListeners.ruinEnds(vehicleRoutes, unassigned);
return unassigned; return unassigned;
} }
@ -116,7 +116,7 @@ public abstract class AbstractRuinStrategy implements RuinStrategy{
if (jobIsInitial(job)) return false; if (jobIsInitial(job)) return false;
boolean removed = route.getTourActivities().removeJob(job); boolean removed = route.getTourActivities().removeJob(job);
if (removed) { if (removed) {
logger.trace("ruin: " + job.getId()); logger.trace("ruin: {}", job.getId());
ruinListeners.removed(job, route); ruinListeners.removed(job, route);
return true; return true;
} }

View file

@ -26,7 +26,7 @@ class JobNeighborhoodsImpl implements JobNeighborhoods {
super(); super();
this.vrp = vrp; this.vrp = vrp;
this.jobDistance = jobDistance; this.jobDistance = jobDistance;
logger.debug("intialise " + this); logger.debug("intialise {}", this);
} }
@Override @Override
@ -86,8 +86,8 @@ class JobNeighborhoodsImpl implements JobNeighborhoods {
} }
stopWatch.stop(); stopWatch.stop();
logger.debug("preprocessing comp-time: " + stopWatch + "; nuOfDistances stored: " + nuOfDistancesStored + "; estimated memory: " + logger.debug("preprocessing comp-time: {}; nuOfDistances stored: {}; estimated memory: {}" +
(distanceNodeTree.keySet().size()*64+nuOfDistancesStored*92) + " bytes"); " bytes", stopWatch, nuOfDistancesStored, (distanceNodeTree.keySet().size() * 64 + nuOfDistancesStored * 92));
} }
} }

View file

@ -29,7 +29,7 @@ class JobNeighborhoodsImplWithCapRestriction implements JobNeighborhoods {
this.vrp = vrp; this.vrp = vrp;
this.jobDistance = jobDistance; this.jobDistance = jobDistance;
this.capacity = capacity; this.capacity = capacity;
logger.debug("intialise " + this); logger.debug("intialise {}", this);
} }
@Override @Override
@ -59,7 +59,7 @@ class JobNeighborhoodsImplWithCapRestriction implements JobNeighborhoods {
@Override @Override
public void initialise() { public void initialise() {
logger.debug("calculates distances from EACH job to EACH job --> n^2="+Math.pow(vrp.getJobs().values().size(), 2) + " calculations, but 'only' "+(vrp.getJobs().values().size()*capacity)+ " are cached."); logger.debug("calculates distances from EACH job to EACH job --> n^2={} calculations, but 'only' {} are cached.", Math.pow(vrp.getJobs().values().size(), 2), (vrp.getJobs().values().size() * capacity));
if (capacity == 0) return; if (capacity == 0) return;
calculateDistancesFromJob2Job(); calculateDistancesFromJob2Job();
} }
@ -89,8 +89,7 @@ class JobNeighborhoodsImplWithCapRestriction implements JobNeighborhoods {
if (treeSet.size() < capacity) { if (treeSet.size() < capacity) {
treeSet.add(refNode); treeSet.add(refNode);
nuOfDistancesStored++; nuOfDistancesStored++;
} } else {
else{
if (treeSet.last().getDistance() > distance) { if (treeSet.last().getDistance() > distance) {
treeSet.pollLast(); treeSet.pollLast();
treeSet.add(refNode); treeSet.add(refNode);
@ -101,8 +100,8 @@ class JobNeighborhoodsImplWithCapRestriction implements JobNeighborhoods {
} }
stopWatch.stop(); stopWatch.stop();
logger.debug("preprocessing comp-time: " + stopWatch + "; nuOfDistances stored: " + nuOfDistancesStored + "; estimated memory: " + logger.debug("preprocessing comp-time: {}; nuOfDistances stored: {}; estimated memory: {}" +
(distanceNodeTree.keySet().size()*64+nuOfDistancesStored*92) + " bytes"); " bytes", stopWatch, nuOfDistancesStored, (distanceNodeTree.keySet().size() * 64 + nuOfDistancesStored * 92));
} }
@Override @Override

View file

@ -29,7 +29,8 @@ class NearestNeighborhoodIterator implements Iterator<Job> {
public boolean hasNext() { public boolean hasNext() {
if (jobCount < nJobs) { if (jobCount < nJobs) {
boolean hasNext = jobIter.hasNext(); boolean hasNext = jobIter.hasNext();
if(!hasNext) log.warn("more jobs are requested then iterator can iterate over. probably the number of neighbors memorized in JobNeighborhoods is too small"); if (!hasNext)
log.warn("more jobs are requested then iterator can iterate over. probably the number of neighbors memorized in JobNeighborhoods is too small");
return hasNext; return hasNext;
} }
return false; return false;

View file

@ -35,7 +35,6 @@ import java.util.*;
* customer are removed randomly from current solution. * customer are removed randomly from current solution.
* *
* @author stefan schroeder * @author stefan schroeder
*
*/ */
public final class RuinClusters extends AbstractRuinStrategy implements IterationStartsListener { public final class RuinClusters extends AbstractRuinStrategy implements IterationStartsListener {
@ -87,7 +86,7 @@ public final class RuinClusters extends AbstractRuinStrategy implements Iteratio
} }
}); });
this.jobNeighborhoods = jobNeighborhoods; this.jobNeighborhoods = jobNeighborhoods;
logger.debug("initialise " + this); logger.debug("initialise {}", this);
} }
public void setNoClusters(int noClusters) { public void setNoClusters(int noClusters) {
@ -96,7 +95,7 @@ public final class RuinClusters extends AbstractRuinStrategy implements Iteratio
/** /**
* Removes a fraction of jobs from vehicleRoutes. * Removes a fraction of jobs from vehicleRoutes.
* * <p/>
* <p>The number of jobs is calculated as follows: Math.ceil(vrp.getJobs().values().size() * fractionOfAllNodes2beRuined). * <p>The number of jobs is calculated as follows: Math.ceil(vrp.getJobs().values().size() * fractionOfAllNodes2beRuined).
*/ */
@Override @Override
@ -116,6 +115,7 @@ public final class RuinClusters extends AbstractRuinStrategy implements Iteratio
} }
private void ruin(Collection<VehicleRoute> vehicleRoutes, int nOfJobs2BeRemoved, List<Job> unassignedJobs) { private void ruin(Collection<VehicleRoute> vehicleRoutes, int nOfJobs2BeRemoved, List<Job> unassignedJobs) {
if (vrp.getJobs().values().size() == 0) return;
Map<Job, VehicleRoute> mappedRoutes = map(vehicleRoutes); Map<Job, VehicleRoute> mappedRoutes = map(vehicleRoutes);
int toRemove = nOfJobs2BeRemoved; int toRemove = nOfJobs2BeRemoved;
@ -129,8 +129,7 @@ public final class RuinClusters extends AbstractRuinStrategy implements Iteratio
if (lastRemoved.isEmpty()) { if (lastRemoved.isEmpty()) {
target = RandomUtils.nextJob(vrp.getJobs().values(), random); target = RandomUtils.nextJob(vrp.getJobs().values(), random);
targetRoute = mappedRoutes.get(target); targetRoute = mappedRoutes.get(target);
} } else {
else{
target = RandomUtils.nextJob(lastRemoved, random); target = RandomUtils.nextJob(lastRemoved, random);
Iterator<Job> neighborIterator = jobNeighborhoods.getNearestNeighborsIterator(nOfJobs2BeRemoved, target); Iterator<Job> neighborIterator = jobNeighborhoods.getNearestNeighborsIterator(nOfJobs2BeRemoved, target);
while (neighborIterator.hasNext()) { while (neighborIterator.hasNext()) {

View file

@ -28,13 +28,11 @@ import java.util.*;
/** /**
*
* RuinStrategy that ruins the neighborhood of a randomly selected job. The size and the structure of the neighborhood is defined by * RuinStrategy that ruins the neighborhood of a randomly selected job. The size and the structure of the neighborhood is defined by
* the share of jobs to be removed and the distance between jobs (where distance not necessarily mean Euclidean distance but an arbitrary * the share of jobs to be removed and the distance between jobs (where distance not necessarily mean Euclidean distance but an arbitrary
* measure). * measure).
* *
* @author stefan * @author stefan
*
*/ */
public final class RuinRadial extends AbstractRuinStrategy { public final class RuinRadial extends AbstractRuinStrategy {
@ -68,7 +66,7 @@ public final class RuinRadial extends AbstractRuinStrategy {
JobNeighborhoodsImplWithCapRestriction jobNeighborhoodsImpl = new JobNeighborhoodsImplWithCapRestriction(vrp, jobDistance, noJobsToMemorize); JobNeighborhoodsImplWithCapRestriction jobNeighborhoodsImpl = new JobNeighborhoodsImplWithCapRestriction(vrp, jobDistance, noJobsToMemorize);
jobNeighborhoodsImpl.initialise(); jobNeighborhoodsImpl.initialise();
jobNeighborhoods = jobNeighborhoodsImpl; jobNeighborhoods = jobNeighborhoodsImpl;
logger.debug("initialise " + this); logger.debug("initialise {}", this);
} }
public RuinRadial(VehicleRoutingProblem vrp, int noJobs2beRemoved, JobDistance jobDistance) { public RuinRadial(VehicleRoutingProblem vrp, int noJobs2beRemoved, JobDistance jobDistance) {
@ -87,7 +85,7 @@ public final class RuinRadial extends AbstractRuinStrategy {
JobNeighborhoodsImplWithCapRestriction jobNeighborhoodsImpl = new JobNeighborhoodsImplWithCapRestriction(vrp, jobDistance, noJobsToMemorize); JobNeighborhoodsImplWithCapRestriction jobNeighborhoodsImpl = new JobNeighborhoodsImplWithCapRestriction(vrp, jobDistance, noJobsToMemorize);
jobNeighborhoodsImpl.initialise(); jobNeighborhoodsImpl.initialise();
jobNeighborhoods = jobNeighborhoodsImpl; jobNeighborhoods = jobNeighborhoodsImpl;
logger.debug("initialise " + this); logger.debug("initialise {}", this);
} }
public RuinRadial(VehicleRoutingProblem vrp, int noJobs2beRemoved, JobNeighborhoods neighborhoods) { public RuinRadial(VehicleRoutingProblem vrp, int noJobs2beRemoved, JobNeighborhoods neighborhoods) {
@ -103,7 +101,7 @@ public final class RuinRadial extends AbstractRuinStrategy {
}; };
jobNeighborhoods = neighborhoods; jobNeighborhoods = neighborhoods;
logger.debug("initialise " + this); logger.debug("initialise {}", this);
} }
@Override @Override
@ -130,6 +128,7 @@ public final class RuinRadial extends AbstractRuinStrategy {
/** /**
* Removes targetJob and its neighborhood and returns the removed jobs. * Removes targetJob and its neighborhood and returns the removed jobs.
*
* @deprecated will be private * @deprecated will be private
*/ */
@Deprecated @Deprecated

View file

@ -27,13 +27,11 @@ import java.util.*;
/** /**
*
* RuinStrategy that ruins the neighborhood of a randomly selected job. The size and the structure of the neighborhood is defined by * RuinStrategy that ruins the neighborhood of a randomly selected job. The size and the structure of the neighborhood is defined by
* the share of jobs to be removed and the distance between jobs (where distance not necessarily mean Euclidean distance but an arbitrary * the share of jobs to be removed and the distance between jobs (where distance not necessarily mean Euclidean distance but an arbitrary
* measure). * measure).
* *
* @author stefan * @author stefan
*
*/ */
public final class RuinRadialMultipleCenters extends AbstractRuinStrategy { public final class RuinRadialMultipleCenters extends AbstractRuinStrategy {
@ -62,7 +60,7 @@ public final class RuinRadialMultipleCenters extends AbstractRuinStrategy {
JobNeighborhoodsImplWithCapRestriction jobNeighborhoodsImpl = new JobNeighborhoodsImplWithCapRestriction(vrp, jobDistance, noJobsToMemorize); JobNeighborhoodsImplWithCapRestriction jobNeighborhoodsImpl = new JobNeighborhoodsImplWithCapRestriction(vrp, jobDistance, noJobsToMemorize);
jobNeighborhoodsImpl.initialise(); jobNeighborhoodsImpl.initialise();
jobNeighborhoods = jobNeighborhoodsImpl; jobNeighborhoods = jobNeighborhoodsImpl;
logger.debug("initialise " + this); logger.debug("initialise {}", this);
} }
public void setNumberOfRuinCenters(int noCenters) { public void setNumberOfRuinCenters(int noCenters) {
@ -100,6 +98,7 @@ public final class RuinRadialMultipleCenters extends AbstractRuinStrategy {
/** /**
* Removes targetJob and its neighborhood and returns the removed jobs. * Removes targetJob and its neighborhood and returns the removed jobs.
*
* @deprecated will be private * @deprecated will be private
*/ */
@Deprecated @Deprecated
@ -129,8 +128,7 @@ public final class RuinRadialMultipleCenters extends AbstractRuinStrategy {
for (Job j : available) { for (Job j : available) {
if (i >= randomIndex) { if (i >= randomIndex) {
return j; return j;
} } else i++;
else i++;
} }
return null; return null;
} }

View file

@ -33,7 +33,6 @@ import java.util.List;
* customer are removed randomly from current solution. * customer are removed randomly from current solution.
* *
* @author stefan schroeder * @author stefan schroeder
*
*/ */
public final class RuinRandom extends AbstractRuinStrategy { public final class RuinRandom extends AbstractRuinStrategy {
@ -60,12 +59,12 @@ public final class RuinRandom extends AbstractRuinStrategy {
return selectNuOfJobs2BeRemoved(); return selectNuOfJobs2BeRemoved();
} }
}); });
logger.debug("initialise " + this); logger.debug("initialise {}", this);
} }
/** /**
* Removes a fraction of jobs from vehicleRoutes. * Removes a fraction of jobs from vehicleRoutes.
* * <p/>
* <p>The number of jobs is calculated as follows: Math.ceil(vrp.getJobs().values().size() * fractionOfAllNodes2beRuined). * <p>The number of jobs is calculated as follows: Math.ceil(vrp.getJobs().values().size() * fractionOfAllNodes2beRuined).
*/ */
@Override @Override

View file

@ -23,13 +23,8 @@ import jsprit.core.problem.solution.route.VehicleRoute;
import java.util.Collection; import java.util.Collection;
/** /**
*
* @author stefan schroeder * @author stefan schroeder
*
*/ */
public interface RuinStrategy { public interface RuinStrategy {

View file

@ -34,7 +34,6 @@ import java.util.*;
* customer are removed randomly from current solution. * customer are removed randomly from current solution.
* *
* @author stefan schroeder * @author stefan schroeder
*
*/ */
public final class RuinWorst extends AbstractRuinStrategy { public final class RuinWorst extends AbstractRuinStrategy {
@ -64,12 +63,12 @@ public final class RuinWorst extends AbstractRuinStrategy {
return initialNumberJobsToRemove; return initialNumberJobsToRemove;
} }
}); });
logger.debug("initialise " + this); logger.debug("initialise {}", this);
} }
/** /**
* Removes a fraction of jobs from vehicleRoutes. * Removes a fraction of jobs from vehicleRoutes.
* * <p/>
* <p>The number of jobs is calculated as follows: Math.ceil(vrp.getJobs().values().size() * fractionOfAllNodes2beRuined). * <p>The number of jobs is calculated as follows: Math.ceil(vrp.getJobs().values().size() * fractionOfAllNodes2beRuined).
*/ */
@Override @Override
@ -120,8 +119,7 @@ public final class RuinWorst extends AbstractRuinStrategy {
Job job = ((TourActivity.JobActivity) actToEval).getJob(); Job job = ((TourActivity.JobActivity) actToEval).getJob();
if (!savingsMap.containsKey(job)) { if (!savingsMap.containsKey(job)) {
savingsMap.put(job, savings); savingsMap.put(job, savings);
} } else {
else {
double s = savingsMap.get(job); double s = savingsMap.get(job);
savingsMap.put(job, s + savings); savingsMap.put(job, s + savings);
} }
@ -132,8 +130,7 @@ public final class RuinWorst extends AbstractRuinStrategy {
Job job = ((TourActivity.JobActivity) actToEval).getJob(); Job job = ((TourActivity.JobActivity) actToEval).getJob();
if (!savingsMap.containsKey(job)) { if (!savingsMap.containsKey(job)) {
savingsMap.put(job, savings); savingsMap.put(job, savings);
} } else {
else {
double s = savingsMap.get(job); double s = savingsMap.get(job);
savingsMap.put(job, s + savings); savingsMap.put(job, s + savings);
} }

View file

@ -24,14 +24,12 @@ import jsprit.core.problem.job.Shipment;
import jsprit.core.util.EuclideanDistanceCalculator; import jsprit.core.util.EuclideanDistanceCalculator;
/** /**
* Calculator that calculates average distance between two jobs based on the input-transport costs. * Calculator that calculates average distance between two jobs based on the input-transport costs.
* * <p/>
* <p>If the distance between two jobs cannot be calculated with input-transport costs, it tries the euclidean distance between these jobs. * <p>If the distance between two jobs cannot be calculated with input-transport costs, it tries the euclidean distance between these jobs.
* *
* @author stefan schroeder * @author stefan schroeder
*
*/ */
public class AvgServiceAndShipmentDistance implements JobDistance { public class AvgServiceAndShipmentDistance implements JobDistance {
@ -45,7 +43,7 @@ public class AvgServiceAndShipmentDistance implements JobDistance {
/** /**
* Calculates and returns the average distance between two jobs based on the input-transport costs. * Calculates and returns the average distance between two jobs based on the input-transport costs.
* * <p/>
* <p>If the distance between two jobs cannot be calculated with input-transport costs, it tries the euclidean distance between these jobs. * <p>If the distance between two jobs cannot be calculated with input-transport costs, it tries the euclidean distance between these jobs.
*/ */
@Override @Override
@ -54,17 +52,13 @@ public class AvgServiceAndShipmentDistance implements JobDistance {
if (i instanceof Service && j instanceof Service) { if (i instanceof Service && j instanceof Service) {
return calcDist((Service) i, (Service) j); return calcDist((Service) i, (Service) j);
} } else if (i instanceof Service && j instanceof Shipment) {
else if(i instanceof Service && j instanceof Shipment){
return calcDist((Service) i, (Shipment) j); return calcDist((Service) i, (Shipment) j);
} } else if (i instanceof Shipment && j instanceof Service) {
else if(i instanceof Shipment && j instanceof Service){
return calcDist((Service) j, (Shipment) i); return calcDist((Service) j, (Shipment) i);
} } else if (i instanceof Shipment && j instanceof Shipment) {
else if(i instanceof Shipment && j instanceof Shipment){
return calcDist((Shipment) i, (Shipment) j); return calcDist((Shipment) i, (Shipment) j);
} } else {
else{
throw new IllegalStateException("this supports only shipments or services"); throw new IllegalStateException("this supports only shipments or services");
} }
} }
@ -90,8 +84,7 @@ public class AvgServiceAndShipmentDistance implements JobDistance {
private double calcDist(Location location_i, Location location_j) { private double calcDist(Location location_i, Location location_j) {
try { try {
return costs.getTransportCost(location_i, location_j, 0.0, null, null); return costs.getTransportCost(location_i, location_j, 0.0, null, null);
} } catch (IllegalStateException e) {
catch(IllegalStateException e){
// now try the euclidean distance between these two services // now try the euclidean distance between these two services
} }
return EuclideanDistanceCalculator.calculateDistance(location_i.getCoordinate(), location_j.getCoordinate()); return EuclideanDistanceCalculator.calculateDistance(location_i.getCoordinate(), location_j.getCoordinate());

View file

@ -21,14 +21,12 @@ import jsprit.core.problem.job.Job;
import jsprit.core.problem.job.Service; import jsprit.core.problem.job.Service;
/** /**
* Calculator that calculates average distance between two jobs based on the input-transport costs. * Calculator that calculates average distance between two jobs based on the input-transport costs.
* * <p/>
* <p>If the distance between two jobs cannot be calculated with input-transport costs, it tries the euclidean distance between these jobs. * <p>If the distance between two jobs cannot be calculated with input-transport costs, it tries the euclidean distance between these jobs.
* *
* @author stefan schroeder * @author stefan schroeder
*
*/ */
public class AvgServiceDistance implements JobDistance { public class AvgServiceDistance implements JobDistance {
@ -42,7 +40,7 @@ public class AvgServiceDistance implements JobDistance {
/** /**
* Calculates and returns the average distance between two jobs based on the input-transport costs. * Calculates and returns the average distance between two jobs based on the input-transport costs.
* * <p/>
* <p>If the distance between two jobs cannot be calculated with input-transport costs, it tries the euclidean distance between these jobs. * <p>If the distance between two jobs cannot be calculated with input-transport costs, it tries the euclidean distance between these jobs.
*/ */
@Override @Override
@ -68,8 +66,7 @@ public class AvgServiceDistance implements JobDistance {
try { try {
distance = costs.getTransportCost(s_i.getLocation(), s_j.getLocation(), 0.0, null, null); distance = costs.getTransportCost(s_i.getLocation(), s_j.getLocation(), 0.0, null, null);
return distance; return distance;
} } catch (IllegalStateException e) {
catch(IllegalStateException e){
// now try the euclidean distance between these two services // now try the euclidean distance between these two services
} }
EuclideanServiceDistance euclidean = new EuclideanServiceDistance(); EuclideanServiceDistance euclidean = new EuclideanServiceDistance();

View file

@ -35,7 +35,8 @@ public class EuclideanServiceDistance implements JobDistance {
} else { } else {
Service s_i = (Service) i; Service s_i = (Service) i;
Service s_j = (Service) j; Service s_j = (Service) j;
if(s_i.getLocation().getCoordinate() == null || s_j.getLocation().getCoordinate() == null) throw new IllegalStateException("cannot calculate euclidean distance. since service coords are missing"); if (s_i.getLocation().getCoordinate() == null || s_j.getLocation().getCoordinate() == null)
throw new IllegalStateException("cannot calculate euclidean distance. since service coords are missing");
avgCost = EuclideanDistanceCalculator.calculateDistance(s_i.getLocation().getCoordinate(), s_j.getLocation().getCoordinate()); avgCost = EuclideanDistanceCalculator.calculateDistance(s_i.getLocation().getCoordinate(), s_j.getLocation().getCoordinate());
} }
} else { } else {

View file

@ -19,7 +19,6 @@ package jsprit.core.algorithm.ruin.distance;
import jsprit.core.problem.job.Job; import jsprit.core.problem.job.Job;
public interface JobDistance { public interface JobDistance {
public double getDistance(Job i, Job j); public double getDistance(Job i, Job j);

View file

@ -29,7 +29,6 @@ import java.util.Collection;
* Listener that listens to the ruin-process. It informs whoever is interested about start, end and about a removal of a job. * Listener that listens to the ruin-process. It informs whoever is interested about start, end and about a removal of a job.
* *
* @author schroeder * @author schroeder
*
*/ */
public interface RuinListener extends SearchStrategyModuleListener { public interface RuinListener extends SearchStrategyModuleListener {

View file

@ -1,4 +1,3 @@
/******************************************************************************* /*******************************************************************************
* Copyright (C) 2014 Stefan Schroeder * Copyright (C) 2014 Stefan Schroeder
* *

View file

@ -21,9 +21,6 @@ import jsprit.core.problem.solution.VehicleRoutingProblemSolution;
import java.util.Collection; import java.util.Collection;
public class SelectBest implements SolutionSelector { public class SelectBest implements SolutionSelector {
private static SelectBest selector = null; private static SelectBest selector = null;
@ -44,8 +41,7 @@ public class SelectBest implements SolutionSelector{
if (bestSolution == null) { if (bestSolution == null) {
bestSolution = sol; bestSolution = sol;
minCost = sol.getCost(); minCost = sol.getCost();
} } else if (sol.getCost() < minCost) {
else if(sol.getCost() < minCost){
bestSolution = sol; bestSolution = sol;
minCost = sol.getCost(); minCost = sol.getCost();
} }

View file

@ -25,8 +25,6 @@ import java.util.List;
import java.util.Random; import java.util.Random;
public class SelectRandomly implements SolutionSelector { public class SelectRandomly implements SolutionSelector {
private static SelectRandomly selector = null; private static SelectRandomly selector = null;

View file

@ -21,7 +21,6 @@ import jsprit.core.problem.solution.VehicleRoutingProblemSolution;
import java.util.Collection; import java.util.Collection;
public interface SolutionSelector { public interface SolutionSelector {
public VehicleRoutingProblemSolution selectSolution(Collection<VehicleRoutingProblemSolution> solutions); public VehicleRoutingProblemSolution selectSolution(Collection<VehicleRoutingProblemSolution> solutions);

View file

@ -1,4 +1,3 @@
/******************************************************************************* /*******************************************************************************
* Copyright (C) 2014 Stefan Schroeder * Copyright (C) 2014 Stefan Schroeder
* *
@ -50,4 +49,6 @@ public class InternalStates {
public static final StateId FUTURE_WAITING = new StateFactory.StateIdImpl("future_waiting", 13); public static final StateId FUTURE_WAITING = new StateFactory.StateIdImpl("future_waiting", 13);
public static final StateId EARLIEST_WITHOUT_WAITING = new StateFactory.StateIdImpl("earliest_without_waiting", 14); public static final StateId EARLIEST_WITHOUT_WAITING = new StateFactory.StateIdImpl("earliest_without_waiting", 14);
public static final StateId SWITCH_NOT_FEASIBLE = new StateFactory.StateIdImpl("switch_not_feasible", 15);
} }

View file

@ -13,7 +13,9 @@ class StateFactory {
static StateId createId(String name) { static StateId createId(String name) {
if(reservedIds.contains(name)){ throwReservedIdException(name); } if (reservedIds.contains(name)) {
throwReservedIdException(name);
}
return new StateIdImpl(name, -1); return new StateIdImpl(name, -1);
} }
@ -41,7 +43,9 @@ class StateFactory {
private int index; private int index;
public int getIndex(){ return index; } public int getIndex() {
return index;
}
/* (non-Javadoc) /* (non-Javadoc)
* @see java.lang.Object#hashCode() * @see java.lang.Object#hashCode()

View file

@ -37,12 +37,11 @@ import java.util.*;
/** /**
* Manages states. * Manages states.
* * <p/>
* <p>Some condition, rules or constraints are stateful. This StateManager manages these states, i.e. it offers * <p>Some condition, rules or constraints are stateful. This StateManager manages these states, i.e. it offers
* methods to add, store and retrieve states based on the problem, vehicle-routes and tour-activities. * methods to add, store and retrieve states based on the problem, vehicle-routes and tour-activities.
* *
* @author schroeder * @author schroeder
*
*/ */
public class StateManager implements RouteAndActivityStateGetter, IterationStartsListener, RuinListener, InsertionStartsListener, JobInsertedListener, InsertionEndsListener { public class StateManager implements RouteAndActivityStateGetter, IterationStartsListener, RuinListener, InsertionStartsListener, JobInsertedListener, InsertionEndsListener {
@ -109,13 +108,16 @@ public class StateManager implements RouteAndActivityStateGetter, IterationStart
private VehicleRoutingProblem vrp; private VehicleRoutingProblem vrp;
int getMaxIndexOfVehicleTypeIdentifiers(){ return nuVehicleTypeKeys; } int getMaxIndexOfVehicleTypeIdentifiers() {
return nuVehicleTypeKeys;
}
/** /**
* Create and returns a stateId with the specified state-name. * Create and returns a stateId with the specified state-name.
* * <p/>
* <p>If a stateId with the specified name has already been created, it returns the created stateId.</p> * <p>If a stateId with the specified name has already been created, it returns the created stateId.</p>
* <p>If the specified is equal to a name that is already used internally, it throws an IllegalStateException</p> * <p>If the specified is equal to a name that is already used internally, it throws an IllegalStateException</p>
*
* @param name the specified name of the state * @param name the specified name of the state
* @return the stateId with which a state can be identified, no matter if it is a problem, route or activity state. * @return the stateId with which a state can be identified, no matter if it is a problem, route or activity state.
* @throws java.lang.IllegalStateException if name of state is already used internally * @throws java.lang.IllegalStateException if name of state is already used internally
@ -194,7 +196,6 @@ public class StateManager implements RouteAndActivityStateGetter, IterationStart
/** /**
* Clears all states, i.e. set all value to null. * Clears all states, i.e. set all value to null.
*
*/ */
public void clear() { public void clear() {
fill_twoDimArr(activity_states, null); fill_twoDimArr(activity_states, null);
@ -239,8 +240,7 @@ public class StateManager implements RouteAndActivityStateGetter, IterationStart
T state; T state;
try { try {
state = type.cast(activity_states[act.getIndex()][stateId.getIndex()]); state = type.cast(activity_states[act.getIndex()][stateId.getIndex()]);
} } catch (ClassCastException e) {
catch (ClassCastException e){
throw getClassCastException(e, stateId, type.toString(), activity_states[act.getIndex()][stateId.getIndex()].getClass().toString()); throw getClassCastException(e, stateId, type.toString(), activity_states[act.getIndex()][stateId.getIndex()].getClass().toString());
} }
return state; return state;
@ -264,6 +264,7 @@ public class StateManager implements RouteAndActivityStateGetter, IterationStart
* Returns the associated state value to the specified activity, vehicle and stateId, or null if no state value is * Returns the associated state value to the specified activity, vehicle and stateId, or null if no state value is
* associated. * associated.
* <p>If type class is not equal to the associated type class of the requested state value, it throws a ClassCastException.</p> * <p>If type class is not equal to the associated type class of the requested state value, it throws a ClassCastException.</p>
*
* @param act the activity for which a state value is associated to * @param act the activity for which a state value is associated to
* @param vehicle the vehicle for which a state value is associated to * @param vehicle the vehicle for which a state value is associated to
* @param stateId the stateId which is the associated key to the problem state * @param stateId the stateId which is the associated key to the problem state
@ -280,8 +281,7 @@ public class StateManager implements RouteAndActivityStateGetter, IterationStart
T state; T state;
try { try {
state = type.cast(vehicle_dependent_activity_states[act.getIndex()][vehicle.getVehicleTypeIdentifier().getIndex()][stateId.getIndex()]); state = type.cast(vehicle_dependent_activity_states[act.getIndex()][vehicle.getVehicleTypeIdentifier().getIndex()][stateId.getIndex()]);
} } catch (ClassCastException e) {
catch(ClassCastException e){
Object state_class = vehicle_dependent_activity_states[act.getIndex()][vehicle.getVehicleTypeIdentifier().getIndex()][stateId.getIndex()]; Object state_class = vehicle_dependent_activity_states[act.getIndex()][vehicle.getVehicleTypeIdentifier().getIndex()][stateId.getIndex()];
throw getClassCastException(e, stateId, type.toString(), state_class.getClass().toString()); throw getClassCastException(e, stateId, type.toString(), state_class.getClass().toString());
} }
@ -316,8 +316,7 @@ public class StateManager implements RouteAndActivityStateGetter, IterationStart
state = type.cast(route_state_map.get(route)[stateId.getIndex()]); state = type.cast(route_state_map.get(route)[stateId.getIndex()]);
} }
// state = type.cast(route_states[index_of_first_act][stateId.getIndex()]); // state = type.cast(route_states[index_of_first_act][stateId.getIndex()]);
} } catch (ClassCastException e) {
catch (ClassCastException e){
throw getClassCastException(e, stateId, type.toString(), route_state_map.get(route)[stateId.getIndex()].getClass().toString()); throw getClassCastException(e, stateId, type.toString(), route_state_map.get(route)[stateId.getIndex()].getClass().toString());
// throw getClassCastException(e,stateId,type.toString(),route_states[index_of_first_act][stateId.getIndex()].getClass().toString()); // throw getClassCastException(e,stateId,type.toString(),route_states[index_of_first_act][stateId.getIndex()].getClass().toString());
} }
@ -342,6 +341,7 @@ public class StateManager implements RouteAndActivityStateGetter, IterationStart
/** /**
* Returns the route state that is assigned to the specified route, vehicle and stateId. * Returns the route state that is assigned to the specified route, vehicle and stateId.
* <p>Returns null if no state can be found</p> * <p>Returns null if no state can be found</p>
*
* @param route the route for which the state is requested * @param route the route for which the state is requested
* @param vehicle the vehicle for which the state is requested * @param vehicle the vehicle for which the state is requested
* @param stateId the stateId(entifier) for the state that is requested * @param stateId the stateId(entifier) for the state that is requested
@ -361,8 +361,7 @@ public class StateManager implements RouteAndActivityStateGetter, IterationStart
state = type.cast(vehicle_dependent_route_state_map.get(route)[vehicle.getVehicleTypeIdentifier().getIndex()][stateId.getIndex()]); state = type.cast(vehicle_dependent_route_state_map.get(route)[vehicle.getVehicleTypeIdentifier().getIndex()][stateId.getIndex()]);
} }
// state = type.cast(vehicle_dependent_route_states[index_of_first_act][vehicle.getVehicleTypeIdentifier().getIndex()][stateId.getIndex()]); // state = type.cast(vehicle_dependent_route_states[index_of_first_act][vehicle.getVehicleTypeIdentifier().getIndex()][stateId.getIndex()]);
} } catch (ClassCastException e) {
catch( ClassCastException e){
throw getClassCastException(e, stateId, type.toString(), vehicle_dependent_route_state_map.get(route)[vehicle.getVehicleTypeIdentifier().getIndex()][stateId.getIndex()].getClass().toString()); throw getClassCastException(e, stateId, type.toString(), vehicle_dependent_route_state_map.get(route)[vehicle.getVehicleTypeIdentifier().getIndex()][stateId.getIndex()].getClass().toString());
} }
return state; return state;
@ -378,11 +377,11 @@ public class StateManager implements RouteAndActivityStateGetter, IterationStart
* @param <T> the type of the state * @param <T> the type of the state
* @throws java.lang.IllegalStateException if <code>act.getIndex() == 0</code> * @throws java.lang.IllegalStateException if <code>act.getIndex() == 0</code>
* || stateId.getIndex < noInternalStates * || stateId.getIndex < noInternalStates
*
*/ */
public <T> void putActivityState(TourActivity act, StateId stateId, T state) { public <T> void putActivityState(TourActivity act, StateId stateId, T state) {
if (act.getIndex() == 0) throw new IllegalStateException("activity index is 0. this should not be."); if (act.getIndex() == 0) throw new IllegalStateException("activity index is 0. this should not be.");
if(stateId.getIndex() < initialNoStates) throw new IllegalStateException("either you use a reserved stateId that is applied\n" + if (stateId.getIndex() < initialNoStates)
throw new IllegalStateException("either you use a reserved stateId that is applied\n" +
"internally or your stateId has been created without index, e.g. StateFactory.createId(stateName)\n" + "internally or your stateId has been created without index, e.g. StateFactory.createId(stateName)\n" +
" does not assign indeces thus do not use it anymore, but use\n " + " does not assign indeces thus do not use it anymore, but use\n " +
"stateManager.createStateId(name)\n" + "stateManager.createStateId(name)\n" +
@ -404,7 +403,8 @@ public class StateManager implements RouteAndActivityStateGetter, IterationStart
*/ */
public <T> void putActivityState(TourActivity act, Vehicle vehicle, StateId stateId, T state) { public <T> void putActivityState(TourActivity act, Vehicle vehicle, StateId stateId, T state) {
if (act.getIndex() == 0) throw new IllegalStateException("activity index is 0. this should not be."); if (act.getIndex() == 0) throw new IllegalStateException("activity index is 0. this should not be.");
if(stateId.getIndex() < initialNoStates) throw new IllegalStateException("either you use a reserved stateId that is applied\n" + if (stateId.getIndex() < initialNoStates)
throw new IllegalStateException("either you use a reserved stateId that is applied\n" +
"internally or your stateId has been created without index, e.g. StateFactory.createId(stateName)\n" + "internally or your stateId has been created without index, e.g. StateFactory.createId(stateName)\n" +
" does not assign indeces thus do not use it anymore, but use\n " + " does not assign indeces thus do not use it anymore, but use\n " +
"stateManager.createStateId(name)\n" + "stateManager.createStateId(name)\n" +
@ -472,11 +472,11 @@ public class StateManager implements RouteAndActivityStateGetter, IterationStart
/** /**
* Adds state updater. * Adds state updater.
* * <p/>
* <p>Note that a state update occurs if route and/or activity states have changed, i.e. if jobs are removed * <p>Note that a state update occurs if route and/or activity states have changed, i.e. if jobs are removed
* or inserted into a route. Thus here, it is assumed that a state updater is either of type InsertionListener, * or inserted into a route. Thus here, it is assumed that a state updater is either of type InsertionListener,
* RuinListener, ActivityVisitor, ReverseActivityVisitor, RouteVisitor, ReverseRouteVisitor. * RuinListener, ActivityVisitor, ReverseActivityVisitor, RouteVisitor, ReverseRouteVisitor.
* * <p/>
* <p>The following rule pertain for activity/route visitors:These visitors visits all activities/route in a route subsequently in two cases. First, if insertionStart (after ruinStrategies have removed activities from routes) * <p>The following rule pertain for activity/route visitors:These visitors visits all activities/route in a route subsequently in two cases. First, if insertionStart (after ruinStrategies have removed activities from routes)
* and, second, if a job has been inserted and thus if a route has changed. * and, second, if a job has been inserted and thus if a route has changed.
* *
@ -543,7 +543,9 @@ public class StateManager implements RouteAndActivityStateGetter, IterationStart
public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) { public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) {
// log.debug("insert " + job2insert + " in " + inRoute); // log.debug("insert " + job2insert + " in " + inRoute);
insertionListeners.informJobInserted(job2insert, inRoute, additionalCosts, additionalTime); insertionListeners.informJobInserted(job2insert, inRoute, additionalCosts, additionalTime);
for(RouteVisitor v : routeVisitors){ v.visit(inRoute); } for (RouteVisitor v : routeVisitors) {
v.visit(inRoute);
}
routeActivityVisitor.visit(inRoute); routeActivityVisitor.visit(inRoute);
revRouteActivityVisitor.visit(inRoute); revRouteActivityVisitor.visit(inRoute);
} }
@ -552,7 +554,9 @@ public class StateManager implements RouteAndActivityStateGetter, IterationStart
public void informInsertionStarts(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs) { public void informInsertionStarts(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs) {
insertionListeners.informInsertionStarts(vehicleRoutes, unassignedJobs); insertionListeners.informInsertionStarts(vehicleRoutes, unassignedJobs);
for (VehicleRoute route : vehicleRoutes) { for (VehicleRoute route : vehicleRoutes) {
for(RouteVisitor v : routeVisitors){ v.visit(route); } for (RouteVisitor v : routeVisitors) {
v.visit(route);
}
routeActivityVisitor.visit(route); routeActivityVisitor.visit(route);
revRouteActivityVisitor.visit(route); revRouteActivityVisitor.visit(route);
} }

View file

@ -25,11 +25,10 @@ import jsprit.core.util.ActivityTimeTracker;
/** /**
* Updates arrival and end times of activities. * Updates arrival and end times of activities.
* * <p/>
* <p>Note that this modifies arrTime and endTime of each activity in a route. * <p>Note that this modifies arrTime and endTime of each activity in a route.
* *
* @author stefan * @author stefan
*
*/ */
public class UpdateActivityTimes implements ActivityVisitor, StateUpdater { public class UpdateActivityTimes implements ActivityVisitor, StateUpdater {
@ -39,15 +38,12 @@ public class UpdateActivityTimes implements ActivityVisitor, StateUpdater{
/** /**
* Updates arrival and end times of activities. * Updates arrival and end times of activities.
* * <p/>
* <p>Note that this modifies arrTime and endTime of each activity in a route. * <p>Note that this modifies arrTime and endTime of each activity in a route.
* * <p/>
* <p>ArrTimes and EndTimes can be retrieved by <br> * <p>ArrTimes and EndTimes can be retrieved by <br>
* <code>activity.getArrTime()</code> and * <code>activity.getArrTime()</code> and
* <code>activity.getEndTime()</code> * <code>activity.getEndTime()</code>
*
*
*
*/ */
public UpdateActivityTimes(ForwardTransportTime transportTime) { public UpdateActivityTimes(ForwardTransportTime transportTime) {
super(); super();

View file

@ -39,7 +39,4 @@ public class UpdateEndLocationIfRouteIsOpen implements StateUpdater, RouteVisito
} }
} }

View file

@ -33,13 +33,12 @@ import java.util.Collection;
/** /**
* Updates load at start and end of route as well as at each activity. And update is triggered when either * Updates load at start and end of route as well as at each activity. And update is triggered when either
* activityVisitor has been started, the insertion process has been started or a job has been inserted. * activityVisitor has been started, the insertion process has been started or a job has been inserted.
* * <p/>
* <p>Note that this only works properly if you register this class as ActivityVisitor AND InsertionStartsListener AND JobInsertedListener. * <p>Note that this only works properly if you register this class as ActivityVisitor AND InsertionStartsListener AND JobInsertedListener.
* The reason behind is that activity states are dependent on route-level states and vice versa. If this is properly registered, * The reason behind is that activity states are dependent on route-level states and vice versa. If this is properly registered,
* this dependency is solved automatically. * this dependency is solved automatically.
* *
* @author stefan * @author stefan
*
*/ */
class UpdateLoads implements ActivityVisitor, StateUpdater, InsertionStartsListener, JobInsertedListener { class UpdateLoads implements ActivityVisitor, StateUpdater, InsertionStartsListener, JobInsertedListener {
@ -86,8 +85,7 @@ class UpdateLoads implements ActivityVisitor, StateUpdater, InsertionStartsListe
for (Job j : route.getTourActivities().getJobs()) { for (Job j : route.getTourActivities().getJobs()) {
if (j instanceof Delivery) { if (j instanceof Delivery) {
loadAtDepot = Capacity.addup(loadAtDepot, j.getSize()); loadAtDepot = Capacity.addup(loadAtDepot, j.getSize());
} } else if (j instanceof Pickup || j instanceof Service) {
else if(j instanceof Pickup || j instanceof Service){
loadAtEnd = Capacity.addup(loadAtEnd, j.getSize()); loadAtEnd = Capacity.addup(loadAtEnd, j.getSize());
} }
} }
@ -97,7 +95,9 @@ class UpdateLoads implements ActivityVisitor, StateUpdater, InsertionStartsListe
@Override @Override
public void informInsertionStarts(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs) { public void informInsertionStarts(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs) {
for(VehicleRoute route : vehicleRoutes){ insertionStarts(route); } for (VehicleRoute route : vehicleRoutes) {
insertionStarts(route);
}
} }
@Override @Override
@ -106,8 +106,7 @@ class UpdateLoads implements ActivityVisitor, StateUpdater, InsertionStartsListe
Capacity loadAtDepot = stateManager.getRouteState(inRoute, InternalStates.LOAD_AT_BEGINNING, Capacity.class); Capacity loadAtDepot = stateManager.getRouteState(inRoute, InternalStates.LOAD_AT_BEGINNING, Capacity.class);
if (loadAtDepot == null) loadAtDepot = defaultValue; if (loadAtDepot == null) loadAtDepot = defaultValue;
stateManager.putTypedInternalRouteState(inRoute, InternalStates.LOAD_AT_BEGINNING, Capacity.addup(loadAtDepot, job2insert.getSize())); stateManager.putTypedInternalRouteState(inRoute, InternalStates.LOAD_AT_BEGINNING, Capacity.addup(loadAtDepot, job2insert.getSize()));
} } else if (job2insert instanceof Pickup || job2insert instanceof Service) {
else if(job2insert instanceof Pickup || job2insert instanceof Service){
Capacity loadAtEnd = stateManager.getRouteState(inRoute, InternalStates.LOAD_AT_END, Capacity.class); Capacity loadAtEnd = stateManager.getRouteState(inRoute, InternalStates.LOAD_AT_END, Capacity.class);
if (loadAtEnd == null) loadAtEnd = defaultValue; if (loadAtEnd == null) loadAtEnd = defaultValue;
stateManager.putTypedInternalRouteState(inRoute, InternalStates.LOAD_AT_END, Capacity.addup(loadAtEnd, job2insert.getSize())); stateManager.putTypedInternalRouteState(inRoute, InternalStates.LOAD_AT_END, Capacity.addup(loadAtEnd, job2insert.getSize()));

View file

@ -26,7 +26,6 @@ import jsprit.core.problem.solution.route.activity.TourActivity;
* i.e. the maximum capacity utilization at previous activities. * i.e. the maximum capacity utilization at previous activities.
* *
* @author schroeder * @author schroeder
*
*/ */
class UpdateMaxCapacityUtilisationAtActivitiesByLookingBackwardInRoute implements ActivityVisitor, StateUpdater { class UpdateMaxCapacityUtilisationAtActivitiesByLookingBackwardInRoute implements ActivityVisitor, StateUpdater {
@ -59,5 +58,6 @@ class UpdateMaxCapacityUtilisationAtActivitiesByLookingBackwardInRoute implement
} }
@Override @Override
public void finish() {} public void finish() {
}
} }

View file

@ -24,7 +24,7 @@ import jsprit.core.problem.solution.route.activity.TourActivity;
/** /**
* A {@link ReverseActivityVisitor} that looks forward in the vehicle route and determines * A {@link ReverseActivityVisitor} that looks forward in the vehicle route and determines
* the maximum capacity utilization (in terms of loads) at subsequent activities. * the maximum capacity utilization (in terms of loads) at subsequent activities.
* * <p/>
* <p>Assume a vehicle route with the following activity sequence {start,pickup(1,4),delivery(2,3),pickup(3,2),end} where * <p>Assume a vehicle route with the following activity sequence {start,pickup(1,4),delivery(2,3),pickup(3,2),end} where
* pickup(1,2) = pickup(id,cap-demand).<br> * pickup(1,2) = pickup(id,cap-demand).<br>
* Future maxLoad for each activity are calculated as follows:<br> * Future maxLoad for each activity are calculated as follows:<br>
@ -36,9 +36,7 @@ import jsprit.core.problem.solution.route.activity.TourActivity;
* activity (apart from start and end), the maximum capacity is determined when forward looking into the route. * activity (apart from start and end), the maximum capacity is determined when forward looking into the route.
* That is at each activity we know how much capacity is available whithout breaking future capacity constraints. * That is at each activity we know how much capacity is available whithout breaking future capacity constraints.
* *
*
* @author schroeder * @author schroeder
*
*/ */
class UpdateMaxCapacityUtilisationAtActivitiesByLookingForwardInRoute implements ReverseActivityVisitor, StateUpdater { class UpdateMaxCapacityUtilisationAtActivitiesByLookingForwardInRoute implements ReverseActivityVisitor, StateUpdater {
@ -72,5 +70,6 @@ class UpdateMaxCapacityUtilisationAtActivitiesByLookingForwardInRoute implements
} }
@Override @Override
public void finish() {} public void finish() {
}
} }

View file

@ -25,14 +25,13 @@ import jsprit.core.problem.solution.route.activity.TourActivity;
/** /**
* Updates load at activity level. * Updates load at activity level.
* * <p/>
* <p>Note that this assumes that StateTypes.LOAD_AT_DEPOT is already updated, i.e. it starts by setting loadAtDepot to StateTypes.LOAD_AT_DEPOT. * <p>Note that this assumes that StateTypes.LOAD_AT_DEPOT is already updated, i.e. it starts by setting loadAtDepot to StateTypes.LOAD_AT_DEPOT.
* If StateTypes.LOAD_AT_DEPOT is not set, it starts with 0 load at depot. * If StateTypes.LOAD_AT_DEPOT is not set, it starts with 0 load at depot.
* * <p/>
* <p>Thus it DEPENDS on StateTypes.LOAD_AT_DEPOT * <p>Thus it DEPENDS on StateTypes.LOAD_AT_DEPOT
* *
* @author stefan * @author stefan
*
*/ */
class UpdateMaxCapacityUtilisationAtRoute implements ActivityVisitor, StateUpdater { class UpdateMaxCapacityUtilisationAtRoute implements ActivityVisitor, StateUpdater {

View file

@ -25,7 +25,6 @@ import jsprit.core.problem.solution.route.activity.TourActivity;
* Updates and memorizes latest operation start times at activities. * Updates and memorizes latest operation start times at activities.
* *
* @author schroeder * @author schroeder
*
*/ */
class UpdatePracticalTimeWindows implements ReverseActivityVisitor, StateUpdater { class UpdatePracticalTimeWindows implements ReverseActivityVisitor, StateUpdater {
@ -64,5 +63,6 @@ class UpdatePracticalTimeWindows implements ReverseActivityVisitor, StateUpdater
} }
@Override @Override
public void finish() {} public void finish() {
}
} }

View file

@ -27,10 +27,9 @@ import jsprit.core.util.ActivityTimeTracker;
/** /**
* Updates total costs (i.e. transport and activity costs) at route and activity level. * Updates total costs (i.e. transport and activity costs) at route and activity level.
* * <p/>
* <p>Thus it modifies <code>stateManager.getRouteState(route, StateTypes.COSTS)</code> and <br> * <p>Thus it modifies <code>stateManager.getRouteState(route, StateTypes.COSTS)</code> and <br>
* <code>stateManager.getActivityState(activity, StateTypes.COSTS)</code> * <code>stateManager.getActivityState(activity, StateTypes.COSTS)</code>
*
*/ */
public class UpdateVariableCosts implements ActivityVisitor, StateUpdater { public class UpdateVariableCosts implements ActivityVisitor, StateUpdater {
@ -52,11 +51,10 @@ public class UpdateVariableCosts implements ActivityVisitor,StateUpdater{
/** /**
* Updates total costs (i.e. transport and activity costs) at route and activity level. * Updates total costs (i.e. transport and activity costs) at route and activity level.
* * <p/>
* <p>Thus it modifies <code>stateManager.getRouteState(route, StateTypes.COSTS)</code> and <br> * <p>Thus it modifies <code>stateManager.getRouteState(route, StateTypes.COSTS)</code> and <br>
* <code>stateManager.getActivityState(activity, StateTypes.COSTS)</code> * <code>stateManager.getActivityState(activity, StateTypes.COSTS)</code>
* *
*
* @param activityCost * @param activityCost
* @param transportCost * @param transportCost
* @param states * @param states

View file

@ -97,6 +97,9 @@ public class UpdateVehicleDependentPracticalTimeWindows implements RouteVisitor,
double potentialLatestArrivalTimeAtCurrAct = latestArrTimeAtPrevAct - transportCosts.getBackwardTransportTime(activity.getLocation(), prevLocation, double potentialLatestArrivalTimeAtCurrAct = latestArrTimeAtPrevAct - transportCosts.getBackwardTransportTime(activity.getLocation(), prevLocation,
latestArrTimeAtPrevAct, route.getDriver(), vehicle) - activity.getOperationTime(); latestArrTimeAtPrevAct, route.getDriver(), vehicle) - activity.getOperationTime();
double latestArrivalTime = Math.min(activity.getTheoreticalLatestOperationStartTime(), potentialLatestArrivalTimeAtCurrAct); double latestArrivalTime = Math.min(activity.getTheoreticalLatestOperationStartTime(), potentialLatestArrivalTimeAtCurrAct);
if(latestArrivalTime < activity.getTheoreticalEarliestOperationStartTime()){
stateManager.putTypedInternalRouteState(route,vehicle,InternalStates.SWITCH_NOT_FEASIBLE,true);
}
stateManager.putInternalTypedActivityState(activity, vehicle, InternalStates.LATEST_OPERATION_START_TIME, latestArrivalTime); stateManager.putInternalTypedActivityState(activity, vehicle, InternalStates.LATEST_OPERATION_START_TIME, latestArrivalTime);
latest_arrTimes_at_prevAct[vehicle.getVehicleTypeIdentifier().getIndex()] = latestArrivalTime; latest_arrTimes_at_prevAct[vehicle.getVehicleTypeIdentifier().getIndex()] = latestArrivalTime;
location_of_prevAct[vehicle.getVehicleTypeIdentifier().getIndex()] = activity.getLocation(); location_of_prevAct[vehicle.getVehicleTypeIdentifier().getIndex()] = activity.getLocation();
@ -104,7 +107,8 @@ public class UpdateVehicleDependentPracticalTimeWindows implements RouteVisitor,
} }
public void finish() {} public void finish() {
}
} }

View file

@ -22,13 +22,12 @@ import org.apache.logging.log4j.Logger;
/** /**
* Terminates algorithm prematurely based on iterations without any improvement (i.e. new solution acceptance). * Terminates algorithm prematurely based on iterations without any improvement (i.e. new solution acceptance).
* * <p/>
* <p>Termination will be activated by:<br> * <p>Termination will be activated by:<br>
* * <p/>
* <code>algorithm.setPrematureAlgorithmTermination(this);</code><br> * <code>algorithm.setPrematureAlgorithmTermination(this);</code><br>
* *
* @author stefan schroeder * @author stefan schroeder
*
*/ */
public class IterationWithoutImprovementTermination implements PrematureAlgorithmTermination { public class IterationWithoutImprovementTermination implements PrematureAlgorithmTermination {

Some files were not shown because too many files have changed in this diff Show more