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>
@ -28,7 +29,7 @@
</goals> </goals>
</pluginExecutionFilter> </pluginExecutionFilter>
<action> <action>
<ignore /> <ignore/>
</action> </action>
</pluginExecution> </pluginExecution>
</pluginExecutions> </pluginExecutions>
@ -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

@ -89,11 +89,10 @@ public class AlgorithmEventsRecorder implements RuinListener, IterationStartsLis
File dgsFile = new File(dgsFileLocation); File dgsFile = new File(dgsFileLocation);
fos = new FileOutputStream(dgsFile); fos = new FileOutputStream(dgsFile);
fileSink = new FileSinkDGS(); fileSink = new FileSinkDGS();
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);
@ -109,37 +108,37 @@ public class AlgorithmEventsRecorder implements RuinListener, IterationStartsLis
new AlgorithmEventsRecorder(vrp, dgsFileLocation); new AlgorithmEventsRecorder(vrp, dgsFileLocation);
} }
public void setRecordingRange(int startIteration, int endIteration){ public void setRecordingRange(int startIteration, int endIteration) {
this.start_recording_at = startIteration; this.start_recording_at = startIteration;
this.end_recording_at = endIteration; this.end_recording_at = endIteration;
} }
@Override @Override
public void ruinStarts(Collection<VehicleRoute> routes) { public void ruinStarts(Collection<VehicleRoute> routes) {
if(!record()) return; if (!record()) return;
fileSink.stepBegins(graph.getId(),0,BEFORE_RUIN_RENDER_SOLUTION); fileSink.stepBegins(graph.getId(), 0, BEFORE_RUIN_RENDER_SOLUTION);
markAllNodesAsInserted(); markAllNodesAsInserted();
addRoutes(routes); addRoutes(routes);
fileSink.stepBegins(graph.getId(),0,RUIN); fileSink.stepBegins(graph.getId(), 0, RUIN);
} }
private void markAllNodesAsInserted() { private void markAllNodesAsInserted() {
for(Job j : vrp.getJobs().values()){ for (Job j : vrp.getJobs().values()) {
markInserted(j); markInserted(j);
} }
} }
private void addRoutes(Collection<VehicleRoute> routes) { private void addRoutes(Collection<VehicleRoute> routes) {
for(VehicleRoute route : routes){ for (VehicleRoute route : routes) {
String prevNode = makeStartId(route.getVehicle()); String prevNode = makeStartId(route.getVehicle());
for(TourActivity act : route.getActivities()){ for (TourActivity act : route.getActivities()) {
String actNodeId = getNodeId(act); String actNodeId = getNodeId(act);
addEdge(prevNode+"_"+actNodeId,prevNode,actNodeId); addEdge(prevNode + "_" + actNodeId, prevNode, actNodeId);
prevNode = actNodeId; prevNode = actNodeId;
} }
if(route.getVehicle().isReturnToDepot()) { if (route.getVehicle().isReturnToDepot()) {
String lastNode = makeEndId(route.getVehicle()); String lastNode = makeEndId(route.getVehicle());
addEdge(prevNode+"_"+lastNode,prevNode,lastNode); addEdge(prevNode + "_" + lastNode, prevNode, lastNode);
} }
} }
@ -147,13 +146,12 @@ public class AlgorithmEventsRecorder implements RuinListener, IterationStartsLis
private String getNodeId(TourActivity act) { private String getNodeId(TourActivity act) {
String nodeId = null; String nodeId = null;
if(act instanceof TourActivity.JobActivity){ if (act instanceof TourActivity.JobActivity) {
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);
} }
} }
@ -171,28 +169,29 @@ public class AlgorithmEventsRecorder implements RuinListener, IterationStartsLis
@Override @Override
public void removed(Job job, VehicleRoute fromRoute) { public void removed(Job job, VehicleRoute fromRoute) {
if(!record()) return; if (!record()) return;
if(job instanceof Service) removeService(job, fromRoute); if (job instanceof Service) removeService(job, fromRoute);
else if(job instanceof Shipment) removeShipment(job,fromRoute); else if (job instanceof Shipment) removeShipment(job, fromRoute);
} }
private void removeShipment(Job job, VehicleRoute fromRoute) { private void removeShipment(Job job, VehicleRoute fromRoute) {
Shipment shipment = (Shipment)job; Shipment shipment = (Shipment) job;
String fromNodeId = getFromNodeId(shipment); String fromNodeId = getFromNodeId(shipment);
String toNodeId = getToNodeId(shipment); String toNodeId = getToNodeId(shipment);
// removeNodeAndBelongingEdges(fromNodeId,fromRoute); // removeNodeAndBelongingEdges(fromNodeId,fromRoute);
// removeNodeAndBelongingEdges(toNodeId,fromRoute); // removeNodeAndBelongingEdges(toNodeId,fromRoute);
Edge enteringToNode = getEnteringEdge(toNodeId); Edge enteringToNode = getEnteringEdge(toNodeId);
if(enteringToNode.getNode0().getId().equals(fromNodeId)){ if (enteringToNode.getNode0().getId().equals(fromNodeId)) {
markRemoved(graph.getNode(fromNodeId)); markRemoved(graph.getNode(fromNodeId));
markRemoved(graph.getNode(toNodeId)); markRemoved(graph.getNode(toNodeId));
// i -> from -> to -> j: rem(i,from), rem(from,to), rem(to,j), add(i,j) // i -> from -> to -> j: rem(i,from), rem(from,to), rem(to,j), add(i,j)
Edge enteringFromNode = getEnteringEdge(fromNodeId); Edge enteringFromNode = getEnteringEdge(fromNodeId);
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;
} }
@ -200,22 +199,23 @@ public class AlgorithmEventsRecorder implements RuinListener, IterationStartsLis
removeEdge(leavingToNode.getId()); removeEdge(leavingToNode.getId());
Node from = enteringFromNode.getNode0(); Node from = enteringFromNode.getNode0();
Node to = leavingToNode.getNode1(); Node to = leavingToNode.getNode1();
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);
} }
} }
private Edge getLeavingEdge(String toNodeId) { private Edge getLeavingEdge(String toNodeId) {
Collection<Edge> edges = graph.getNode(toNodeId).getLeavingEdgeSet(); Collection<Edge> edges = graph.getNode(toNodeId).getLeavingEdgeSet();
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;
} }
} }
@ -224,10 +224,12 @@ public class AlgorithmEventsRecorder implements RuinListener, IterationStartsLis
private Edge getEnteringEdge(String toNodeId) { private Edge getEnteringEdge(String toNodeId) {
Collection<Edge> enteringEdges = graph.getNode(toNodeId).getEnteringEdgeSet(); Collection<Edge> enteringEdges = graph.getNode(toNodeId).getEnteringEdgeSet();
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;
} }
} }
@ -253,8 +255,8 @@ public class AlgorithmEventsRecorder implements RuinListener, IterationStartsLis
Edge entering = getEnteringEdge(nodeId); Edge entering = getEnteringEdge(nodeId);
removeEdge(entering.getId()); removeEdge(entering.getId());
if(node.getLeavingEdgeSet().isEmpty()){ if (node.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;
} }
@ -262,13 +264,13 @@ public class AlgorithmEventsRecorder implements RuinListener, IterationStartsLis
removeEdge((leaving.getId())); removeEdge((leaving.getId()));
Node from = entering.getNode0(); Node from = entering.getNode0();
Node to = leaving.getNode1(); Node to = leaving.getNode1();
if(!fromRoute.getActivities().isEmpty()){ if (!fromRoute.getActivities().isEmpty()) {
addEdge(makeEdgeId(from,to),from.getId(),to.getId()); addEdge(makeEdgeId(from, to), from.getId(), to.getId());
} }
} }
private void markRemoved(Node node) { private void markRemoved(Node node) {
node.setAttribute("ui.class","removed"); node.setAttribute("ui.class", "removed");
} }
private String makeEdgeId(Node from, Node to) { private String makeEdgeId(Node from, Node to) {
@ -278,7 +280,7 @@ public class AlgorithmEventsRecorder implements RuinListener, IterationStartsLis
@Override @Override
public void informAlgorithmEnds(VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions) { public void informAlgorithmEnds(VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions) {
VehicleRoutingProblemSolution solution = Solutions.bestOf(solutions); VehicleRoutingProblemSolution solution = Solutions.bestOf(solutions);
fileSink.stepBegins(graph.getId(),0,BEFORE_RUIN_RENDER_SOLUTION); fileSink.stepBegins(graph.getId(), 0, BEFORE_RUIN_RENDER_SOLUTION);
addRoutes(solution.getRoutes()); addRoutes(solution.getRoutes());
finish(); finish();
} }
@ -287,7 +289,7 @@ public class AlgorithmEventsRecorder implements RuinListener, IterationStartsLis
try { try {
fileSink.end(); fileSink.end();
fos.close(); fos.close();
if(gzipOs != null) gzipOs.close(); if (gzipOs != null) gzipOs.close();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -299,28 +301,27 @@ public class AlgorithmEventsRecorder implements RuinListener, IterationStartsLis
} }
private void initialiseGraph(VehicleRoutingProblem problem) { private void initialiseGraph(VehicleRoutingProblem problem) {
for(Vehicle vehicle : problem.getVehicles()){ for (Vehicle vehicle : problem.getVehicles()) {
addVehicle(vehicle); addVehicle(vehicle);
} }
for(Job job : problem.getJobs().values()){ for (Job job : problem.getJobs().values()) {
addJob(job); addJob(job);
} }
} }
private void addJob(Job job) { private void addJob(Job job) {
if(job instanceof Service){ if (job instanceof Service) {
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());
String toNodeId = getToNodeId(shipment); String toNodeId = getToNodeId(shipment);
addNode(toNodeId,shipment.getDeliveryLocation().getCoordinate()); addNode(toNodeId, shipment.getDeliveryLocation().getCoordinate());
markShipment(shipment); markShipment(shipment);
if(renderShipments) { if (renderShipments) {
Edge e = graph.addEdge("shipment_" + fromNodeId + "_" + toNodeId, fromNodeId, toNodeId, true); Edge e = graph.addEdge("shipment_" + fromNodeId + "_" + toNodeId, fromNodeId, toNodeId, true);
e.addAttribute("ui.class", "shipment"); e.addAttribute("ui.class", "shipment");
} }
@ -333,35 +334,34 @@ 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());
} }
} }
private void markPickup(String id) { private void markPickup(String id) {
graph.getNode(id).addAttribute("ui.class","pickup"); graph.getNode(id).addAttribute("ui.class", "pickup");
} }
private void markDelivery(String id) { private void markDelivery(String id) {
graph.getNode(id).addAttribute("ui.class","delivery"); graph.getNode(id).addAttribute("ui.class", "delivery");
} }
private void addVehicle(Vehicle vehicle) { private void addVehicle(Vehicle vehicle) {
String startId = makeStartId(vehicle); String startId = makeStartId(vehicle);
Node node = graph.addNode(startId); Node node = graph.addNode(startId);
node.addAttribute("x",vehicle.getStartLocation().getCoordinate().getX()); node.addAttribute("x", vehicle.getStartLocation().getCoordinate().getX());
node.addAttribute("y", vehicle.getStartLocation().getCoordinate().getY()); node.addAttribute("y", vehicle.getStartLocation().getCoordinate().getY());
node.addAttribute("ui.class","depot"); node.addAttribute("ui.class", "depot");
String endId = makeEndId(vehicle); String endId = makeEndId(vehicle);
if(!startId.equals(endId)){ if (!startId.equals(endId)) {
Node endNode = graph.addNode(endId); Node endNode = graph.addNode(endId);
endNode.addAttribute("x", vehicle.getEndLocation().getCoordinate().getX()); endNode.addAttribute("x", vehicle.getEndLocation().getCoordinate().getX());
endNode.addAttribute("y", vehicle.getEndLocation().getCoordinate().getY()); endNode.addAttribute("y", vehicle.getEndLocation().getCoordinate().getY());
endNode.addAttribute("ui.class","depot"); endNode.addAttribute("ui.class", "depot");
} }
} }
@ -370,7 +370,7 @@ public class AlgorithmEventsRecorder implements RuinListener, IterationStartsLis
} }
private String makeEndId(Vehicle vehicle) { private String makeEndId(Vehicle vehicle) {
if(vehicle.getStartLocation().getId().equals(vehicle.getEndLocation().getId())) return makeStartId(vehicle); if (vehicle.getStartLocation().getId().equals(vehicle.getEndLocation().getId())) return makeStartId(vehicle);
return vehicle.getId() + "_end"; return vehicle.getId() + "_end";
} }
@ -382,20 +382,20 @@ public class AlgorithmEventsRecorder implements RuinListener, IterationStartsLis
@Override @Override
public void informInsertionEnds(Collection<VehicleRoute> vehicleRoutes) { public void informInsertionEnds(Collection<VehicleRoute> vehicleRoutes) {
if(!record()) return; if (!record()) return;
fileSink.stepBegins(graph.getId(),0,CLEAR_SOLUTION); fileSink.stepBegins(graph.getId(), 0, CLEAR_SOLUTION);
removeRoutes(vehicleRoutes); removeRoutes(vehicleRoutes);
} }
private void removeRoutes(Collection<VehicleRoute> vehicleRoutes) { private void removeRoutes(Collection<VehicleRoute> vehicleRoutes) {
for(VehicleRoute route : vehicleRoutes){ for (VehicleRoute route : vehicleRoutes) {
String prevNode = makeStartId(route.getVehicle()); String prevNode = makeStartId(route.getVehicle());
for(TourActivity act : route.getActivities()){ for (TourActivity act : route.getActivities()) {
String actNode = getNodeId(act); String actNode = getNodeId(act);
removeEdge(prevNode + "_" + actNode); removeEdge(prevNode + "_" + actNode);
prevNode = actNode; prevNode = actNode;
} }
if(route.getVehicle().isReturnToDepot()) { if (route.getVehicle().isReturnToDepot()) {
String lastNode = makeEndId(route.getVehicle()); String lastNode = makeEndId(route.getVehicle());
removeEdge(prevNode + "_" + lastNode); removeEdge(prevNode + "_" + lastNode);
} }
@ -404,25 +404,25 @@ public class AlgorithmEventsRecorder implements RuinListener, IterationStartsLis
@Override @Override
public void informBeforeJobInsertion(Job job, InsertionData data, VehicleRoute route) { public void informBeforeJobInsertion(Job job, InsertionData data, VehicleRoute route) {
if(!record()) return; if (!record()) return;
markInserted(job); markInserted(job);
handleVehicleSwitch(data, route); handleVehicleSwitch(data, route);
insertJob(job, data, route); insertJob(job, data, route);
} }
private void insertJob(Job job, InsertionData data, VehicleRoute route) { private void insertJob(Job job, InsertionData data, VehicleRoute route) {
if(job instanceof Service) insertService(job,data,route); if (job instanceof Service) insertService(job, data, route);
else if(job instanceof Shipment) insertShipment(job,data,route); else if (job instanceof Shipment) insertShipment(job, data, route);
} }
private void insertShipment(Job job, InsertionData data, VehicleRoute route) { private void insertShipment(Job job, InsertionData data, VehicleRoute route) {
String fromNodeId = getFromNodeId((Shipment) job); String fromNodeId = getFromNodeId((Shipment) job);
String toNodeId = getToNodeId((Shipment) job); String toNodeId = getToNodeId((Shipment) job);
insertNode(toNodeId,data.getDeliveryInsertionIndex(),data,route); insertNode(toNodeId, data.getDeliveryInsertionIndex(), data, route);
List<AbstractActivity> del = vrp.getActivities(job); List<AbstractActivity> del = vrp.getActivities(job);
VehicleRoute copied = VehicleRoute.copyOf(route); VehicleRoute copied = VehicleRoute.copyOf(route);
copied.getTourActivities().addActivity(data.getDeliveryInsertionIndex(),del.get(1)); copied.getTourActivities().addActivity(data.getDeliveryInsertionIndex(), del.get(1));
insertNode(fromNodeId, data.getPickupInsertionIndex(), data, copied); insertNode(fromNodeId, data.getPickupInsertionIndex(), data, copied);
} }
@ -436,19 +436,17 @@ public class AlgorithmEventsRecorder implements RuinListener, IterationStartsLis
String node_i; String node_i;
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);
} }
String edgeId_1 = node_i + "_" + nodeId; String edgeId_1 = node_i + "_" + nodeId;
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);
} }
@ -456,7 +454,7 @@ public class AlgorithmEventsRecorder implements RuinListener, IterationStartsLis
addEdge(edgeId_1, node_i, nodeId); addEdge(edgeId_1, node_i, nodeId);
if(!(isLast(insertionIndex,route) && !data.getSelectedVehicle().isReturnToDepot())) { if (!(isLast(insertionIndex, route) && !data.getSelectedVehicle().isReturnToDepot())) {
addEdge(edgeId_2, nodeId, node_j); addEdge(edgeId_2, nodeId, node_j);
if (!route.getActivities().isEmpty()) { if (!route.getActivities().isEmpty()) {
removeEdge(node_i + "_" + node_j); removeEdge(node_i + "_" + node_j);
@ -466,38 +464,37 @@ public class AlgorithmEventsRecorder implements RuinListener, IterationStartsLis
private void handleVehicleSwitch(InsertionData data, VehicleRoute route) { private void handleVehicleSwitch(InsertionData data, VehicleRoute route) {
boolean vehicleSwitch = false; boolean vehicleSwitch = false;
if(!(route.getVehicle() instanceof VehicleImpl.NoVehicle)) { if (!(route.getVehicle() instanceof VehicleImpl.NoVehicle)) {
if (!route.getVehicle().getId().equals(data.getSelectedVehicle().getId())) { if (!route.getVehicle().getId().equals(data.getSelectedVehicle().getId())) {
vehicleSwitch = true; vehicleSwitch = true;
} }
} }
if(vehicleSwitch && !route.getActivities().isEmpty()){ if (vehicleSwitch && !route.getActivities().isEmpty()) {
String oldStart = makeStartId(route.getVehicle()); String oldStart = makeStartId(route.getVehicle());
String firstAct = ((TourActivity.JobActivity)route.getActivities().get(0)).getJob().getId(); String firstAct = ((TourActivity.JobActivity) route.getActivities().get(0)).getJob().getId();
String oldEnd = makeEndId(route.getVehicle()); String oldEnd = makeEndId(route.getVehicle());
String lastAct = ((TourActivity.JobActivity)route.getActivities().get(route.getActivities().size()-1)).getJob().getId(); String lastAct = ((TourActivity.JobActivity) route.getActivities().get(route.getActivities().size() - 1)).getJob().getId();
removeEdge(oldStart + "_" + firstAct); removeEdge(oldStart + "_" + firstAct);
if(route.getVehicle().isReturnToDepot()) { if (route.getVehicle().isReturnToDepot()) {
removeEdge(lastAct + "_" + oldEnd); removeEdge(lastAct + "_" + oldEnd);
} }
String newStart = makeStartId(data.getSelectedVehicle()); String newStart = makeStartId(data.getSelectedVehicle());
String newEnd = makeEndId(data.getSelectedVehicle()); String newEnd = makeEndId(data.getSelectedVehicle());
addEdge(newStart + "_" + firstAct,newStart,firstAct); addEdge(newStart + "_" + firstAct, newStart, firstAct);
if(data.getSelectedVehicle().isReturnToDepot()) { if (data.getSelectedVehicle().isReturnToDepot()) {
addEdge(lastAct + "_" + newEnd, lastAct, newEnd); addEdge(lastAct + "_" + newEnd, lastAct, newEnd);
} }
} }
} }
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);
} }
} }
@ -507,7 +504,7 @@ public class AlgorithmEventsRecorder implements RuinListener, IterationStartsLis
} }
private void markEdgeRemoved(String edgeId) { private void markEdgeRemoved(String edgeId) {
graph.getEdge(edgeId).addAttribute("ui.class","removed"); graph.getEdge(edgeId).addAttribute("ui.class", "removed");
} }
private boolean isFirst(int index) { private boolean isFirst(int index) {
@ -519,18 +516,18 @@ public class AlgorithmEventsRecorder implements RuinListener, IterationStartsLis
} }
private void addEdge(String edgeId, String fromNode, String toNode) { private void addEdge(String edgeId, String fromNode, String toNode) {
graph.addEdge(edgeId,fromNode,toNode,true); graph.addEdge(edgeId, fromNode, toNode, true);
markEdgeInserted(edgeId); markEdgeInserted(edgeId);
} }
private void markEdgeInserted(String edgeId) { private void markEdgeInserted(String edgeId) {
graph.getEdge(edgeId).addAttribute("ui.class","inserted"); graph.getEdge(edgeId).addAttribute("ui.class", "inserted");
graph.getEdge(edgeId).removeAttribute("ui.class"); graph.getEdge(edgeId).removeAttribute("ui.class");
} }
@Override @Override
public void informInsertionStarts(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs) { public void informInsertionStarts(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs) {
if(!record()) return; if (!record()) return;
fileSink.stepBegins(graph.getId(),0,RECREATE); fileSink.stepBegins(graph.getId(), 0, RECREATE);
} }
} }

View file

@ -47,7 +47,7 @@ public class AlgorithmEventsViewer {
this.delayContainer = delayContainer; this.delayContainer = delayContainer;
} }
public void setRuinDelay(long ruinDelay){ public void setRuinDelay(long ruinDelay) {
this.ruinDelay = ruinDelay; this.ruinDelay = ruinDelay;
} }
@ -131,16 +131,14 @@ public class AlgorithmEventsViewer {
@Override @Override
public void stepBegins(String sourceId, long timeId, double step) { public void stepBegins(String sourceId, long timeId, double step) {
if(step == AlgorithmEventsRecorder.RECREATE) { if (step == AlgorithmEventsRecorder.RECREATE) {
delayContainer.delay = recreateDelay; delayContainer.delay = recreateDelay;
} }
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;
} }
} }
@ -156,15 +154,15 @@ public class AlgorithmEventsViewer {
private long delay = 2; private long delay = 2;
public void setRecreationDelay(long delay_in_ms){ public void setRecreationDelay(long delay_in_ms) {
this.delayRecreation = delay_in_ms; this.delayRecreation = delay_in_ms;
} }
public void setRuinDelay(long delay_in_ms){ public void setRuinDelay(long delay_in_ms) {
this.delayRuin = delay_in_ms; this.delayRuin = delay_in_ms;
} }
public void display(String dgsFile){ public void display(String dgsFile) {
System.setProperty("org.graphstream.ui.renderer", "org.graphstream.ui.j2dviewer.J2DGraphRenderer"); System.setProperty("org.graphstream.ui.renderer", "org.graphstream.ui.j2dviewer.J2DGraphRenderer");
Graph graph = GraphStreamViewer.createMultiGraph("g", GraphStreamViewer.StyleSheets.BLUE_FOREST); Graph graph = GraphStreamViewer.createMultiGraph("g", GraphStreamViewer.StyleSheets.BLUE_FOREST);
Viewer viewer = graph.display(); Viewer viewer = graph.display();
@ -185,13 +183,13 @@ public class AlgorithmEventsViewer {
while (fs.nextEvents()) { while (fs.nextEvents()) {
sleep(delayContainer.delay); sleep(delayContainer.delay);
} }
} catch( IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
try { try {
fs.end(); fs.end();
} catch( IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} finally { } finally {
fs.removeSink(graph); fs.removeSink(graph);

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 {
@ -53,7 +52,7 @@ public class AlgorithmSearchProgressChartListener implements IterationEndsListen
public AlgorithmSearchProgressChartListener(String pngFileName) { public AlgorithmSearchProgressChartListener(String pngFileName) {
super(); super();
this.filename = pngFileName; this.filename = pngFileName;
if(!this.filename.endsWith("png")){ if (!this.filename.endsWith("png")) {
this.filename += ".png"; this.filename += ".png";
} }
} }
@ -69,19 +68,19 @@ public class AlgorithmSearchProgressChartListener implements IterationEndsListen
double worst = 0.0; double worst = 0.0;
double best = Double.MAX_VALUE; double best = Double.MAX_VALUE;
double sum = 0.0; double sum = 0.0;
for(VehicleRoutingProblemSolution sol : solutions){ for (VehicleRoutingProblemSolution sol : solutions) {
if(sol.getCost() > worst) worst = Math.min(sol.getCost(),Double.MAX_VALUE); if (sol.getCost() > worst) worst = Math.min(sol.getCost(), Double.MAX_VALUE);
if(sol.getCost() < best) best = sol.getCost(); if (sol.getCost() < best) best = sol.getCost();
sum += Math.min(sol.getCost(),Double.MAX_VALUE); sum += Math.min(sol.getCost(), Double.MAX_VALUE);
} }
chartBuilder.addData("best", i, best); chartBuilder.addData("best", i, best);
chartBuilder.addData("worst", i, worst); chartBuilder.addData("worst", i, worst);
chartBuilder.addData("avg", i, sum/(double)solutions.size()); chartBuilder.addData("avg", i, sum / (double) solutions.size());
} }
@Override @Override
public void informAlgorithmStarts(VehicleRoutingProblem problem,VehicleRoutingAlgorithm algorithm,Collection<VehicleRoutingProblemSolution> solutions) { public void informAlgorithmStarts(VehicleRoutingProblem problem, VehicleRoutingAlgorithm algorithm, Collection<VehicleRoutingProblemSolution> solutions) {
chartBuilder = XYLineChartBuilder.newInstance("search-progress", "iterations", "results"); chartBuilder = XYLineChartBuilder.newInstance("search-progress", "iterations", "results");
} }

View file

@ -39,14 +39,13 @@ 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 {
public void calculationStarts(final BenchmarkInstance p, final String algorithmName, final VehicleRoutingAlgorithm algorithm, final int run); public void calculationStarts(final BenchmarkInstance p, final String algorithmName, final VehicleRoutingAlgorithm algorithm, final int run);
@ -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 {
@ -75,13 +73,14 @@ public class ComputationalLaboratory {
private int run; private int run;
private String indicatorName; private String indicatorName;
public Key(String instanceName, String algorithmName, int run,String indicatorName) { public Key(String instanceName, String algorithmName, int run, String indicatorName) {
super(); super();
this.instanceName = instanceName; this.instanceName = instanceName;
this.algorithmName = algorithmName; this.algorithmName = algorithmName;
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,22 +128,26 @@ 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;
} }
@Override @Override
public String toString() { public String toString() {
return "[algorithm="+algorithmName+"][instance="+instanceName+"][run="+run+"][indicator="+indicatorName+"]"; return "[algorithm=" + algorithmName + "][instance=" + instanceName + "][run=" + run + "][indicator=" + 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.
@ -163,14 +168,15 @@ public class ComputationalLaboratory {
* @param indicatorName * @param indicatorName
* @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))
Key key = new Key(instanceName,algorithmName,run,indicatorName); throw new IllegalArgumentException(indicatorName + " is already used internally. please choose another indicator-name.");
Key key = new Key(instanceName, algorithmName, run, indicatorName);
data.put(key, value); data.put(key, value);
} }
public void addSolution(String instanceName, String algorithmName, int run, VehicleRoutingProblemSolution solution){ public void addSolution(String instanceName, String algorithmName, int run, VehicleRoutingProblemSolution solution) {
Key key = new Key(instanceName,algorithmName,run,SOLUTION_INDICATOR_NAME); Key key = new Key(instanceName, algorithmName, run, SOLUTION_INDICATOR_NAME);
solutions.put(key, solution); solutions.put(key, solution);
} }
@ -182,10 +188,10 @@ public class ComputationalLaboratory {
* @param indicator * @param indicator
* @return * @return
*/ */
public Collection<Double> getData(String instanceName, String algorithmName, String indicator){ public Collection<Double> getData(String instanceName, String algorithmName, String indicator) {
List<Double> values = new ArrayList<Double>(); List<Double> values = new ArrayList<Double>();
for(Key key : data.keySet()){ for (Key key : data.keySet()) {
if(key.getAlgorithmName().equals(algorithmName) && key.getInstanceName().equals(instanceName) && key.getIndicatorName().equals(indicator)){ if (key.getAlgorithmName().equals(algorithmName) && key.getInstanceName().equals(instanceName) && key.getIndicatorName().equals(indicator)) {
values.add(data.get(key)); values.add(data.get(key));
} }
} }
@ -201,12 +207,12 @@ public class ComputationalLaboratory {
* @param indicator * @param indicator
* @return * @return
*/ */
public Double getDate(String instanceName, String algorithmName, int run, String indicator){ public Double getDate(String instanceName, String algorithmName, int run, String indicator) {
return data.get(new Key(instanceName,algorithmName,run,indicator)); return data.get(new Key(instanceName, algorithmName, run, indicator));
} }
public VehicleRoutingProblemSolution getSolution(String instanceName, String algorithmName, int run){ public VehicleRoutingProblemSolution getSolution(String instanceName, String algorithmName, int run) {
return solutions.get(new Key(instanceName,algorithmName,run,"solution")); return solutions.get(new Key(instanceName, algorithmName, run, "solution"));
} }
/** /**
@ -214,19 +220,19 @@ public class ComputationalLaboratory {
* *
* @return * @return
*/ */
public Set<Key> getDataKeySet(){ public Set<Key> getDataKeySet() {
return data.keySet(); return data.keySet();
} }
public Set<Key> getSolutionKeySet(){ public Set<Key> getSolutionKeySet() {
return solutions.keySet(); return solutions.keySet();
} }
public VehicleRoutingProblemSolution getSolution(Key solutionKey){ public VehicleRoutingProblemSolution getSolution(Key solutionKey) {
return solutions.get(solutionKey); return solutions.get(solutionKey);
} }
public Collection<VehicleRoutingProblemSolution> getSolutions(){ public Collection<VehicleRoutingProblemSolution> getSolutions() {
return solutions.values(); return solutions.values();
} }
@ -236,7 +242,7 @@ public class ComputationalLaboratory {
* @param key * @param key
* @return * @return
*/ */
public Double getData(Key key){ public Double getData(Key key) {
return data.get(key); return data.get(key);
} }
@ -284,9 +290,10 @@ public class ComputationalLaboratory {
* @param factory * @param factory
* @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))
algorithms.add(new Algorithm(name,factory)); throw new IllegalStateException("there is already a algorithmFactory with the same name (algorithmName=" + name + "). unique names are required.");
algorithms.add(new Algorithm(name, factory));
algorithmNames.add(name); algorithmNames.add(name);
} }
@ -294,7 +301,7 @@ public class ComputationalLaboratory {
return algorithmNames; return algorithmNames;
} }
public Collection<String> getInstanceNames(){ public Collection<String> getInstanceNames() {
return instanceNames; return instanceNames;
} }
@ -305,9 +312,10 @@ public class ComputationalLaboratory {
* @param problem * @param problem
* @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))
benchmarkInstances.add(new BenchmarkInstance(name,problem,null,null)); throw new IllegalStateException("there is already an instance with the same name (instanceName=" + name + "). unique names are required.");
benchmarkInstances.add(new BenchmarkInstance(name, problem, null, null));
instanceNames.add(name); instanceNames.add(name);
} }
@ -317,8 +325,9 @@ public class ComputationalLaboratory {
* @param instance the instance to be added * @param instance the instance to be added
* @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);
} }
@ -329,8 +338,8 @@ public class ComputationalLaboratory {
* @param instances collection of instances to be added * @param instances collection of instances to be added
* @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 addAllInstances(Collection<BenchmarkInstance> instances){ public void addAllInstances(Collection<BenchmarkInstance> instances) {
for(BenchmarkInstance i : instances){ for (BenchmarkInstance i : instances) {
addInstance(i); addInstance(i);
} }
} }
@ -342,8 +351,8 @@ public class ComputationalLaboratory {
* @param problem * @param problem
* @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, Double bestKnownResult, Double bestKnownVehicles){ public void addInstance(String name, VehicleRoutingProblem problem, Double bestKnownResult, Double bestKnownVehicles) {
addInstance(new BenchmarkInstance(name,problem,bestKnownResult,bestKnownVehicles)); addInstance(new BenchmarkInstance(name, problem, bestKnownResult, bestKnownVehicles));
} }
/** /**
@ -351,11 +360,11 @@ public class ComputationalLaboratory {
* *
* @param listener * @param listener
*/ */
public void addListener(LabListener listener){ public void addListener(LabListener listener) {
if(listener instanceof CalculationListener) { if (listener instanceof CalculationListener) {
listeners.add((CalculationListener) listener); listeners.add((CalculationListener) listener);
} }
if(listener instanceof LabStartsAndEndsListener){ if (listener instanceof LabStartsAndEndsListener) {
startsAndEndslisteners.add((LabStartsAndEndsListener) listener); startsAndEndslisteners.add((LabStartsAndEndsListener) listener);
} }
} }
@ -366,13 +375,13 @@ public class ComputationalLaboratory {
* *
* @param runs * @param runs
*/ */
public void setNuOfRuns(int runs){ public void setNuOfRuns(int runs) {
this.runs = runs; this.runs = runs;
} }
/** /**
* 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,31 +389,31 @@ 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()) {
throw new IllegalStateException("no algorithm specified. at least one algorithm needs to be specified."); throw new IllegalStateException("no algorithm specified. at least one algorithm needs to be specified.");
} }
if(benchmarkInstances.isEmpty()){ if (benchmarkInstances.isEmpty()) {
throw new IllegalStateException("no instance specified. at least one instance needs to be specified."); throw new IllegalStateException("no instance specified. at least one instance needs to be specified.");
} }
informStart(); informStart();
System.out.println("start benchmarking [nuAlgorithms="+algorithms.size()+"][nuInstances=" + benchmarkInstances.size() + "][runsPerInstance=" + runs + "]"); System.out.println("start benchmarking [nuAlgorithms=" + algorithms.size() + "][nuInstances=" + benchmarkInstances.size() + "][runsPerInstance=" + runs + "]");
double startTime = System.currentTimeMillis(); double startTime = System.currentTimeMillis();
ExecutorService executor = Executors.newFixedThreadPool(threads); ExecutorService executor = Executors.newFixedThreadPool(threads);
for(final Algorithm algorithm : algorithms){ for (final Algorithm algorithm : algorithms) {
for(final BenchmarkInstance p : benchmarkInstances){ for (final BenchmarkInstance p : benchmarkInstances) {
for(int run=0;run<runs;run++){ for (int run = 0; run < runs; run++) {
final int r = run; final int r = run;
// runAlgorithm(p, algorithm, r+1); // runAlgorithm(p, algorithm, r+1);
executor.submit(new Runnable(){ executor.submit(new Runnable() {
@Override @Override
public void run() { public void run() {
runAlgorithm(p, algorithm, r+1); runAlgorithm(p, algorithm, r + 1);
} }
}); });
@ -418,19 +427,19 @@ public class ComputationalLaboratory {
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} }
System.out.println("benchmarking done [time="+(System.currentTimeMillis()-startTime)/1000 + "sec]"); System.out.println("benchmarking done [time=" + (System.currentTimeMillis() - startTime) / 1000 + "sec]");
informEnd(); informEnd();
} }
private void informEnd() { private void informEnd() {
for(LabStartsAndEndsListener l : startsAndEndslisteners){ for (LabStartsAndEndsListener l : startsAndEndslisteners) {
l.labEnds(); l.labEnds();
} }
} }
private void informStart() { private void informStart() {
for(LabStartsAndEndsListener l : startsAndEndslisteners){ for (LabStartsAndEndsListener l : startsAndEndslisteners) {
l.labStarts(benchmarkInstances, algorithms.size(),runs); l.labStarts(benchmarkInstances, algorithms.size(), runs);
} }
} }
@ -445,21 +454,21 @@ public class ComputationalLaboratory {
} }
private void runAlgorithm(BenchmarkInstance p, Algorithm algorithm, int run) { private void runAlgorithm(BenchmarkInstance p, Algorithm algorithm, int run) {
System.out.println("[algorithm=" + algorithm.name + "][instance="+p.name+"][run="+run+"][status=start]"); System.out.println("[algorithm=" + algorithm.name + "][instance=" + p.name + "][run=" + run + "][status=start]");
VehicleRoutingAlgorithm vra = algorithm.factory.createAlgorithm(p.vrp); VehicleRoutingAlgorithm vra = algorithm.factory.createAlgorithm(p.vrp);
informCalculationStarts(p, algorithm.name, vra, run); informCalculationStarts(p, algorithm.name, vra, run);
Collection<VehicleRoutingProblemSolution> solutions = vra.searchSolutions(); Collection<VehicleRoutingProblemSolution> solutions = vra.searchSolutions();
System.out.println("[algorithm=" + algorithm.name + "][instance="+p.name+"][run="+run+"][status=finished]"); System.out.println("[algorithm=" + algorithm.name + "][instance=" + p.name + "][run=" + run + "][status=finished]");
informCalculationsEnds(p, algorithm.name, vra, run, solutions); informCalculationsEnds(p, algorithm.name, vra, run, solutions);
} }
private void informCalculationStarts(BenchmarkInstance p, String name, VehicleRoutingAlgorithm vra, int run) { private void informCalculationStarts(BenchmarkInstance p, String name, VehicleRoutingAlgorithm vra, int run) {
for(CalculationListener l : listeners) l.calculationStarts(p, name, vra, run); for (CalculationListener l : listeners) l.calculationStarts(p, name, vra, run);
} }
private void informCalculationsEnds(BenchmarkInstance p, String name, VehicleRoutingAlgorithm vra, int run, private void informCalculationsEnds(BenchmarkInstance p, String name, VehicleRoutingAlgorithm vra, int run,
Collection<VehicleRoutingProblemSolution> solutions) { Collection<VehicleRoutingProblemSolution> solutions) {
for(CalculationListener l : listeners) l.calculationEnds(p, name, vra, run, solutions); for (CalculationListener l : listeners) l.calculationEnds(p, name, vra, run, solutions);
} }
} }

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>();
@ -52,7 +51,7 @@ public class ConcurrentBenchmarker {
private Collection<BenchmarkResult> results = new ArrayList<BenchmarkResult>(); private Collection<BenchmarkResult> results = new ArrayList<BenchmarkResult>();
private Cost cost = new Cost(){ private Cost cost = new Cost() {
@Override @Override
public double getCost(VehicleRoutingProblemSolution sol) { public double getCost(VehicleRoutingProblemSolution sol) {
@ -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();
@ -71,28 +72,28 @@ public class ConcurrentBenchmarker {
// LogManager.getRootLogger().setLevel(Level.ERROR); // LogManager.getRootLogger().setLevel(Level.ERROR);
} }
public ConcurrentBenchmarker(VehicleRoutingAlgorithmFactory algorithmFactory){ public ConcurrentBenchmarker(VehicleRoutingAlgorithmFactory algorithmFactory) {
this.algorithmFactory = algorithmFactory; this.algorithmFactory = algorithmFactory;
} }
public void addBenchmarkWriter(BenchmarkWriter writer){ public void addBenchmarkWriter(BenchmarkWriter writer) {
writers.add(writer); writers.add(writer);
} }
public void addInstance(String name, VehicleRoutingProblem problem){ public void addInstance(String name, VehicleRoutingProblem problem) {
benchmarkInstances.add(new BenchmarkInstance(name,problem,null,null)); benchmarkInstances.add(new BenchmarkInstance(name, problem, null, null));
} }
public void addInstane(BenchmarkInstance instance){ public void addInstane(BenchmarkInstance instance) {
benchmarkInstances.add(instance); benchmarkInstances.add(instance);
} }
public void addAllInstances(Collection<BenchmarkInstance> instances){ public void addAllInstances(Collection<BenchmarkInstance> instances) {
benchmarkInstances.addAll(instances); benchmarkInstances.addAll(instances);
} }
public void addInstance(String name, VehicleRoutingProblem problem, Double bestKnownResult, Double bestKnownVehicles){ public void addInstance(String name, VehicleRoutingProblem problem, Double bestKnownResult, Double bestKnownVehicles) {
benchmarkInstances.add(new BenchmarkInstance(name,problem,bestKnownResult,bestKnownVehicles)); benchmarkInstances.add(new BenchmarkInstance(name, problem, bestKnownResult, bestKnownVehicles));
} }
/** /**
@ -101,18 +102,18 @@ public class ConcurrentBenchmarker {
* *
* @param runs * @param runs
*/ */
public void setNuOfRuns(int runs){ public void setNuOfRuns(int runs) {
this.runs = runs; this.runs = runs;
} }
public void run(){ public void run() {
System.out.println("start benchmarking [nuOfInstances=" + benchmarkInstances.size() + "][runsPerInstance=" + runs + "]"); System.out.println("start benchmarking [nuOfInstances=" + benchmarkInstances.size() + "][runsPerInstance=" + runs + "]");
double startTime = System.currentTimeMillis(); double startTime = System.currentTimeMillis();
ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()+1); ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() + 1);
List<Future<BenchmarkResult>> futures = new ArrayList<Future<BenchmarkResult>>(); List<Future<BenchmarkResult>> futures = new ArrayList<Future<BenchmarkResult>>();
for(final BenchmarkInstance p : benchmarkInstances){ for (final BenchmarkInstance p : benchmarkInstances) {
Future<BenchmarkResult> futureResult = executor.submit(new Callable<BenchmarkResult>(){ Future<BenchmarkResult> futureResult = executor.submit(new Callable<BenchmarkResult>() {
@Override @Override
public BenchmarkResult call() throws Exception { public BenchmarkResult call() throws Exception {
@ -125,9 +126,9 @@ public class ConcurrentBenchmarker {
} }
try { try {
int count = 1; int count = 1;
for(Future<BenchmarkResult> f : futures){ for (Future<BenchmarkResult> f : futures) {
BenchmarkResult r = f.get(); BenchmarkResult r = f.get();
print(r,count); print(r, count);
results.add(f.get()); results.add(f.get());
count++; count++;
} }
@ -140,7 +141,7 @@ public class ConcurrentBenchmarker {
} }
executor.shutdown(); executor.shutdown();
print(results); print(results);
System.out.println("done [time="+(System.currentTimeMillis()-startTime)/1000 + "sec]"); System.out.println("done [time=" + (System.currentTimeMillis() - startTime) / 1000 + "sec]");
} }
private BenchmarkResult runAlgoAndGetResult(BenchmarkInstance p) { private BenchmarkResult runAlgoAndGetResult(BenchmarkInstance p) {
@ -148,10 +149,10 @@ public class ConcurrentBenchmarker {
double[] results = new double[runs]; double[] results = new double[runs];
double[] times = new double[runs]; double[] times = new double[runs];
for(int run=0;run<runs;run++){ for (int run = 0; run < runs; run++) {
VehicleRoutingAlgorithm vra = createAlgorithm(p); VehicleRoutingAlgorithm vra = createAlgorithm(p);
StopWatch stopwatch = new StopWatch(); StopWatch stopwatch = new StopWatch();
vra.getAlgorithmListeners().addListener(stopwatch,Priority.HIGH); vra.getAlgorithmListeners().addListener(stopwatch, Priority.HIGH);
Collection<VehicleRoutingProblemSolution> solutions = vra.searchSolutions(); Collection<VehicleRoutingProblemSolution> solutions = vra.searchSolutions();
VehicleRoutingProblemSolution best = Solutions.bestOf(solutions); VehicleRoutingProblemSolution best = Solutions.bestOf(solutions);
vehicles[run] = best.getRoutes().size(); vehicles[run] = best.getRoutes().size();
@ -163,25 +164,24 @@ 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);
} }
} }
private void print(Collection<BenchmarkResult> results) { private void print(Collection<BenchmarkResult> results) {
double sumTime=0.0; double sumTime = 0.0;
double sumResult=0.0; double sumResult = 0.0;
for(BenchmarkResult r : results){ for (BenchmarkResult r : results) {
sumTime+=r.getTimesStats().getMean(); sumTime += r.getTimesStats().getMean();
sumResult+=r.getResultStats().getMean(); sumResult += r.getResultStats().getMean();
// print(r); // print(r);
} }
System.out.println("[avgTime="+round(sumTime/(double)results.size(),2)+"][avgResult="+round(sumResult/(double)results.size(),2)+"]"); System.out.println("[avgTime=" + round(sumTime / (double) results.size(), 2) + "][avgResult=" + round(sumResult / (double) results.size(), 2) + "]");
for(BenchmarkWriter writer : writers){ for (BenchmarkWriter writer : writers) {
writer.write(results); writer.write(results);
} }
} }
@ -190,30 +190,30 @@ public class ConcurrentBenchmarker {
Double avgDelta = null; Double avgDelta = null;
Double bestDelta = null; Double bestDelta = null;
Double worstDelta = null; Double worstDelta = null;
if(r.instance.bestKnownResult != null){ if (r.instance.bestKnownResult != null) {
avgDelta = (r.getResultStats().getMean() / r.instance.bestKnownResult - 1) * 100; avgDelta = (r.getResultStats().getMean() / r.instance.bestKnownResult - 1) * 100;
bestDelta = (r.getResultStats().getMin() / r.instance.bestKnownResult - 1) * 100; bestDelta = (r.getResultStats().getMin() / r.instance.bestKnownResult - 1) * 100;
worstDelta = (r.getResultStats().getMax() / r.instance.bestKnownResult - 1) * 100; worstDelta = (r.getResultStats().getMax() / r.instance.bestKnownResult - 1) * 100;
} }
System.out.println("("+count+"/"+benchmarkInstances.size() +")"+ "\t[instance="+r.instance.name+ System.out.println("(" + count + "/" + benchmarkInstances.size() + ")" + "\t[instance=" + r.instance.name +
"][avgTime="+round(r.getTimesStats().getMean(),2)+"]" + "][avgTime=" + round(r.getTimesStats().getMean(), 2) + "]" +
"[Result=" + getString(r.getResultStats()) + "]" + "[Result=" + getString(r.getResultStats()) + "]" +
"[Vehicles=" + getString(r.getVehicleStats()) + "]" + "[Vehicles=" + getString(r.getVehicleStats()) + "]" +
"[Delta[%]=" + getString(bestDelta,avgDelta,worstDelta) + "]"); "[Delta[%]=" + getString(bestDelta, avgDelta, worstDelta) + "]");
} }
private String getString(Double bestDelta, Double avgDelta,Double worstDelta) { private String getString(Double bestDelta, Double avgDelta, Double worstDelta) {
return "[best="+round(bestDelta,2)+"][avg="+round(avgDelta,2)+"][worst="+round(worstDelta,2)+"]"; return "[best=" + round(bestDelta, 2) + "][avg=" + round(avgDelta, 2) + "][worst=" + round(worstDelta, 2) + "]";
} }
private String getString(DescriptiveStatistics stats){ private String getString(DescriptiveStatistics stats) {
return "[best="+round(stats.getMin(),2)+"][avg="+round(stats.getMean(),2)+"][worst="+round(stats.getMax(),2)+"][stdDev=" + round(stats.getStandardDeviation(),2)+"]"; return "[best=" + round(stats.getMin(), 2) + "][avg=" + round(stats.getMean(), 2) + "][worst=" + round(stats.getMax(), 2) + "][stdDev=" + round(stats.getStandardDeviation(), 2) + "]";
} }
private Double round(Double value, int i) { private Double round(Double value, int i) {
if(value==null) return null; if (value == null) return null;
long roundedVal = Math.round(value*Math.pow(10, i)); long roundedVal = Math.round(value * Math.pow(10, i));
return (double)roundedVal/(double)(Math.pow(10, i)); return (double) roundedVal / (double) (Math.pow(10, i));
} }
} }

View file

@ -110,8 +110,7 @@ public class GraphStreamViewer {
"edge.shipment {" + "edge.shipment {" +
" fill-color: #999;" + " fill-color: #999;" +
" arrow-size: 6px,3px;" + " arrow-size: 6px,3px;" +
"}" ; "}";
@SuppressWarnings("UnusedDeclaration") @SuppressWarnings("UnusedDeclaration")
@ -165,11 +164,11 @@ public class GraphStreamViewer {
"edge.shipment {" + "edge.shipment {" +
" fill-color: #999;" + " fill-color: #999;" +
" arrow-size: 6px,3px;" + " arrow-size: 6px,3px;" +
"}" ; "}";
} }
public static Graph createMultiGraph(String name, String style){ public static Graph createMultiGraph(String name, String style) {
Graph g = new MultiGraph(name); Graph g = new MultiGraph(name);
g.addAttribute("ui.quality"); g.addAttribute("ui.quality");
g.addAttribute("ui.antialias"); g.addAttribute("ui.antialias");
@ -177,8 +176,8 @@ public class GraphStreamViewer {
return g; return g;
} }
public static ViewPanel createEmbeddedView(Graph graph, double scaling){ public static ViewPanel createEmbeddedView(Graph graph, double scaling) {
Viewer viewer = new Viewer(graph,Viewer.ThreadingModel.GRAPH_IN_ANOTHER_THREAD); Viewer viewer = new Viewer(graph, Viewer.ThreadingModel.GRAPH_IN_ANOTHER_THREAD);
ViewPanel view = viewer.addDefaultView(false); ViewPanel view = viewer.addDefaultView(false);
view.setPreferredSize(new Dimension((int) (698 * scaling), (int) (440 * scaling))); view.setPreferredSize(new Dimension((int) (698 * scaling), (int) (440 * scaling)));
return view; return view;
@ -234,7 +233,7 @@ public class GraphStreamViewer {
"edge.shipment {" + "edge.shipment {" +
" fill-color: #999;" + " fill-color: #999;" +
" arrow-size: 6px,3px;" + " arrow-size: 6px,3px;" +
"}" ; "}";
public static enum Label { public static enum Label {
NO_LABEL, ID, JOB_NAME, ARRIVAL_TIME, DEPARTURE_TIME, ACTIVITY NO_LABEL, ID, JOB_NAME, ARRIVAL_TIME, DEPARTURE_TIME, ACTIVITY
@ -280,13 +279,13 @@ public class GraphStreamViewer {
this.solution = solution; this.solution = solution;
} }
public GraphStreamViewer labelWith(Label label){ public GraphStreamViewer labelWith(Label label) {
this.label=label; this.label = label;
return this; return this;
} }
public GraphStreamViewer setRenderDelay(long ms){ public GraphStreamViewer setRenderDelay(long ms) {
this.renderDelay_in_ms=ms; this.renderDelay_in_ms = ms;
return this; return this;
} }
@ -295,20 +294,20 @@ public class GraphStreamViewer {
return this; return this;
} }
public GraphStreamViewer setRenderShipments(boolean renderShipments){ public GraphStreamViewer setRenderShipments(boolean renderShipments) {
this.renderShipments = renderShipments; this.renderShipments = renderShipments;
return this; return this;
} }
public GraphStreamViewer setGraphStreamFrameScalingFactor(double factor){ public GraphStreamViewer setGraphStreamFrameScalingFactor(double factor) {
this.scaling=factor; this.scaling = factor;
return this; return this;
} }
/** /**
* 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
@ -316,20 +315,20 @@ public class GraphStreamViewer {
* @param zoomFactor zoom factor * @param zoomFactor zoom factor
* @return the viewer * @return the viewer
*/ */
public GraphStreamViewer setCameraView(double centerX, double centerY, double zoomFactor){ public GraphStreamViewer setCameraView(double centerX, double centerY, double zoomFactor) {
center = new Center(centerX,centerY); center = new Center(centerX, centerY);
this.zoomFactor = zoomFactor; this.zoomFactor = zoomFactor;
return this; return this;
} }
public void display(){ public void display() {
System.setProperty("org.graphstream.ui.renderer", "org.graphstream.ui.j2dviewer.J2DGraphRenderer"); System.setProperty("org.graphstream.ui.renderer", "org.graphstream.ui.j2dviewer.J2DGraphRenderer");
Graph g = createMultiGraph("g"); Graph g = createMultiGraph("g");
ViewPanel view = createEmbeddedView(g,scaling); ViewPanel view = createEmbeddedView(g, scaling);
createJFrame(view,scaling); createJFrame(view, scaling);
render(g, view); render(g, view);
} }
@ -345,11 +344,11 @@ public class GraphStreamViewer {
JPanel graphStreamPanel = new JPanel(); JPanel graphStreamPanel = new JPanel();
graphStreamPanel.setPreferredSize(new Dimension((int)(800*scaling),(int)(460*scaling))); graphStreamPanel.setPreferredSize(new Dimension((int) (800 * scaling), (int) (460 * scaling)));
graphStreamPanel.setBackground(Color.WHITE); graphStreamPanel.setBackground(Color.WHITE);
JPanel graphStreamBackPanel = new JPanel(); JPanel graphStreamBackPanel = new JPanel();
graphStreamBackPanel.setPreferredSize(new Dimension((int)(700*scaling),(int)(450*scaling))); graphStreamBackPanel.setPreferredSize(new Dimension((int) (700 * scaling), (int) (450 * scaling)));
graphStreamBackPanel.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY, 1)); graphStreamBackPanel.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY, 1));
graphStreamBackPanel.setBackground(Color.WHITE); graphStreamBackPanel.setBackground(Color.WHITE);
@ -365,7 +364,7 @@ public class GraphStreamViewer {
jframe.add(basicPanel); jframe.add(basicPanel);
//conf jframe //conf jframe
jframe.setSize((int)(800*scaling),(int)(580*scaling)); jframe.setSize((int) (800 * scaling), (int) (580 * scaling));
jframe.setLocationRelativeTo(null); jframe.setLocationRelativeTo(null);
jframe.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); jframe.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
jframe.setVisible(true); jframe.setVisible(true);
@ -375,34 +374,33 @@ public class GraphStreamViewer {
} }
private Graph createMultiGraph(String name) { private Graph createMultiGraph(String name) {
return GraphStreamViewer.createMultiGraph(name,STYLESHEET); return GraphStreamViewer.createMultiGraph(name, STYLESHEET);
} }
private void render(Graph g, ViewPanel view) { private void render(Graph g, ViewPanel view) {
if(center != null){ if (center != null) {
view.resizeFrame(view.getWidth(), view.getHeight()); view.resizeFrame(view.getWidth(), view.getHeight());
alignCamera(view); alignCamera(view);
} }
for(Vehicle vehicle : vrp.getVehicles()){ for (Vehicle vehicle : vrp.getVehicles()) {
renderVehicle(g,vehicle,label); renderVehicle(g, vehicle, label);
sleep(renderDelay_in_ms); sleep(renderDelay_in_ms);
} }
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);
} }
if(solution != null){ if (solution != null) {
int routeId = 1; int routeId = 1;
for(VehicleRoute route : solution.getRoutes()){ for (VehicleRoute route : solution.getRoutes()) {
renderRoute(g,route,routeId,renderDelay_in_ms,label); renderRoute(g, route, routeId, renderDelay_in_ms, label);
sleep(renderDelay_in_ms); sleep(renderDelay_in_ms);
routeId++; routeId++;
} }
@ -417,7 +415,7 @@ public class GraphStreamViewer {
private JLabel createEmptyLabel() { private JLabel createEmptyLabel() {
JLabel emptyLabel1 = new JLabel(); JLabel emptyLabel1 = new JLabel();
emptyLabel1.setPreferredSize(new Dimension((int)(40*scaling),(int)(25*scaling))); emptyLabel1.setPreferredSize(new Dimension((int) (40 * scaling), (int) (25 * scaling)));
return emptyLabel1; return emptyLabel1;
} }
@ -426,43 +424,43 @@ public class GraphStreamViewer {
int height = 50; int height = 50;
JPanel panel = new JPanel(); JPanel panel = new JPanel();
panel.setPreferredSize(new Dimension((int)(width*scaling),(int)(height*scaling))); panel.setPreferredSize(new Dimension((int) (width * scaling), (int) (height * scaling)));
panel.setBackground(Color.WHITE); panel.setBackground(Color.WHITE);
JPanel subpanel = new JPanel(); JPanel subpanel = new JPanel();
subpanel.setLayout(new FlowLayout()); subpanel.setLayout(new FlowLayout());
subpanel.setPreferredSize(new Dimension((int)(700*scaling),(int)(40*scaling))); subpanel.setPreferredSize(new Dimension((int) (700 * scaling), (int) (40 * scaling)));
subpanel.setBackground(Color.WHITE); subpanel.setBackground(Color.WHITE);
subpanel.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY,1)); subpanel.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY, 1));
Font font = Font.decode("couriernew"); Font font = Font.decode("couriernew");
JLabel jobs = new JLabel("jobs"); JLabel jobs = new JLabel("jobs");
jobs.setFont(font); jobs.setFont(font);
jobs.setPreferredSize(new Dimension((int)(40*scaling),(int)(25*scaling))); jobs.setPreferredSize(new Dimension((int) (40 * scaling), (int) (25 * scaling)));
int noJobs = 0; int noJobs = 0;
if(this.vrp != null) noJobs = this.vrp.getJobs().values().size(); if (this.vrp != null) noJobs = this.vrp.getJobs().values().size();
JFormattedTextField nJobs = new JFormattedTextField(noJobs); JFormattedTextField nJobs = new JFormattedTextField(noJobs);
nJobs.setFont(font); nJobs.setFont(font);
nJobs.setEditable(false); nJobs.setEditable(false);
nJobs.setBorder(BorderFactory.createEmptyBorder()); nJobs.setBorder(BorderFactory.createEmptyBorder());
nJobs.setBackground(new Color(230,230,230)); nJobs.setBackground(new Color(230, 230, 230));
JLabel costs = new JLabel("costs"); JLabel costs = new JLabel("costs");
costs.setFont(font); costs.setFont(font);
costs.setPreferredSize(new Dimension((int)(40*scaling),(int)(25*scaling))); costs.setPreferredSize(new Dimension((int) (40 * scaling), (int) (25 * scaling)));
JFormattedTextField costsVal = new JFormattedTextField(getSolutionCosts()); JFormattedTextField costsVal = new JFormattedTextField(getSolutionCosts());
costsVal.setFont(font); costsVal.setFont(font);
costsVal.setEditable(false); costsVal.setEditable(false);
costsVal.setBorder(BorderFactory.createEmptyBorder()); costsVal.setBorder(BorderFactory.createEmptyBorder());
costsVal.setBackground(new Color(230,230,230)); costsVal.setBackground(new Color(230, 230, 230));
JLabel vehicles = new JLabel("routes"); JLabel vehicles = new JLabel("routes");
vehicles.setFont(font); vehicles.setFont(font);
vehicles.setPreferredSize(new Dimension((int)(40*scaling),(int)(25*scaling))); vehicles.setPreferredSize(new Dimension((int) (40 * scaling), (int) (25 * scaling)));
// vehicles.setForeground(Color.DARK_GRAY); // vehicles.setForeground(Color.DARK_GRAY);
JFormattedTextField vehVal = new JFormattedTextField(getNoRoutes()); JFormattedTextField vehVal = new JFormattedTextField(getNoRoutes());
@ -470,11 +468,11 @@ public class GraphStreamViewer {
vehVal.setEditable(false); vehVal.setEditable(false);
vehVal.setBorder(BorderFactory.createEmptyBorder()); vehVal.setBorder(BorderFactory.createEmptyBorder());
// vehVal.setForeground(Color.DARK_GRAY); // vehVal.setForeground(Color.DARK_GRAY);
vehVal.setBackground(new Color(230,230,230)); vehVal.setBackground(new Color(230, 230, 230));
//platzhalter //platzhalter
JLabel placeholder1 = new JLabel(); JLabel placeholder1 = new JLabel();
placeholder1.setPreferredSize(new Dimension((int)(60*scaling),(int)(25*scaling))); placeholder1.setPreferredSize(new Dimension((int) (60 * scaling), (int) (25 * scaling)));
JLabel emptyLabel1 = createEmptyLabel(); JLabel emptyLabel1 = createEmptyLabel();
@ -498,32 +496,32 @@ public class GraphStreamViewer {
} }
private Integer getNoRoutes() { private Integer getNoRoutes() {
if(solution!=null) return solution.getRoutes().size(); if (solution != null) return solution.getRoutes().size();
return 0; return 0;
} }
private Double getSolutionCosts() { private Double getSolutionCosts() {
if(solution!=null) return solution.getCost(); if (solution != null) return solution.getCost();
return 0.0; return 0.0;
} }
private void renderShipment(Graph g, Shipment shipment, Label label, boolean renderShipments) { private void renderShipment(Graph g, Shipment shipment, Label label, boolean renderShipments) {
Node n1 = g.addNode(makeId(shipment.getId(),shipment.getPickupLocation().getId())); Node n1 = g.addNode(makeId(shipment.getId(), shipment.getPickupLocation().getId()));
if(label.equals(Label.ID)) n1.addAttribute("ui.label", shipment.getId()); if (label.equals(Label.ID)) n1.addAttribute("ui.label", shipment.getId());
n1.addAttribute("x", shipment.getPickupLocation().getCoordinate().getX()); n1.addAttribute("x", shipment.getPickupLocation().getCoordinate().getX());
n1.addAttribute("y", shipment.getPickupLocation().getCoordinate().getY()); n1.addAttribute("y", shipment.getPickupLocation().getCoordinate().getY());
n1.setAttribute("ui.class", "pickup"); n1.setAttribute("ui.class", "pickup");
Node n2 = g.addNode(makeId(shipment.getId(),shipment.getDeliveryLocation().getId())); Node n2 = g.addNode(makeId(shipment.getId(), shipment.getDeliveryLocation().getId()));
if(label.equals(Label.ID)) n2.addAttribute("ui.label", shipment.getId()); if (label.equals(Label.ID)) n2.addAttribute("ui.label", shipment.getId());
n2.addAttribute("x", shipment.getDeliveryLocation().getCoordinate().getX()); n2.addAttribute("x", shipment.getDeliveryLocation().getCoordinate().getX());
n2.addAttribute("y", shipment.getDeliveryLocation().getCoordinate().getY()); n2.addAttribute("y", shipment.getDeliveryLocation().getCoordinate().getY());
n2.setAttribute("ui.class", "delivery"); n2.setAttribute("ui.class", "delivery");
if(renderShipments){ if (renderShipments) {
Edge s = g.addEdge(shipment.getId(), makeId(shipment.getId(),shipment.getPickupLocation().getId()), Edge s = g.addEdge(shipment.getId(), makeId(shipment.getId(), shipment.getPickupLocation().getId()),
makeId(shipment.getId(),shipment.getDeliveryLocation().getId()), true); makeId(shipment.getId(), shipment.getDeliveryLocation().getId()), true);
s.addAttribute("ui.class", "shipment"); s.addAttribute("ui.class", "shipment");
} }
@ -539,12 +537,12 @@ public class GraphStreamViewer {
} }
private void renderService(Graph g, Service service, Label label) { private void renderService(Graph g, Service service, Label label) {
Node n = g.addNode(makeId(service.getId(),service.getLocation().getId())); Node n = g.addNode(makeId(service.getId(), service.getLocation().getId()));
if(label.equals(Label.ID)) n.addAttribute("ui.label", service.getId()); if (label.equals(Label.ID)) n.addAttribute("ui.label", service.getId());
n.addAttribute("x", service.getLocation().getCoordinate().getX()); n.addAttribute("x", service.getLocation().getCoordinate().getX());
n.addAttribute("y", service.getLocation().getCoordinate().getY()); n.addAttribute("y", service.getLocation().getCoordinate().getY());
if(service.getType().equals("pickup")) n.setAttribute("ui.class", "pickup"); if (service.getType().equals("pickup")) n.setAttribute("ui.class", "pickup");
if(service.getType().equals("delivery")) n.setAttribute("ui.class", "delivery"); if (service.getType().equals("delivery")) n.setAttribute("ui.class", "delivery");
} }
private String makeId(String id, String locationId) { private String makeId(String id, String locationId) {
@ -552,17 +550,17 @@ public class GraphStreamViewer {
} }
private void renderVehicle(Graph g, Vehicle vehicle, Label label) { private void renderVehicle(Graph g, Vehicle vehicle, Label label) {
String nodeId = makeId(vehicle.getId(),vehicle.getStartLocation().getId()); String nodeId = makeId(vehicle.getId(), vehicle.getStartLocation().getId());
Node vehicleStart = g.addNode(nodeId); Node vehicleStart = g.addNode(nodeId);
if(label.equals(Label.ID)) vehicleStart.addAttribute("ui.label", "depot"); if (label.equals(Label.ID)) vehicleStart.addAttribute("ui.label", "depot");
// if(label.equals(Label.ACTIVITY)) n.addAttribute("ui.label", "start"); // if(label.equals(Label.ACTIVITY)) n.addAttribute("ui.label", "start");
vehicleStart.addAttribute("x", vehicle.getStartLocation().getCoordinate().getX()); vehicleStart.addAttribute("x", vehicle.getStartLocation().getCoordinate().getX());
vehicleStart.addAttribute("y", vehicle.getStartLocation().getCoordinate().getY()); vehicleStart.addAttribute("y", vehicle.getStartLocation().getCoordinate().getY());
vehicleStart.setAttribute("ui.class", "depot"); vehicleStart.setAttribute("ui.class", "depot");
if(!vehicle.getStartLocation().getId().equals(vehicle.getEndLocation().getId())){ if (!vehicle.getStartLocation().getId().equals(vehicle.getEndLocation().getId())) {
Node vehicleEnd = g.addNode(makeId(vehicle.getId(),vehicle.getEndLocation().getId())); Node vehicleEnd = g.addNode(makeId(vehicle.getId(), vehicle.getEndLocation().getId()));
if(label.equals(Label.ID)) vehicleEnd.addAttribute("ui.label", "depot"); if (label.equals(Label.ID)) vehicleEnd.addAttribute("ui.label", "depot");
vehicleEnd.addAttribute("x", vehicle.getEndLocation().getCoordinate().getX()); vehicleEnd.addAttribute("x", vehicle.getEndLocation().getCoordinate().getX());
vehicleEnd.addAttribute("y", vehicle.getEndLocation().getCoordinate().getY()); vehicleEnd.addAttribute("y", vehicle.getEndLocation().getCoordinate().getY());
vehicleEnd.setAttribute("ui.class", "depot"); vehicleEnd.setAttribute("ui.class", "depot");
@ -572,40 +570,38 @@ public class GraphStreamViewer {
private void renderRoute(Graph g, VehicleRoute route, int routeId, long renderDelay_in_ms, Label label) { private void renderRoute(Graph g, VehicleRoute route, int routeId, long renderDelay_in_ms, Label label) {
int vehicle_edgeId = 1; int vehicle_edgeId = 1;
String prevIdentifier = makeId(route.getVehicle().getId(),route.getVehicle().getStartLocation().getId()); String prevIdentifier = makeId(route.getVehicle().getId(), route.getVehicle().getStartLocation().getId());
if(label.equals(Label.ACTIVITY) || label.equals(Label.JOB_NAME)){ if (label.equals(Label.ACTIVITY) || label.equals(Label.JOB_NAME)) {
Node n = g.getNode(prevIdentifier); Node n = g.getNode(prevIdentifier);
n.addAttribute("ui.label", "start"); n.addAttribute("ui.label", "start");
} }
for(TourActivity act : route.getActivities()){ for (TourActivity act : route.getActivities()) {
Job job = ((JobActivity) act).getJob(); Job job = ((JobActivity) act).getJob();
String currIdentifier = makeId(job.getId(),act.getLocation().getId()); String currIdentifier = makeId(job.getId(), act.getLocation().getId());
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);
} }
if(route.getVehicle().isReturnToDepot()){ if (route.getVehicle().isReturnToDepot()) {
String lastIdentifier = makeId(route.getVehicle().getId(),route.getVehicle().getEndLocation().getId()); String lastIdentifier = makeId(route.getVehicle().getId(), route.getVehicle().getEndLocation().getId());
g.addEdge(makeEdgeId(routeId,vehicle_edgeId), prevIdentifier, lastIdentifier, true); g.addEdge(makeEdgeId(routeId, vehicle_edgeId), prevIdentifier, lastIdentifier, true);
} }
} }

View file

@ -18,7 +18,7 @@
******************************************************************************/ ******************************************************************************/
package jsprit.analysis.toolbox; package jsprit.analysis.toolbox;
class NoLocationFoundException extends Exception{ class NoLocationFoundException extends Exception {
/** /**
* *

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 {
@ -74,12 +73,12 @@ public class Plotter {
private XYSeriesCollection seriesCollection; private XYSeriesCollection seriesCollection;
private Map<XYDataItem,Activity> activities; private Map<XYDataItem, Activity> activities;
private Set<XYDataItem> firstActivities; private Set<XYDataItem> firstActivities;
public MyActivityRenderer(XYSeriesCollection seriesCollection,Map<XYDataItem, Activity> activities,Set<XYDataItem> firstActivities) { public MyActivityRenderer(XYSeriesCollection seriesCollection, Map<XYDataItem, Activity> activities, Set<XYDataItem> firstActivities) {
super(false,true); super(false, true);
this.seriesCollection = seriesCollection; this.seriesCollection = seriesCollection;
this.activities = activities; this.activities = activities;
this.firstActivities = firstActivities; this.firstActivities = firstActivities;
@ -90,7 +89,7 @@ public class Plotter {
@Override @Override
public Shape getItemShape(int seriesIndex, int itemIndex) { public Shape getItemShape(int seriesIndex, int itemIndex) {
XYDataItem dataItem = seriesCollection.getSeries(seriesIndex).getDataItem(itemIndex); XYDataItem dataItem = seriesCollection.getSeries(seriesIndex).getDataItem(itemIndex);
if(firstActivities.contains(dataItem)){ if (firstActivities.contains(dataItem)) {
return ShapeUtilities.createUpTriangle(4.0f); return ShapeUtilities.createUpTriangle(4.0f);
} }
return ELLIPSE; return ELLIPSE;
@ -99,7 +98,7 @@ public class Plotter {
@Override @Override
public Paint getItemOutlinePaint(int seriesIndex, int itemIndex) { public Paint getItemOutlinePaint(int seriesIndex, int itemIndex) {
XYDataItem dataItem = seriesCollection.getSeries(seriesIndex).getDataItem(itemIndex); XYDataItem dataItem = seriesCollection.getSeries(seriesIndex).getDataItem(itemIndex);
if(firstActivities.contains(dataItem)){ if (firstActivities.contains(dataItem)) {
return Color.BLACK; return Color.BLACK;
} }
return super.getItemOutlinePaint(seriesIndex, itemIndex); return super.getItemOutlinePaint(seriesIndex, itemIndex);
@ -109,12 +108,12 @@ public class Plotter {
public Paint getItemPaint(int seriesIndex, int itemIndex) { public Paint getItemPaint(int seriesIndex, int itemIndex) {
XYDataItem dataItem = seriesCollection.getSeries(seriesIndex).getDataItem(itemIndex); XYDataItem dataItem = seriesCollection.getSeries(seriesIndex).getDataItem(itemIndex);
Activity activity = activities.get(dataItem); Activity activity = activities.get(dataItem);
if(activity.equals(Activity.PICKUP)) return PICKUP_COLOR; if (activity.equals(Activity.PICKUP)) return PICKUP_COLOR;
if(activity.equals(Activity.DELIVERY)) return DELIVERY_COLOR; if (activity.equals(Activity.DELIVERY)) return DELIVERY_COLOR;
if(activity.equals(Activity.SERVICE)) return SERVICE_COLOR; if (activity.equals(Activity.SERVICE)) return SERVICE_COLOR;
if(activity.equals(Activity.START)) return START_COLOR; if (activity.equals(Activity.START)) return START_COLOR;
if(activity.equals(Activity.END)) return END_COLOR; if (activity.equals(Activity.END)) return END_COLOR;
throw new IllegalStateException("activity at "+dataItem.toString()+" cannot be assigned to a color"); throw new IllegalStateException("activity at " + dataItem.toString() + " cannot be assigned to a color");
} }
} }
@ -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
@ -162,9 +162,9 @@ public class Plotter {
private BoundingBox boundingBox = null; private BoundingBox boundingBox = null;
private Map<XYDataItem,Activity> activitiesByDataItem = new HashMap<XYDataItem, Plotter.Activity>(); private Map<XYDataItem, Activity> activitiesByDataItem = new HashMap<XYDataItem, Plotter.Activity>();
private Map<XYDataItem,String> labelsByDataItem = new HashMap<XYDataItem, String>(); private Map<XYDataItem, String> labelsByDataItem = new HashMap<XYDataItem, String>();
private XYSeries activities; private XYSeries activities;
@ -217,22 +217,23 @@ public class Plotter {
} }
@SuppressWarnings("UnusedDeclaration") @SuppressWarnings("UnusedDeclaration")
public Plotter setScalingFactor(double scalingFactor){ public Plotter setScalingFactor(double scalingFactor) {
this.scalingFactor=scalingFactor; this.scalingFactor = scalingFactor;
return this; return this;
} }
/** /**
* Sets a label. * Sets a label.
*
* @param label of jobs * @param label of jobs
* @return plotter * @return plotter
*/ */
public Plotter setLabel(Label label){ public Plotter setLabel(Label label) {
this.label = label; this.label = label;
return this; return this;
} }
public Plotter invertCoordinates(boolean invert){ public Plotter invertCoordinates(boolean invert) {
this.invert = invert; this.invert = invert;
return this; return this;
} }
@ -247,8 +248,8 @@ public class Plotter {
* @return * @return
*/ */
@SuppressWarnings("UnusedDeclaration") @SuppressWarnings("UnusedDeclaration")
public Plotter setBoundingBox(double minX, double minY, double maxX, double maxY){ public Plotter setBoundingBox(double minX, double minY, double maxX, double maxY) {
boundingBox = new BoundingBox(minX,minY,maxX,maxY); boundingBox = new BoundingBox(minX, minY, maxX, maxY);
return this; return this;
} }
@ -269,21 +270,19 @@ public class Plotter {
* @param pngFileName - path and filename * @param pngFileName - path and filename
* @param plotTitle - title that appears on top of image * @param plotTitle - title that appears on top of image
*/ */
public void plot(String pngFileName, String plotTitle){ public void plot(String pngFileName, String plotTitle) {
String filename = pngFileName; String filename = pngFileName;
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);
} }
} }
private void plot(VehicleRoutingProblem vrp, final Collection<VehicleRoute> routes, String pngFile, String title){ private void plot(VehicleRoutingProblem vrp, final Collection<VehicleRoute> routes, String pngFile, String title) {
log.info("plot to " + pngFile); log.info("plot to " + pngFile);
XYSeriesCollection problem; XYSeriesCollection problem;
XYSeriesCollection solution = null; XYSeriesCollection solution = null;
@ -292,7 +291,7 @@ public class Plotter {
retrieveActivities(vrp); retrieveActivities(vrp);
problem = new XYSeriesCollection(activities); problem = new XYSeriesCollection(activities);
shipments = makeShipmentSeries(vrp.getJobs().values()); shipments = makeShipmentSeries(vrp.getJobs().values());
if(routes!=null) solution = makeSolutionSeries(vrp, routes); if (routes != null) solution = makeSolutionSeries(vrp, routes);
} catch (NoLocationFoundException e) { } catch (NoLocationFoundException e) {
log.warn("cannot plot vrp, since coord is missing"); log.warn("cannot plot vrp, since coord is missing");
return; return;
@ -304,11 +303,11 @@ public class Plotter {
chart.removeLegend(); chart.removeLegend();
chart.addLegend(legend); chart.addLegend(legend);
save(chart,pngFile); save(chart, pngFile);
} }
private LegendTitle createLegend(final Collection<VehicleRoute> routes,final XYSeriesCollection shipments, final XYPlot plot) { private LegendTitle createLegend(final Collection<VehicleRoute> routes, final XYSeriesCollection shipments, final XYPlot plot) {
LegendItemSource lis = new LegendItemSource() { LegendItemSource lis = new LegendItemSource() {
@Override @Override
@ -318,26 +317,26 @@ public class Plotter {
vehLoc.setShape(ELLIPSE); vehLoc.setShape(ELLIPSE);
vehLoc.setShapeVisible(true); vehLoc.setShapeVisible(true);
lic.add(vehLoc); lic.add(vehLoc);
if(containsServiceAct){ if (containsServiceAct) {
LegendItem item = new LegendItem("service", Color.BLUE); LegendItem item = new LegendItem("service", Color.BLUE);
item.setShape(ELLIPSE); item.setShape(ELLIPSE);
item.setShapeVisible(true); item.setShapeVisible(true);
lic.add(item); lic.add(item);
} }
if(containsPickupAct){ if (containsPickupAct) {
LegendItem item = new LegendItem("pickup", Color.GREEN); LegendItem item = new LegendItem("pickup", Color.GREEN);
item.setShape(ELLIPSE); item.setShape(ELLIPSE);
item.setShapeVisible(true); item.setShapeVisible(true);
lic.add(item); lic.add(item);
} }
if(containsDeliveryAct){ if (containsDeliveryAct) {
LegendItem item = new LegendItem("delivery", Color.BLUE); LegendItem item = new LegendItem("delivery", Color.BLUE);
item.setShape(ELLIPSE); item.setShape(ELLIPSE);
item.setShapeVisible(true); item.setShapeVisible(true);
lic.add(item); lic.add(item);
} }
if(routes!=null){ if (routes != null) {
LegendItem item = new LegendItem("firstActivity",Color.BLACK); LegendItem item = new LegendItem("firstActivity", Color.BLACK);
Shape upTriangle = ShapeUtilities.createUpTriangle(3.0f); Shape upTriangle = ShapeUtilities.createUpTriangle(3.0f);
item.setShape(upTriangle); item.setShape(upTriangle);
item.setOutlinePaint(Color.BLACK); item.setOutlinePaint(Color.BLACK);
@ -348,10 +347,10 @@ public class Plotter {
lic.add(item); lic.add(item);
} }
if(!shipments.getSeries().isEmpty()){ if (!shipments.getSeries().isEmpty()) {
lic.add(plot.getRenderer(1).getLegendItem(1, 0)); lic.add(plot.getRenderer(1).getLegendItem(1, 0));
} }
if(routes!=null){ if (routes != null) {
lic.addAll(plot.getRenderer(2).getLegendItems()); lic.addAll(plot.getRenderer(2).getLegendItems());
} }
return lic; return lic;
@ -365,18 +364,18 @@ public class Plotter {
private XYItemRenderer getShipmentRenderer(XYSeriesCollection shipments) { private XYItemRenderer getShipmentRenderer(XYSeriesCollection shipments) {
XYItemRenderer shipmentsRenderer = new XYLineAndShapeRenderer(true, false); // Shapes only XYItemRenderer shipmentsRenderer = new XYLineAndShapeRenderer(true, false); // Shapes only
for(int i=0;i<shipments.getSeriesCount();i++){ for (int i = 0; i < shipments.getSeriesCount(); i++) {
shipmentsRenderer.setSeriesPaint(i, Color.DARK_GRAY); shipmentsRenderer.setSeriesPaint(i, Color.DARK_GRAY);
shipmentsRenderer.setSeriesStroke(i, new BasicStroke( shipmentsRenderer.setSeriesStroke(i, new BasicStroke(
1.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 1.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND,
1.f, new float[] {4.0f, 4.0f}, 0.0f 1.f, new float[]{4.0f, 4.0f}, 0.0f
)); ));
} }
return shipmentsRenderer; return shipmentsRenderer;
} }
private MyActivityRenderer getProblemRenderer(final XYSeriesCollection problem) { private MyActivityRenderer getProblemRenderer(final XYSeriesCollection problem) {
MyActivityRenderer problemRenderer = new MyActivityRenderer(problem, activitiesByDataItem,firstActivities); MyActivityRenderer problemRenderer = new MyActivityRenderer(problem, activitiesByDataItem, firstActivities);
problemRenderer.setBaseItemLabelGenerator(new XYItemLabelGenerator() { problemRenderer.setBaseItemLabelGenerator(new XYItemLabelGenerator() {
@Override @Override
@ -393,12 +392,12 @@ public class Plotter {
} }
private Range getRange(final XYSeriesCollection seriesCol) { private Range getRange(final XYSeriesCollection seriesCol) {
if(this.boundingBox==null) return seriesCol.getRangeBounds(false); if (this.boundingBox == null) return seriesCol.getRangeBounds(false);
else return new Range(boundingBox.minY, boundingBox.maxY); else return new Range(boundingBox.minY, boundingBox.maxY);
} }
private Range getDomainRange(final XYSeriesCollection seriesCol) { private Range getDomainRange(final XYSeriesCollection seriesCol) {
if(this.boundingBox == null) return seriesCol.getDomainBounds(true); if (this.boundingBox == null) return seriesCol.getDomainBounds(true);
else return new Range(boundingBox.minX, boundingBox.maxX); else return new Range(boundingBox.minX, boundingBox.maxX);
} }
@ -416,7 +415,7 @@ public class Plotter {
plot.setDataset(1, shipments); plot.setDataset(1, shipments);
plot.setRenderer(1, shipmentsRenderer); plot.setRenderer(1, shipmentsRenderer);
if(solution != null){ if (solution != null) {
XYItemRenderer solutionRenderer = getRouteRenderer(solution); XYItemRenderer solutionRenderer = getRouteRenderer(solution);
plot.setDataset(2, solution); plot.setDataset(2, solution);
plot.setRenderer(2, solutionRenderer); plot.setRenderer(2, solutionRenderer);
@ -425,11 +424,10 @@ public class Plotter {
NumberAxis xAxis = new NumberAxis(); NumberAxis xAxis = new NumberAxis();
NumberAxis yAxis = new NumberAxis(); NumberAxis yAxis = new NumberAxis();
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));
} }
@ -442,7 +440,7 @@ public class Plotter {
private XYItemRenderer getRouteRenderer(XYSeriesCollection solutionColl) { private XYItemRenderer getRouteRenderer(XYSeriesCollection solutionColl) {
XYItemRenderer solutionRenderer = new XYLineAndShapeRenderer(true, false); // Lines only XYItemRenderer solutionRenderer = new XYLineAndShapeRenderer(true, false); // Lines only
for(int i=0;i<solutionColl.getSeriesCount();i++){ for (int i = 0; i < solutionColl.getSeriesCount(); i++) {
XYSeries s = solutionColl.getSeries(i); XYSeries s = solutionColl.getSeries(i);
XYDataItem firstCustomer = s.getDataItem(1); XYDataItem firstCustomer = s.getDataItem(1);
firstActivities.add(firstCustomer); firstActivities.add(firstCustomer);
@ -460,24 +458,24 @@ public class Plotter {
} }
} }
private XYSeriesCollection makeSolutionSeries(VehicleRoutingProblem vrp, Collection<VehicleRoute> routes) throws NoLocationFoundException{ private XYSeriesCollection makeSolutionSeries(VehicleRoutingProblem vrp, Collection<VehicleRoute> routes) throws NoLocationFoundException {
Locations locations = retrieveLocations(vrp); Locations locations = retrieveLocations(vrp);
XYSeriesCollection coll = new XYSeriesCollection(); XYSeriesCollection coll = new XYSeriesCollection();
int counter = 1; int counter = 1;
for(VehicleRoute route : routes){ for (VehicleRoute route : routes) {
if(route.isEmpty()) continue; if (route.isEmpty()) continue;
XYSeries series = new XYSeries(counter, false, true); XYSeries series = new XYSeries(counter, false, true);
Coordinate startCoord = getCoordinate(locations.getCoord(route.getStart().getLocation().getId())); Coordinate startCoord = getCoordinate(locations.getCoord(route.getStart().getLocation().getId()));
series.add(startCoord.getX()*scalingFactor, startCoord.getY()*scalingFactor); series.add(startCoord.getX() * scalingFactor, startCoord.getY() * scalingFactor);
for(TourActivity act : route.getTourActivities().getActivities()){ for (TourActivity act : route.getTourActivities().getActivities()) {
Coordinate coord = getCoordinate(locations.getCoord(act.getLocation().getId())); Coordinate coord = getCoordinate(locations.getCoord(act.getLocation().getId()));
series.add(coord.getX()*scalingFactor, coord.getY()*scalingFactor); series.add(coord.getX() * scalingFactor, coord.getY() * scalingFactor);
} }
Coordinate endCoord = getCoordinate(locations.getCoord(route.getEnd().getLocation().getId())); Coordinate endCoord = getCoordinate(locations.getCoord(route.getEnd().getLocation().getId()));
series.add(endCoord.getX()*scalingFactor, endCoord.getY()*scalingFactor); series.add(endCoord.getX() * scalingFactor, endCoord.getY() * scalingFactor);
coll.addSeries(series); coll.addSeries(series);
counter++; counter++;
@ -485,89 +483,83 @@ public class Plotter {
return coll; return coll;
} }
private XYSeriesCollection makeShipmentSeries(Collection<Job> jobs) throws NoLocationFoundException{ private XYSeriesCollection makeShipmentSeries(Collection<Job> jobs) throws NoLocationFoundException {
XYSeriesCollection coll = new XYSeriesCollection(); XYSeriesCollection coll = new XYSeriesCollection();
if(!plotShipments) return coll; if (!plotShipments) return coll;
int sCounter = 1; int sCounter = 1;
String ship = "shipment"; String ship = "shipment";
boolean first = true; boolean first = true;
for(Job job : jobs){ for (Job job : jobs) {
if(!(job instanceof Shipment)){ if (!(job instanceof Shipment)) {
continue; continue;
} }
Shipment shipment = (Shipment)job; Shipment shipment = (Shipment) job;
XYSeries shipmentSeries; XYSeries shipmentSeries;
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++;
} }
Coordinate pickupCoordinate = getCoordinate(shipment.getPickupLocation().getCoordinate()); Coordinate pickupCoordinate = getCoordinate(shipment.getPickupLocation().getCoordinate());
Coordinate delCoordinate = getCoordinate(shipment.getDeliveryLocation().getCoordinate()); Coordinate delCoordinate = getCoordinate(shipment.getDeliveryLocation().getCoordinate());
shipmentSeries.add(pickupCoordinate.getX()*scalingFactor, pickupCoordinate.getY()*scalingFactor); shipmentSeries.add(pickupCoordinate.getX() * scalingFactor, pickupCoordinate.getY() * scalingFactor);
shipmentSeries.add(delCoordinate.getX()*scalingFactor, delCoordinate.getY()*scalingFactor); shipmentSeries.add(delCoordinate.getX() * scalingFactor, delCoordinate.getY() * scalingFactor);
coll.addSeries(shipmentSeries); coll.addSeries(shipmentSeries);
} }
return coll; return coll;
} }
private void addJob(XYSeries activities, Job job) { private void addJob(XYSeries activities, Job job) {
if(job instanceof Shipment){ if (job instanceof Shipment) {
Shipment s = (Shipment)job; Shipment s = (Shipment) job;
Coordinate pickupCoordinate = getCoordinate(s.getPickupLocation().getCoordinate()); Coordinate pickupCoordinate = getCoordinate(s.getPickupLocation().getCoordinate());
XYDataItem dataItem = new XYDataItem(pickupCoordinate.getX()*scalingFactor, pickupCoordinate.getY()*scalingFactor); XYDataItem dataItem = new XYDataItem(pickupCoordinate.getX() * scalingFactor, pickupCoordinate.getY() * scalingFactor);
activities.add(dataItem); activities.add(dataItem);
addLabel(s, dataItem); addLabel(s, dataItem);
markItem(dataItem,Activity.PICKUP); markItem(dataItem, Activity.PICKUP);
containsPickupAct = true; containsPickupAct = true;
Coordinate deliveryCoordinate = getCoordinate(s.getDeliveryLocation().getCoordinate()); Coordinate deliveryCoordinate = getCoordinate(s.getDeliveryLocation().getCoordinate());
XYDataItem dataItem2 = new XYDataItem(deliveryCoordinate.getX()*scalingFactor, deliveryCoordinate.getY()*scalingFactor); XYDataItem dataItem2 = new XYDataItem(deliveryCoordinate.getX() * scalingFactor, deliveryCoordinate.getY() * scalingFactor);
activities.add(dataItem2); activities.add(dataItem2);
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);
activities.add(dataItem); activities.add(dataItem);
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);
activities.add(dataItem); activities.add(dataItem);
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);
activities.add(dataItem); activities.add(dataItem);
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.");
} }
} }
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()));
} }
} }
@ -576,12 +568,11 @@ public class Plotter {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
builder.append("("); builder.append("(");
boolean firstDim = true; boolean firstDim = true;
for(int i=0;i<job.getSize().getNuOfDimensions();i++){ for (int i = 0; i < job.getSize().getNuOfDimensions(); i++) {
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)));
} }
@ -590,42 +581,42 @@ public class Plotter {
return builder.toString(); return builder.toString();
} }
private Coordinate getCoordinate(Coordinate coordinate){ private Coordinate getCoordinate(Coordinate coordinate) {
if(invert){ if (invert) {
return Coordinate.newInstance(coordinate.getY(),coordinate.getX()); return Coordinate.newInstance(coordinate.getY(), coordinate.getX());
} }
return coordinate; return coordinate;
} }
private void retrieveActivities(VehicleRoutingProblem vrp) throws NoLocationFoundException{ private void retrieveActivities(VehicleRoutingProblem vrp) throws NoLocationFoundException {
activities = new XYSeries("activities", false, true); activities = new XYSeries("activities", false, true);
for(Vehicle v : vrp.getVehicles()){ for (Vehicle v : vrp.getVehicles()) {
Coordinate start_coordinate = getCoordinate(v.getStartLocation().getCoordinate()); Coordinate start_coordinate = getCoordinate(v.getStartLocation().getCoordinate());
if(start_coordinate == null) throw new NoLocationFoundException(); if (start_coordinate == null) throw new NoLocationFoundException();
XYDataItem item = new XYDataItem(start_coordinate.getX()*scalingFactor, start_coordinate.getY()*scalingFactor); XYDataItem item = new XYDataItem(start_coordinate.getX() * scalingFactor, start_coordinate.getY() * scalingFactor);
markItem(item,Activity.START); markItem(item, Activity.START);
activities.add(item); activities.add(item);
if(!v.getStartLocation().getId().equals(v.getEndLocation().getId())){ if (!v.getStartLocation().getId().equals(v.getEndLocation().getId())) {
Coordinate end_coordinate = getCoordinate(v.getEndLocation().getCoordinate()); Coordinate end_coordinate = getCoordinate(v.getEndLocation().getCoordinate());
if(end_coordinate == null) throw new NoLocationFoundException(); if (end_coordinate == null) throw new NoLocationFoundException();
XYDataItem end_item = new XYDataItem(end_coordinate.getX()*scalingFactor,end_coordinate.getY()*scalingFactor); XYDataItem end_item = new XYDataItem(end_coordinate.getX() * scalingFactor, end_coordinate.getY() * scalingFactor);
markItem(end_item,Activity.END); markItem(end_item, Activity.END);
activities.add(end_item); activities.add(end_item);
} }
} }
for(Job job : vrp.getJobs().values()){ for (Job job : vrp.getJobs().values()) {
addJob(activities, job); addJob(activities, job);
} }
for(VehicleRoute r : vrp.getInitialVehicleRoutes()){ for (VehicleRoute r : vrp.getInitialVehicleRoutes()) {
for(Job job : r.getTourActivities().getJobs()){ for (Job job : r.getTourActivities().getJobs()) {
addJob(activities, job); addJob(activities, job);
} }
} }
} }
private void markItem(XYDataItem item, Activity activity) { private void markItem(XYDataItem item, Activity activity) {
activitiesByDataItem.put(item,activity); activitiesByDataItem.put(item, activity);
} }
private Locations retrieveLocations(VehicleRoutingProblem vrp) throws NoLocationFoundException { private Locations retrieveLocations(VehicleRoutingProblem vrp) throws NoLocationFoundException {

View file

@ -27,7 +27,7 @@ import org.apache.logging.log4j.Logger;
import java.util.Collection; import java.util.Collection;
public class StopWatch implements AlgorithmStartsListener, AlgorithmEndsListener{ public class StopWatch implements AlgorithmStartsListener, AlgorithmEndsListener {
private static Logger log = LogManager.getLogger(StopWatch.class); private static Logger log = LogManager.getLogger(StopWatch.class);
@ -42,8 +42,8 @@ public class StopWatch implements AlgorithmStartsListener, AlgorithmEndsListener
start(); start();
} }
public double getCompTimeInSeconds(){ public double getCompTimeInSeconds() {
return (ran)/1000.0; return (ran) / 1000.0;
} }
@Override @Override
@ -52,15 +52,15 @@ public class StopWatch implements AlgorithmStartsListener, AlgorithmEndsListener
log.info("computation time [in sec]: " + getCompTimeInSeconds()); log.info("computation time [in sec]: " + getCompTimeInSeconds());
} }
public void stop(){ public void stop() {
ran += System.currentTimeMillis() - startTime; ran += System.currentTimeMillis() - startTime;
} }
public void start(){ public void start() {
startTime = System.currentTimeMillis(); startTime = System.currentTimeMillis();
} }
public void reset(){ public void reset() {
startTime = 0; startTime = 0;
ran = 0; ran = 0;
} }
@ -71,7 +71,7 @@ public class StopWatch implements AlgorithmStartsListener, AlgorithmEndsListener
} }
public double getCurrTimeInSeconds() { public double getCurrTimeInSeconds() {
return (System.currentTimeMillis()-startTime)/1000.0; return (System.currentTimeMillis() - startTime) / 1000.0;
} }
} }

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 {
@ -44,7 +42,7 @@ public class XYLineChartBuilder {
* @param chart * @param chart
* @param pngFilename * @param pngFilename
*/ */
public static void saveChartAsPNG(JFreeChart chart, String pngFilename){ public static void saveChartAsPNG(JFreeChart chart, String pngFilename) {
try { try {
ChartUtilities.saveChartAsPNG(new File(pngFilename), chart, 1000, 600); ChartUtilities.saveChartAsPNG(new File(pngFilename), chart, 1000, 600);
} catch (IOException e) { } catch (IOException e) {
@ -58,14 +56,13 @@ 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) {
return new XYLineChartBuilder(chartTitle, xDomainName, yDomainName); return new XYLineChartBuilder(chartTitle, xDomainName, yDomainName);
} }
private ConcurrentHashMap<String,XYSeries> seriesMap = new ConcurrentHashMap<String, XYSeries>(); private ConcurrentHashMap<String, XYSeries> seriesMap = new ConcurrentHashMap<String, XYSeries>();
private final String xDomain; private final String xDomain;
@ -74,9 +71,9 @@ public class XYLineChartBuilder {
private final String chartName; private final String chartName;
private XYLineChartBuilder(String chartName, String xDomainName, String yDomainName) { private XYLineChartBuilder(String chartName, String xDomainName, String yDomainName) {
this.xDomain=xDomainName; this.xDomain = xDomainName;
this.yDomain=yDomainName; this.yDomain = yDomainName;
this.chartName=chartName; this.chartName = chartName;
} }
/** /**
@ -86,20 +83,21 @@ public class XYLineChartBuilder {
* @param xVal * @param xVal
* @param yVal * @param yVal
*/ */
public void addData(String seriesName, double xVal, double yVal){ public void addData(String seriesName, double xVal, double yVal) {
if(!seriesMap.containsKey(seriesName)){ if (!seriesMap.containsKey(seriesName)) {
seriesMap.put(seriesName, new XYSeries(seriesName,true,true)); seriesMap.put(seriesName, new XYSeries(seriesName, true, true));
} }
seriesMap.get(seriesName).add(xVal, yVal); seriesMap.get(seriesName).add(xVal, yVal);
} }
/** /**
* Builds and returns JFreeChart. * Builds and returns JFreeChart.
*
* @return * @return
*/ */
public JFreeChart build(){ public JFreeChart build() {
XYSeriesCollection collection = new XYSeriesCollection(); XYSeriesCollection collection = new XYSeriesCollection();
for(XYSeries s : seriesMap.values()){ for (XYSeries s : seriesMap.values()) {
collection.addSeries(s); collection.addSeries(s);
} }
JFreeChart chart = ChartFactory.createXYLineChart(chartName, xDomain, yDomain, collection, PlotOrientation.VERTICAL, true, true, false); JFreeChart chart = ChartFactory.createXYLineChart(chartName, xDomain, yDomain, collection, PlotOrientation.VERTICAL, true, true, false);

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,15 +16,15 @@
******************************************************************************/ ******************************************************************************/
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;
@ -43,8 +43,8 @@ public class HtmlBenchmarkTableWriter implements BenchmarkWriter{
writer.write(head("inst") + newline()); writer.write(head("inst") + newline());
writer.write(head("runs") + newline()); writer.write(head("runs") + newline());
writer.write(head("&Oslash; time [sec]") + newline()); writer.write(head("&Oslash; time [sec]") + newline());
writer.write(head("results",4)); writer.write(head("results", 4));
writer.write(head("vehicles",4)); writer.write(head("vehicles", 4));
writer.write(head("res*") + newline()); writer.write(head("res*") + newline());
writer.write(head("veh*") + newline()); writer.write(head("veh*") + newline());
writer.write(closeRow() + newline()); writer.write(closeRow() + newline());
@ -78,40 +78,40 @@ public class HtmlBenchmarkTableWriter implements BenchmarkWriter{
double sum_dev_veh = 0.0; double sum_dev_veh = 0.0;
Integer runs = null; Integer runs = null;
Double sum_res_star=null; Double sum_res_star = null;
Double sum_veh_star=null; Double sum_veh_star = null;
for(BenchmarkResult result : results){ for (BenchmarkResult result : results) {
if(runs==null) runs=result.runs; if (runs == null) runs = result.runs;
writer.write(openRow() + newline()); writer.write(openRow() + newline());
writer.write(date(result.instance.name) + newline()); writer.write(date(result.instance.name) + newline());
writer.write(date(Integer.valueOf(result.runs).toString()) + newline()); writer.write(date(Integer.valueOf(result.runs).toString()) + newline());
Double avg_time = round(result.getTimesStats().getMean(),2); Double avg_time = round(result.getTimesStats().getMean(), 2);
writer.write(date(Double.valueOf(avg_time).toString()) + newline()); writer.write(date(Double.valueOf(avg_time).toString()) + newline());
//bestRes //bestRes
Double best_result = round(result.getResultStats().getMin(),2); Double best_result = round(result.getResultStats().getMin(), 2);
writer.write(date(Double.valueOf(best_result).toString()) + newline()); writer.write(date(Double.valueOf(best_result).toString()) + newline());
//avgRes //avgRes
Double avg_result = round(result.getResultStats().getMean(),2); Double avg_result = round(result.getResultStats().getMean(), 2);
writer.write(date(Double.valueOf(avg_result).toString()) + newline()); writer.write(date(Double.valueOf(avg_result).toString()) + newline());
//worstRes //worstRes
Double worst_result = round(result.getResultStats().getMax(),2); Double worst_result = round(result.getResultStats().getMax(), 2);
writer.write(date(Double.valueOf(worst_result).toString()) + newline()); writer.write(date(Double.valueOf(worst_result).toString()) + newline());
//stdevRes //stdevRes
Double std_result = round(result.getResultStats().getStandardDeviation(),2); Double std_result = round(result.getResultStats().getStandardDeviation(), 2);
writer.write(date(Double.valueOf(std_result).toString()) + newline()); writer.write(date(Double.valueOf(std_result).toString()) + newline());
//bestVeh //bestVeh
Double best_vehicle = round(result.getVehicleStats().getMin(),2); Double best_vehicle = round(result.getVehicleStats().getMin(), 2);
writer.write(date(Double.valueOf(best_vehicle).toString()) + newline()); writer.write(date(Double.valueOf(best_vehicle).toString()) + newline());
//avgVeh //avgVeh
Double avg_vehicle = round(result.getVehicleStats().getMean(),2); Double avg_vehicle = round(result.getVehicleStats().getMean(), 2);
writer.write(date(Double.valueOf(avg_vehicle).toString()) + newline()); writer.write(date(Double.valueOf(avg_vehicle).toString()) + newline());
//worstVeh //worstVeh
Double worst_vehicle = round(result.getVehicleStats().getMax(),2); Double worst_vehicle = round(result.getVehicleStats().getMax(), 2);
writer.write(date(Double.valueOf(worst_vehicle).toString()) + newline()); writer.write(date(Double.valueOf(worst_vehicle).toString()) + newline());
//stdevVeh //stdevVeh
Double std_vehicle = round(result.getVehicleStats().getStandardDeviation(),2); Double std_vehicle = round(result.getVehicleStats().getStandardDeviation(), 2);
writer.write(date(Double.valueOf(std_vehicle).toString()) + newline()); writer.write(date(Double.valueOf(std_vehicle).toString()) + newline());
//bestKnownRes //bestKnownRes
writer.write(date("" + result.instance.bestKnownResult + newline())); writer.write(date("" + result.instance.bestKnownResult + newline()));
@ -119,71 +119,69 @@ public class HtmlBenchmarkTableWriter implements BenchmarkWriter{
writer.write(date("" + result.instance.bestKnownVehicles + newline())); writer.write(date("" + result.instance.bestKnownVehicles + newline()));
writer.write(closeRow() + newline()); writer.write(closeRow() + newline());
sum_avg_time+=avg_time; sum_avg_time += avg_time;
sum_best_result+=best_result; sum_best_result += best_result;
sum_avg_result+=avg_result; sum_avg_result += avg_result;
sum_worst_result+=worst_result; sum_worst_result += worst_result;
sum_dev_result+=std_result; sum_dev_result += std_result;
sum_best_veh+=best_vehicle; sum_best_veh += best_vehicle;
sum_avg_veh+=avg_vehicle; sum_avg_veh += avg_vehicle;
sum_worst_veh+=worst_vehicle; sum_worst_veh += worst_vehicle;
sum_dev_veh+=std_vehicle; sum_dev_veh += std_vehicle;
if(result.instance.bestKnownResult != null){ if (result.instance.bestKnownResult != null) {
if(sum_res_star==null) sum_res_star=result.instance.bestKnownResult; if (sum_res_star == null) sum_res_star = result.instance.bestKnownResult;
else sum_res_star+=result.instance.bestKnownResult; else sum_res_star += result.instance.bestKnownResult;
} }
if(result.instance.bestKnownVehicles != null){ if (result.instance.bestKnownVehicles != null) {
if(sum_veh_star==null) sum_veh_star=result.instance.bestKnownVehicles; if (sum_veh_star == null) sum_veh_star = result.instance.bestKnownVehicles;
else sum_veh_star+=result.instance.bestKnownVehicles; else sum_veh_star += result.instance.bestKnownVehicles;
} }
} }
writer.write(openRow() + newline()); writer.write(openRow() + newline());
writer.write(date("&Oslash;") + newline()); writer.write(date("&Oslash;") + newline());
writer.write(date(""+runs) + newline()); writer.write(date("" + runs) + newline());
Double average_time = round(sum_avg_time/(double)results.size(),2); Double average_time = round(sum_avg_time / (double) results.size(), 2);
writer.write(date(Double.valueOf(average_time).toString()) + newline()); writer.write(date(Double.valueOf(average_time).toString()) + newline());
//bestRes //bestRes
writer.write(date(Double.valueOf(round(sum_best_result/(double)results.size(),2)).toString()) + newline()); writer.write(date(Double.valueOf(round(sum_best_result / (double) results.size(), 2)).toString()) + newline());
//avgRes //avgRes
Double average_result = round(sum_avg_result/(double)results.size(),2); Double average_result = round(sum_avg_result / (double) results.size(), 2);
writer.write(date(Double.valueOf(average_result).toString()) + newline()); writer.write(date(Double.valueOf(average_result).toString()) + newline());
//worstRes //worstRes
writer.write(date(Double.valueOf(round(sum_worst_result/(double)results.size(),2)).toString()) + newline()); writer.write(date(Double.valueOf(round(sum_worst_result / (double) results.size(), 2)).toString()) + newline());
//stdevRes //stdevRes
writer.write(date(Double.valueOf(round(sum_dev_result/(double)results.size(),2)).toString()) + newline()); writer.write(date(Double.valueOf(round(sum_dev_result / (double) results.size(), 2)).toString()) + newline());
//bestVeh //bestVeh
writer.write(date(Double.valueOf(round(sum_best_veh/(double)results.size(),2)).toString()) + newline()); writer.write(date(Double.valueOf(round(sum_best_veh / (double) results.size(), 2)).toString()) + newline());
//avgVeh //avgVeh
Double average_vehicles = round(sum_avg_veh/(double)results.size(),2); Double average_vehicles = round(sum_avg_veh / (double) results.size(), 2);
writer.write(date(Double.valueOf(average_vehicles).toString()) + newline()); writer.write(date(Double.valueOf(average_vehicles).toString()) + newline());
//worstVeh //worstVeh
writer.write(date(Double.valueOf(round(sum_worst_veh/(double)results.size(),2)).toString()) + newline()); writer.write(date(Double.valueOf(round(sum_worst_veh / (double) results.size(), 2)).toString()) + newline());
//stdevVeh //stdevVeh
writer.write(date(Double.valueOf(round(sum_dev_veh/(double)results.size(),2)).toString()) + newline()); writer.write(date(Double.valueOf(round(sum_dev_veh / (double) results.size(), 2)).toString()) + newline());
//bestKnownRes //bestKnownRes
Double delta_res = null; Double delta_res = null;
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());
writer.write("avg. percentage deviation to best-known result: " + round(delta_res,2) + newline() + newline()); writer.write("avg. percentage deviation to best-known result: " + round(delta_res, 2) + newline() + newline());
writer.write("avg. absolute deviation to best-known vehicles: " + round(delta_veh,2) + newline()); writer.write("avg. absolute deviation to best-known vehicles: " + round(delta_veh, 2) + newline());
writer.write(openTable() + newline()); writer.write(openTable() + newline());
writer.write(openRow() + newline()); writer.write(openRow() + newline());
@ -191,15 +189,15 @@ public class HtmlBenchmarkTableWriter implements BenchmarkWriter{
writer.write(date("") + newline()); writer.write(date("") + newline());
writer.write(date("") + newline()); writer.write(date("") + newline());
writer.write(date("") + newline()); writer.write(date("") + newline());
writer.write(date(Double.valueOf(average_time).toString(),"align=\"right\"") + newline()); writer.write(date(Double.valueOf(average_time).toString(), "align=\"right\"") + newline());
writer.write(date(Double.valueOf(average_result).toString(),"align=\"right\"") + newline()); writer.write(date(Double.valueOf(average_result).toString(), "align=\"right\"") + newline());
writer.write(date(Double.valueOf(average_vehicles).toString(),"align=\"right\"") + newline()); writer.write(date(Double.valueOf(average_vehicles).toString(), "align=\"right\"") + newline());
if(delta_res != null){ if (delta_res != null) {
writer.write(date(Double.valueOf(round(delta_res,2)).toString(),"align=\"right\"") + newline()); writer.write(date(Double.valueOf(round(delta_res, 2)).toString(), "align=\"right\"") + newline());
}else writer.write(date("n.a.") + newline()); } else writer.write(date("n.a.") + newline());
if(delta_veh != null){ if (delta_veh != null) {
writer.write(date(Double.valueOf(round(delta_veh,2)).toString(),"align=\"right\"") + newline()); writer.write(date(Double.valueOf(round(delta_veh, 2)).toString(), "align=\"right\"") + newline());
}else writer.write(date("n.a.") + newline()); } else writer.write(date("n.a.") + newline());
writer.write(closeRow() + newline()); writer.write(closeRow() + newline());
writer.write(closeTable() + newline()); writer.write(closeTable() + newline());
@ -213,17 +211,17 @@ public class HtmlBenchmarkTableWriter implements BenchmarkWriter{
} }
private String head(String string, int i) { private String head(String string, int i) {
return "<th colspan=\""+i+"\">"+string+"</th>"; return "<th colspan=\"" + i + "\">" + string + "</th>";
} }
private Double round(Double value, int i) { private Double round(Double value, int i) {
if(value==null) return null; if (value == null) return null;
long roundedVal = Math.round(value*Math.pow(10, i)); long roundedVal = Math.round(value * Math.pow(10, i));
return (double)roundedVal/(double)(Math.pow(10, i)); return (double) roundedVal / (double) (Math.pow(10, i));
} }
private String head(String head) { private String head(String head) {
return "<th>"+head+"</th>"; return "<th>" + head + "</th>";
} }
private String closeTable() { private String closeTable() {
@ -239,11 +237,11 @@ public class HtmlBenchmarkTableWriter implements BenchmarkWriter{
} }
private String date(String date) { private String date(String date) {
return "<td>"+date+"</td>"; return "<td>" + date + "</td>";
} }
private String date(String date, String metaData) { private String date(String date, String metaData) {
return "<td " + metaData + ">"+date+"</td>"; return "<td " + metaData + ">" + date + "</td>";
} }
private String newline() { private String 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,17 +15,18 @@
~ 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>
<name>jsprit-core</name> <name>jsprit-core</name>
<build> <build>
<pluginManagement> <pluginManagement>
<plugins> <plugins>
<plugin> <plugin>
@ -46,7 +46,7 @@
</goals> </goals>
</pluginExecutionFilter> </pluginExecutionFilter>
<action> <action>
<ignore /> <ignore/>
</action> </action>
</pluginExecution> </pluginExecution>
</pluginExecutions> </pluginExecutions>
@ -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;
@ -36,8 +37,8 @@ import jsprit.core.util.ActivityTimeTracker;
import java.util.*; import java.util.*;
/** /**
* Created by schroeder on 10.12.14. * Created by schroeder on 10.12.14.
*/ */
public class PrettyAlgorithmBuilder { public class PrettyAlgorithmBuilder {
private final VehicleRoutingProblem vrp; private final VehicleRoutingProblem vrp;
@ -56,11 +57,11 @@ public class PrettyAlgorithmBuilder {
private boolean coreStuff = false; private boolean coreStuff = false;
public static PrettyAlgorithmBuilder newInstance(VehicleRoutingProblem vrp, VehicleFleetManager fleetManager, StateManager stateManager, ConstraintManager constraintManager){ public static PrettyAlgorithmBuilder newInstance(VehicleRoutingProblem vrp, VehicleFleetManager fleetManager, StateManager stateManager, ConstraintManager constraintManager) {
return new PrettyAlgorithmBuilder(vrp,fleetManager,stateManager,constraintManager); return new PrettyAlgorithmBuilder(vrp, fleetManager, stateManager, constraintManager);
} }
PrettyAlgorithmBuilder(VehicleRoutingProblem vrp, VehicleFleetManager fleetManager, StateManager stateManager, ConstraintManager constraintManager){ PrettyAlgorithmBuilder(VehicleRoutingProblem vrp, VehicleFleetManager fleetManager, StateManager stateManager, ConstraintManager constraintManager) {
this.vrp = vrp; this.vrp = vrp;
this.fleetManager = fleetManager; this.fleetManager = fleetManager;
this.stateManager = stateManager; this.stateManager = stateManager;
@ -68,40 +69,41 @@ public class PrettyAlgorithmBuilder {
this.searchStrategyManager = new SearchStrategyManager(); this.searchStrategyManager = new SearchStrategyManager();
} }
public PrettyAlgorithmBuilder setRandom(Random random){ public PrettyAlgorithmBuilder setRandom(Random random) {
searchStrategyManager.setRandom(random); searchStrategyManager.setRandom(random);
return this; return this;
} }
public PrettyAlgorithmBuilder withStrategy(SearchStrategy strategy, double weight){ public PrettyAlgorithmBuilder withStrategy(SearchStrategy strategy, double weight) {
searchStrategyManager.addStrategy(strategy,weight); searchStrategyManager.addStrategy(strategy, weight);
return this; return this;
} }
public PrettyAlgorithmBuilder constructInitialSolutionWith(InsertionStrategy insertionStrategy, SolutionCostCalculator objFunction){ public PrettyAlgorithmBuilder constructInitialSolutionWith(InsertionStrategy insertionStrategy, SolutionCostCalculator objFunction) {
this.iniInsertionStrategy = insertionStrategy; this.iniInsertionStrategy = insertionStrategy;
this.iniObjFunction = objFunction; this.iniObjFunction = objFunction;
return this; return this;
} }
public VehicleRoutingAlgorithm build(){ public VehicleRoutingAlgorithm build() {
if(coreStuff){ if (coreStuff) {
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>();
@Override @Override
public Collection<Vehicle> get(VehicleRoute vehicleRoute) { public Collection<Vehicle> get(VehicleRoute vehicleRoute) {
if(uniqueTypes.isEmpty()){ if (uniqueTypes.isEmpty()) {
for( Vehicle v : vrp.getVehicles()){ for (Vehicle v : vrp.getVehicles()) {
if(!uniqueTypes.containsKey(v.getVehicleTypeIdentifier())){ if (!uniqueTypes.containsKey(v.getVehicleTypeIdentifier())) {
uniqueTypes.put(v.getVehicleTypeIdentifier(),v); uniqueTypes.put(v.getVehicleTypeIdentifier(), v);
} }
} }
} }
@ -109,14 +111,16 @@ 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);
RemoveEmptyVehicles removeEmptyVehicles = new RemoveEmptyVehicles(fleetManager); RemoveEmptyVehicles removeEmptyVehicles = new RemoveEmptyVehicles(fleetManager);
ResetAndIniFleetManager resetAndIniFleetManager = new ResetAndIniFleetManager(fleetManager); ResetAndIniFleetManager resetAndIniFleetManager = new ResetAndIniFleetManager(fleetManager);
@ -124,7 +128,7 @@ public class PrettyAlgorithmBuilder {
vra.addListener(removeEmptyVehicles); vra.addListener(removeEmptyVehicles);
vra.addListener(resetAndIniFleetManager); vra.addListener(resetAndIniFleetManager);
vra.addListener(vehicleSwitched); vra.addListener(vehicleSwitched);
if(iniInsertionStrategy != null) { if (iniInsertionStrategy != null) {
if (!iniInsertionStrategy.getListeners().contains(removeEmptyVehicles)) if (!iniInsertionStrategy.getListeners().contains(removeEmptyVehicles))
iniInsertionStrategy.addListener(removeEmptyVehicles); iniInsertionStrategy.addListener(removeEmptyVehicles);
if (!iniInsertionStrategy.getListeners().contains(resetAndIniFleetManager)) if (!iniInsertionStrategy.getListeners().contains(resetAndIniFleetManager))
@ -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);
@ -150,10 +156,10 @@ public class PrettyAlgorithmBuilder {
private void searchSchrimpfAndRegister(VehicleRoutingAlgorithm vra) { private void searchSchrimpfAndRegister(VehicleRoutingAlgorithm vra) {
boolean schrimpfAdded = false; boolean schrimpfAdded = false;
for(SearchStrategy strategy : vra.getSearchStrategyManager().getStrategies()){ for (SearchStrategy strategy : vra.getSearchStrategyManager().getStrategies()) {
SolutionAcceptor acceptor = strategy.getSolutionAcceptor(); SolutionAcceptor acceptor = strategy.getSolutionAcceptor();
if(acceptor instanceof SchrimpfAcceptance){ if (acceptor instanceof SchrimpfAcceptance) {
if(!schrimpfAdded) { if (!schrimpfAdded) {
vra.addListener((SchrimpfAcceptance) acceptor); vra.addListener((SchrimpfAcceptance) acceptor);
schrimpfAdded = true; schrimpfAdded = true;
} }

View file

@ -25,7 +25,7 @@ import java.util.Collection;
import java.util.List; import java.util.List;
public class RemoveEmptyVehicles implements InsertionEndsListener{ public class RemoveEmptyVehicles implements InsertionEndsListener {
private VehicleFleetManager fleetManager; private VehicleFleetManager fleetManager;
@ -42,8 +42,8 @@ public class RemoveEmptyVehicles implements InsertionEndsListener{
@Override @Override
public void informInsertionEnds(Collection<VehicleRoute> vehicleRoutes) { public void informInsertionEnds(Collection<VehicleRoute> vehicleRoutes) {
List<VehicleRoute> routes = new ArrayList<VehicleRoute>(vehicleRoutes); List<VehicleRoute> routes = new ArrayList<VehicleRoute>(vehicleRoutes);
for(VehicleRoute route : routes){ for (VehicleRoute route : routes) {
if(route.isEmpty()) { if (route.isEmpty()) {
fleetManager.unlock(route.getVehicle()); fleetManager.unlock(route.getVehicle());
vehicleRoutes.remove(route); vehicleRoutes.remove(route);
} }

View file

@ -25,7 +25,7 @@ import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
public class ResetAndIniFleetManager implements InsertionStartsListener{ public class ResetAndIniFleetManager implements InsertionStartsListener {
private VehicleFleetManager vehicleFleetManager; private VehicleFleetManager vehicleFleetManager;
@ -38,7 +38,7 @@ public class ResetAndIniFleetManager implements InsertionStartsListener{
public void informInsertionStarts(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs) { public void informInsertionStarts(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs) {
vehicleFleetManager.unlockAll(); vehicleFleetManager.unlockAll();
Collection<VehicleRoute> routes = new ArrayList<VehicleRoute>(vehicleRoutes); Collection<VehicleRoute> routes = new ArrayList<VehicleRoute>(vehicleRoutes);
for(VehicleRoute route : routes){ for (VehicleRoute route : routes) {
vehicleFleetManager.lock(route.getVehicle()); vehicleFleetManager.lock(route.getVehicle());
} }
} }

View file

@ -60,11 +60,13 @@ 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() {
return "[strategyId="+strategyId+"][solution="+solution+"][accepted="+accepted+"]"; return "[strategyId=" + strategyId + "][solution=" + solution + "][accepted=" + accepted + "]";
} }
} }
@ -83,12 +85,12 @@ public class SearchStrategy {
private String name; private String name;
public SearchStrategy(String id, SolutionSelector solutionSelector, SolutionAcceptor solutionAcceptor, SolutionCostCalculator solutionCostCalculator) { public SearchStrategy(String id, SolutionSelector solutionSelector, SolutionAcceptor solutionAcceptor, SolutionCostCalculator solutionCostCalculator) {
if(id == null) throw new IllegalStateException("strategy id cannot be null"); if (id == null) throw new IllegalStateException("strategy id cannot be null");
this.solutionSelector = solutionSelector; this.solutionSelector = solutionSelector;
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() {
@ -119,12 +121,12 @@ public class SearchStrategy {
@Override @Override
public String toString() { public String toString() {
return "searchStrategy [#modules="+searchStrategyModules.size()+"][selector="+solutionSelector+"][acceptor="+solutionAcceptor+"]"; return "searchStrategy [#modules=" + searchStrategyModules.size() + "][selector=" + solutionSelector + "][acceptor=" + solutionAcceptor + "]";
} }
/** /**
* 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.
@ -136,11 +138,11 @@ public class SearchStrategy {
* @throws java.lang.IllegalStateException if selector cannot select any solution * @throws java.lang.IllegalStateException if selector cannot select any solution
*/ */
@SuppressWarnings("UnusedParameters") @SuppressWarnings("UnusedParameters")
public DiscoveredSolution run(VehicleRoutingProblem vrp, Collection<VehicleRoutingProblemSolution> solutions){ public DiscoveredSolution run(VehicleRoutingProblem vrp, Collection<VehicleRoutingProblemSolution> solutions) {
VehicleRoutingProblemSolution solution = solutionSelector.selectSolution(solutions); VehicleRoutingProblemSolution solution = solutionSelector.selectSolution(solutions);
if(solution == null) throw new IllegalStateException(getErrMsg()); if (solution == null) throw new IllegalStateException(getErrMsg());
VehicleRoutingProblemSolution lastSolution = VehicleRoutingProblemSolution.copyOf(solution); VehicleRoutingProblemSolution lastSolution = VehicleRoutingProblemSolution.copyOf(solution);
for(SearchStrategyModule module : searchStrategyModules){ for (SearchStrategyModule module : searchStrategyModules) {
lastSolution = module.runAndGetSolution(lastSolution); lastSolution = module.runAndGetSolution(lastSolution);
} }
double costs = solutionCostCalculator.getCosts(lastSolution); double costs = solutionCostCalculator.getCosts(lastSolution);
@ -156,14 +158,14 @@ 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) {
for(SearchStrategyModule module : searchStrategyModules){ for (SearchStrategyModule module : searchStrategyModules) {
module.addModuleListener(moduleListener); module.addModuleListener(moduleListener);
} }

View file

@ -35,7 +35,7 @@ public class SearchStrategyManager {
private List<Double> weights = new ArrayList<Double>(); private List<Double> weights = new ArrayList<Double>();
private Map<String, Integer> id2index = new HashMap<String,Integer>(); private Map<String, Integer> id2index = new HashMap<String, Integer>();
private Random random = RandomNumberGeneration.getRandom(); private Random random = RandomNumberGeneration.getRandom();
@ -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,36 +63,39 @@ 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));
} }
/** /**
* 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
*/ */
public void addStrategy(SearchStrategy strategy, double weight){ public void addStrategy(SearchStrategy strategy, double weight) {
if(strategy == null){ if (strategy == null) {
throw new IllegalStateException("strategy is null. make sure adding a valid strategy."); throw new IllegalStateException("strategy is null. make sure adding a valid strategy.");
} }
if(id2index.keySet().contains(strategy.getId())){ if (id2index.keySet().contains(strategy.getId())) {
throw new IllegalStateException("strategyId " + strategy.getId() + " already in use. replace strateId in your config file or code with a unique strategy id"); throw new IllegalStateException("strategyId " + strategy.getId() + " already in use. replace strateId in your config file or code with a unique strategy id");
} }
if(weight < 0.0){ if (weight < 0.0) {
throw new IllegalStateException("weight is lower than zero."); throw new IllegalStateException("weight is lower than zero.");
} }
id2index.put(strategy.getId(),strategyIndex); id2index.put(strategy.getId(), strategyIndex);
strategyIndex++; strategyIndex++;
strategies.add(strategy); strategies.add(strategy);
weights.add(weight); weights.add(weight);
sumWeights += weight; sumWeights += weight;
} }
public void informStrategyWeightChanged(String strategyId, double weight){ public void informStrategyWeightChanged(String strategyId, double weight) {
int strategyIndex = id2index.get(strategyId); int strategyIndex = id2index.get(strategyId);
weights.set(strategyIndex, weight); weights.set(strategyIndex, weight);
updateSumWeights(); updateSumWeights();
@ -99,7 +103,7 @@ public class SearchStrategyManager {
private void updateSumWeights() { private void updateSumWeights() {
double sum = 0.; double sum = 0.;
for(double w : weights){ for (double w : weights) {
sum += w; sum += w;
} }
sumWeights = sum; sumWeights = sum;
@ -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++) {
@ -124,12 +129,12 @@ public class SearchStrategyManager {
throw new IllegalStateException("no search-strategy found"); throw new IllegalStateException("no search-strategy found");
} }
public void addSearchStrategyListener(SearchStrategyListener strategyListener){ public void addSearchStrategyListener(SearchStrategyListener strategyListener) {
searchStrategyListeners.add(strategyListener); searchStrategyListeners.add(strategyListener);
} }
public void addSearchStrategyModuleListener(SearchStrategyModuleListener moduleListener){ public void addSearchStrategyModuleListener(SearchStrategyModuleListener moduleListener) {
for(SearchStrategy s : strategies){ for (SearchStrategy s : strategies) {
s.addModuleListener(moduleListener); s.addModuleListener(moduleListener);
} }
} }

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 {
@ -42,13 +41,13 @@ public class VariablePlusFixedSolutionCostCalculatorFactory {
this.stateManager = stateManager; this.stateManager = stateManager;
} }
public SolutionCostCalculator createCalculator(){ public SolutionCostCalculator createCalculator() {
return new SolutionCostCalculator() { return new SolutionCostCalculator() {
@Override @Override
public double getCosts(VehicleRoutingProblemSolution solution) { public double getCosts(VehicleRoutingProblemSolution solution) {
double c = 0.0; double c = 0.0;
for(VehicleRoute r : solution.getRoutes()){ for (VehicleRoute r : solution.getRoutes()) {
c += stateManager.getRouteState(r, InternalStates.COSTS, Double.class); c += stateManager.getRouteState(r, InternalStates.COSTS, Double.class);
c += getFixedCosts(r.getVehicle()); c += getFixedCosts(r.getVehicle());
} }
@ -57,8 +56,8 @@ public class VariablePlusFixedSolutionCostCalculatorFactory {
} }
private double getFixedCosts(Vehicle vehicle) { private double getFixedCosts(Vehicle vehicle) {
if(vehicle == null) return 0.0; if (vehicle == null) return 0.0;
if(vehicle.getType() == null) return 0.0; if (vehicle.getType() == null) return 0.0;
return vehicle.getType().getVehicleCostParams().fix; return vehicle.getType().getVehicleCostParams().fix;
} }
}; };

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 {
@ -44,14 +43,14 @@ public class VehicleRoutingAlgorithm {
private Collection<PrematureAlgorithmTermination> terminationCriteria = new ArrayList<PrematureAlgorithmTermination>(); private Collection<PrematureAlgorithmTermination> terminationCriteria = new ArrayList<PrematureAlgorithmTermination>();
void addTermination(PrematureAlgorithmTermination termination){ void addTermination(PrematureAlgorithmTermination termination) {
terminationCriteria.add(termination); terminationCriteria.add(termination);
} }
@Override @Override
public boolean isPrematureBreak(DiscoveredSolution discoveredSolution) { public boolean isPrematureBreak(DiscoveredSolution discoveredSolution) {
for(PrematureAlgorithmTermination termination : terminationCriteria){ for (PrematureAlgorithmTermination termination : terminationCriteria) {
if(termination.isPrematureBreak(discoveredSolution)){ if (termination.isPrematureBreak(discoveredSolution)) {
return true; return true;
} }
} }
@ -73,14 +72,14 @@ public class VehicleRoutingAlgorithm {
long i = counter++; long i = counter++;
long n = nextCounter; long n = nextCounter;
if (i >= n) { if (i >= n) {
nextCounter=n*2; nextCounter = n * 2;
log.info(this.name + n); log.info(this.name + n);
} }
} }
public void reset() { public void reset() {
counter=0; counter = 0;
nextCounter=1; nextCounter = 1;
} }
} }
@ -121,19 +120,19 @@ public class VehicleRoutingAlgorithm {
* *
* @param solution the solution to be added * @param solution the solution to be added
*/ */
public void addInitialSolution(VehicleRoutingProblemSolution solution){ public void addInitialSolution(VehicleRoutingProblemSolution solution) {
verify(solution); verify(solution);
initialSolutions.add(solution); initialSolutions.add(solution);
} }
private void verify(VehicleRoutingProblemSolution solution) { private void verify(VehicleRoutingProblemSolution solution) {
int nuJobs = 0; int nuJobs = 0;
for(VehicleRoute route : solution.getRoutes()){ for (VehicleRoute route : solution.getRoutes()) {
nuJobs += route.getTourActivities().getJobs().size(); nuJobs += route.getTourActivities().getJobs().size();
if(route.getVehicle().getIndex() == 0) if (route.getVehicle().getIndex() == 0)
throw new IllegalStateException("vehicle used in initial solution has no index. probably a vehicle is used that has not been added to the " + throw new IllegalStateException("vehicle used in initial solution has no index. probably a vehicle is used that has not been added to the " +
" the VehicleRoutingProblem. only use vehicles that have already been added to the problem."); " the VehicleRoutingProblem. only use vehicles that have already been added to the problem.");
for(TourActivity act : route.getActivities()) { for (TourActivity act : route.getActivities()) {
if (act.getIndex() == 0) { if (act.getIndex() == 0) {
throw new IllegalStateException("act in initial solution has no index. activities are created and associated to their job in VehicleRoutingProblem\n." + throw new IllegalStateException("act in initial solution has no index. activities are created and associated to their job in VehicleRoutingProblem\n." +
" thus if you build vehicle-routes use the jobActivityFactory from vehicle routing problem like that \n" + " thus if you build vehicle-routes use the jobActivityFactory from vehicle routing problem like that \n" +
@ -142,9 +141,9 @@ 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());
} }
} }
@ -154,7 +153,7 @@ public class VehicleRoutingAlgorithm {
* *
* @param prematureAlgorithmTermination the termination criterion * @param prematureAlgorithmTermination the termination criterion
*/ */
public void setPrematureAlgorithmTermination(PrematureAlgorithmTermination prematureAlgorithmTermination){ public void setPrematureAlgorithmTermination(PrematureAlgorithmTermination prematureAlgorithmTermination) {
terminationManager = new TerminationManager(); terminationManager = new TerminationManager();
terminationManager.addTermination(prematureAlgorithmTermination); terminationManager.addTermination(prematureAlgorithmTermination);
} }
@ -165,7 +164,7 @@ public class VehicleRoutingAlgorithm {
* *
* @param terminationCriterion the termination criterion * @param terminationCriterion the termination criterion
*/ */
public void addTerminationCriterion(PrematureAlgorithmTermination terminationCriterion){ public void addTerminationCriterion(PrematureAlgorithmTermination terminationCriterion) {
terminationManager.addTermination(terminationCriterion); terminationManager.addTermination(terminationCriterion);
} }
@ -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.
@ -188,50 +187,54 @@ public class VehicleRoutingAlgorithm {
* @return Collection<VehicleRoutingProblemSolution> the solutions * @return Collection<VehicleRoutingProblemSolution> the solutions
* @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();
Collection<VehicleRoutingProblemSolution> solutions = new ArrayList<VehicleRoutingProblemSolution>(initialSolutions); Collection<VehicleRoutingProblemSolution> solutions = new ArrayList<VehicleRoutingProblemSolution>(initialSolutions);
algorithmStarts(problem,solutions); algorithmStarts(problem, solutions);
bestEver = Solutions.bestOf(solutions); bestEver = Solutions.bestOf(solutions);
if(logger.isTraceEnabled()) log(solutions); if (logger.isTraceEnabled()) log(solutions);
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);
if(logger.isTraceEnabled()) log(discoveredSolution); if (logger.isTraceEnabled()) log(discoveredSolution);
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 log(Collection<VehicleRoutingProblemSolution> solutions) { private void addBestEver(Collection<VehicleRoutingProblemSolution> solutions) {
for(VehicleRoutingProblemSolution sol : solutions) log(sol); if (bestEver != null) solutions.add(bestEver);
} }
private void log(VehicleRoutingProblemSolution solution){ private void log(Collection<VehicleRoutingProblemSolution> solutions) {
logger.trace("solution costs: " + solution.getCost()); for (VehicleRoutingProblemSolution sol : solutions) log(sol);
for(VehicleRoute r : solution.getRoutes()){ }
private void log(VehicleRoutingProblemSolution solution) {
logger.trace("solution costs: {}", solution.getCost());
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("[ ");
for(TourActivity act : r.getActivities()){ for (TourActivity act : r.getActivities()) {
if(act instanceof TourActivity.JobActivity){ if (act instanceof TourActivity.JobActivity) {
b.append(((TourActivity.JobActivity) act).getJob().getId()).append(" "); b.append(((TourActivity.JobActivity) act).getJob().getId()).append(" ");
} }
} }
@ -240,7 +243,7 @@ public class VehicleRoutingAlgorithm {
} }
StringBuilder b = new StringBuilder(); StringBuilder b = new StringBuilder();
b.append("unassigned : [ "); b.append("unassigned : [ ");
for(Job j : solution.getUnassignedJobs()){ for (Job j : solution.getUnassignedJobs()) {
b.append(j.getId()).append(" "); b.append(j.getId()).append(" ");
} }
b.append("]"); b.append("]");
@ -248,23 +251,21 @@ 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();
} }
private void selectedStrategy(DiscoveredSolution discoveredSolution, VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions) { private void selectedStrategy(DiscoveredSolution discoveredSolution, VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions) {
algoListeners.selectedStrategy(discoveredSolution,problem,solutions); algoListeners.selectedStrategy(discoveredSolution, problem, solutions);
} }
private void algorithmEnds(VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions) { private void algorithmEnds(VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions) {
@ -275,14 +276,16 @@ public class VehicleRoutingAlgorithm {
return algoListeners; return algoListeners;
} }
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) {
algoListeners.iterationEnds(i,problem, solutions); algoListeners.iterationEnds(i, problem, solutions);
} }
private void iterationStarts(int i, VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions) { private void iterationStarts(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 {
@ -49,7 +48,7 @@ public class VehicleRoutingAlgorithmBuilder {
private ConstraintManager constraintManager; private ConstraintManager constraintManager;
private int nuOfThreads=0; private int nuOfThreads = 0;
/** /**
* Constructs the builder with the problem and an algorithmConfigFile. Latter is to configure and specify the ruin-and-recreate meta-heuristic. * Constructs the builder with the problem and an algorithmConfigFile. Latter is to configure and specify the ruin-and-recreate meta-heuristic.
@ -58,9 +57,9 @@ public class VehicleRoutingAlgorithmBuilder {
* @param algorithmConfig config file of VehicleRoutingAlgorithm * @param algorithmConfig config file of VehicleRoutingAlgorithm
*/ */
public VehicleRoutingAlgorithmBuilder(VehicleRoutingProblem problem, String algorithmConfig) { public VehicleRoutingAlgorithmBuilder(VehicleRoutingProblem problem, String algorithmConfig) {
this.vrp=problem; this.vrp = problem;
this.algorithmConfigFile=algorithmConfig; this.algorithmConfigFile = algorithmConfig;
this.algorithmConfig=null; this.algorithmConfig = null;
} }
/** /**
@ -70,14 +69,14 @@ public class VehicleRoutingAlgorithmBuilder {
* @param algorithmConfig config file of VehicleRoutingAlgorithm * @param algorithmConfig config file of VehicleRoutingAlgorithm
*/ */
public VehicleRoutingAlgorithmBuilder(VehicleRoutingProblem problem, AlgorithmConfig algorithmConfig) { public VehicleRoutingAlgorithmBuilder(VehicleRoutingProblem problem, AlgorithmConfig algorithmConfig) {
this.vrp=problem; this.vrp = problem;
this.algorithmConfigFile=null; this.algorithmConfigFile = null;
this.algorithmConfig=algorithmConfig; this.algorithmConfig = algorithmConfig;
} }
/** /**
* 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}).
* *
@ -95,18 +94,17 @@ public class VehicleRoutingAlgorithmBuilder {
* @see StateManager * @see StateManager
*/ */
public void setStateManager(StateManager stateManager) { public void setStateManager(StateManager stateManager) {
this.stateManager=stateManager; this.stateManager = stateManager;
} }
/** /**
* 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,12 +113,12 @@ 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.
*/ */
public void addDefaultCostCalculators() { public void addDefaultCostCalculators() {
addDefaultCostCalculators=true; addDefaultCostCalculators = true;
} }
/** /**
@ -132,8 +130,8 @@ public class VehicleRoutingAlgorithmBuilder {
* @see ConstraintManager * @see ConstraintManager
*/ */
public void setStateAndConstraintManager(StateManager stateManager, ConstraintManager constraintManager) { public void setStateAndConstraintManager(StateManager stateManager, ConstraintManager constraintManager) {
this.stateManager=stateManager; this.stateManager = stateManager;
this.constraintManager=constraintManager; this.constraintManager = constraintManager;
} }
/** /**
@ -141,25 +139,25 @@ public class VehicleRoutingAlgorithmBuilder {
* *
* @param nuOfThreads to be operated * @param nuOfThreads to be operated
*/ */
public void setNuOfThreads(int nuOfThreads){ public void setNuOfThreads(int nuOfThreads) {
this.nuOfThreads=nuOfThreads; this.nuOfThreads = nuOfThreads;
} }
/** /**
* 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
*/ */
public VehicleRoutingAlgorithm build() { public VehicleRoutingAlgorithm build() {
if(stateManager == null) stateManager = new StateManager(vrp); if (stateManager == null) stateManager = new StateManager(vrp);
if(constraintManager == null) constraintManager = new ConstraintManager(vrp,stateManager); if (constraintManager == null) constraintManager = new ConstraintManager(vrp, stateManager);
//add core updater //add core updater
stateManager.addStateUpdater(new UpdateEndLocationIfRouteIsOpen()); stateManager.addStateUpdater(new UpdateEndLocationIfRouteIsOpen());
// stateManager.addStateUpdater(new OpenRouteStateVerifier()); // stateManager.addStateUpdater(new OpenRouteStateVerifier());
if(addCoreConstraints){ if (addCoreConstraints) {
constraintManager.addLoadConstraint(); constraintManager.addLoadConstraint();
constraintManager.addTimeWindowConstraint(); constraintManager.addTimeWindowConstraint();
constraintManager.addSkillsConstraint(); constraintManager.addSkillsConstraint();
@ -167,7 +165,7 @@ public class VehicleRoutingAlgorithmBuilder {
stateManager.updateTimeWindowStates(); stateManager.updateTimeWindowStates();
stateManager.updateSkillStates(); stateManager.updateSkillStates();
} }
if(algorithmConfig==null){ if (algorithmConfig == null) {
algorithmConfig = new AlgorithmConfig(); algorithmConfig = new AlgorithmConfig();
AlgorithmConfigXmlReader xmlReader = new AlgorithmConfigXmlReader(algorithmConfig); AlgorithmConfigXmlReader xmlReader = new AlgorithmConfigXmlReader(algorithmConfig);
xmlReader.read(algorithmConfigFile); xmlReader.read(algorithmConfigFile);

View file

@ -24,18 +24,18 @@ import java.util.Collection;
* @deprecated use GreedyAcceptance instead * @deprecated use GreedyAcceptance instead
*/ */
@Deprecated @Deprecated
public class AcceptNewRemoveFirst implements SolutionAcceptor{ public class AcceptNewRemoveFirst implements SolutionAcceptor {
private final int solutionMemory; private final int solutionMemory;
public AcceptNewRemoveFirst(int solutionMemory){ public AcceptNewRemoveFirst(int solutionMemory) {
this.solutionMemory = solutionMemory; this.solutionMemory = solutionMemory;
} }
/** /**
* Accepts every solution if solution memory allows. If memory occupied, than accepts new solution only if better than the worst in memory. * 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

@ -35,7 +35,7 @@ import java.net.URL;
import java.util.Collection; import java.util.Collection;
public class ExperimentalSchrimpfAcceptance implements SolutionAcceptor, IterationStartsListener, AlgorithmStartsListener{ public class ExperimentalSchrimpfAcceptance implements SolutionAcceptor, IterationStartsListener, AlgorithmStartsListener {
final static Logger logger = LogManager.getLogger(ExperimentalSchrimpfAcceptance.class.getName()); final static Logger logger = LogManager.getLogger(ExperimentalSchrimpfAcceptance.class.getName());
@ -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;
@ -71,16 +70,15 @@ public class ExperimentalSchrimpfAcceptance implements SolutionAcceptor, Iterati
} else { } else {
VehicleRoutingProblemSolution worst = null; VehicleRoutingProblemSolution worst = null;
double threshold = getThreshold(currentIteration); double threshold = getThreshold(currentIteration);
for(VehicleRoutingProblemSolution solutionInMemory : solutions){ for (VehicleRoutingProblemSolution solutionInMemory : solutions) {
if(worst == null) worst = solutionInMemory; if (worst == null) worst = solutionInMemory;
else if(solutionInMemory.getCost() > worst.getCost()) worst = solutionInMemory; else if (solutionInMemory.getCost() > worst.getCost()) worst = solutionInMemory;
} }
if(newSolution.getRoutes().size() < worst.getRoutes().size()){ if (newSolution.getRoutes().size() < worst.getRoutes().size()) {
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;
@ -91,12 +89,12 @@ public class ExperimentalSchrimpfAcceptance implements SolutionAcceptor, Iterati
@Override @Override
public String toString() { public String toString() {
return "[name=schrimpfAcceptanceFunction][alpha="+alpha+"][warmup=" + nOfRandomWalks + "]"; return "[name=schrimpfAcceptanceFunction][alpha=" + alpha + "][warmup=" + nOfRandomWalks + "]";
} }
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,8 +124,8 @@ 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,22 +23,22 @@ 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>
*/ */
public class GreedyAcceptance implements SolutionAcceptor{ public class GreedyAcceptance implements SolutionAcceptor {
private final int solutionMemory; private final int solutionMemory;
public GreedyAcceptance(int solutionMemory){ public GreedyAcceptance(int solutionMemory) {
this.solutionMemory = solutionMemory; this.solutionMemory = solutionMemory;
} }
/** /**
* Accepts every solution if solution memory allows. If memory occupied, than accepts new solution only if better than the worst in memory. * 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,7 +53,7 @@ public class GreedyAcceptance implements SolutionAcceptor{
if (worstSolution == null) worstSolution = s; if (worstSolution == null) worstSolution = s;
else if (s.getCost() > worstSolution.getCost()) worstSolution = s; else if (s.getCost() > worstSolution.getCost()) worstSolution = s;
} }
if(newSolution.getCost() < worstSolution.getCost()){ if (newSolution.getCost() < worstSolution.getCost()) {
solutions.remove(worstSolution); solutions.remove(worstSolution);
solutions.add(newSolution); solutions.add(newSolution);
solutionAccepted = true; solutionAccepted = true;
@ -68,6 +68,4 @@ public class GreedyAcceptance implements SolutionAcceptor{
} }
} }

View file

@ -22,18 +22,18 @@ import java.util.Collection;
@Deprecated @Deprecated
public class GreedyAcceptance_minVehFirst implements SolutionAcceptor{ public class GreedyAcceptance_minVehFirst implements SolutionAcceptor {
private final int solutionMemory; private final int solutionMemory;
public GreedyAcceptance_minVehFirst(int solutionMemory){ public GreedyAcceptance_minVehFirst(int solutionMemory) {
this.solutionMemory = solutionMemory; this.solutionMemory = solutionMemory;
} }
/** /**
* Accepts every solution if solution memory allows. If memory occupied, than accepts new solution only if better than the worst in memory. * 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
@ -48,12 +48,11 @@ public class GreedyAcceptance_minVehFirst implements SolutionAcceptor{
if (worstSolution == null) worstSolution = s; if (worstSolution == null) worstSolution = s;
else if (s.getRoutes().size() > worstSolution.getRoutes().size()) worstSolution = s; else if (s.getRoutes().size() > worstSolution.getRoutes().size()) worstSolution = s;
} }
if(newSolution.getRoutes().size() < worstSolution.getRoutes().size()){ if (newSolution.getRoutes().size() < worstSolution.getRoutes().size()) {
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,17 +55,15 @@ 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 {
private static Logger logger = LogManager.getLogger(SchrimpfAcceptance.class.getName()); private static Logger logger = LogManager.getLogger(SchrimpfAcceptance.class.getName());
@ -80,10 +78,10 @@ public class SchrimpfAcceptance implements SolutionAcceptor, IterationStartsList
private final int solutionMemory; private final int solutionMemory;
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
@ -95,15 +93,14 @@ public class SchrimpfAcceptance implements SolutionAcceptor, IterationStartsList
} else { } else {
VehicleRoutingProblemSolution worst = null; VehicleRoutingProblemSolution worst = null;
double threshold = getThreshold(currentIteration); double threshold = getThreshold(currentIteration);
for(VehicleRoutingProblemSolution solutionInMemory : solutions){ for (VehicleRoutingProblemSolution solutionInMemory : solutions) {
if(worst == null) worst = solutionInMemory; if (worst == null) worst = solutionInMemory;
else if(solutionInMemory.getCost() > worst.getCost()) worst = solutionInMemory; else if (solutionInMemory.getCost() > worst.getCost()) worst = solutionInMemory;
} }
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;
@ -114,7 +111,7 @@ public class SchrimpfAcceptance implements SolutionAcceptor, IterationStartsList
@Override @Override
public String toString() { public String toString() {
return "[name=SchrimpfAcceptance][alpha="+alpha+"]"; return "[name=SchrimpfAcceptance][alpha=" + alpha + "]";
} }
private double getThreshold(int iteration) { private double getThreshold(int iteration) {
@ -124,7 +121,7 @@ public class SchrimpfAcceptance implements SolutionAcceptor, IterationStartsList
@SuppressWarnings("UnusedDeclaration") @SuppressWarnings("UnusedDeclaration")
public double getInitialThreshold(){ public double getInitialThreshold() {
return initialThreshold; return initialThreshold;
} }

View file

@ -48,7 +48,7 @@ public class SchrimpfInitialThresholdGenerator implements AlgorithmStartsListene
} }
@Override @Override
public void informAlgorithmStarts(VehicleRoutingProblem problem,VehicleRoutingAlgorithm algorithm,Collection<VehicleRoutingProblemSolution> solutions) { public void informAlgorithmStarts(VehicleRoutingProblem problem, VehicleRoutingAlgorithm algorithm, Collection<VehicleRoutingProblemSolution> solutions) {
logger.info("prepare schrimpfAcceptanceFunction, i.e. determine initial threshold"); logger.info("prepare schrimpfAcceptanceFunction, i.e. determine initial threshold");
double now = System.currentTimeMillis(); double now = System.currentTimeMillis();
@ -67,8 +67,8 @@ 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 {
@ -54,7 +52,7 @@ public class GreedySchrimpfFactory {
* @param vrp * @param vrp
* @return algorithm * @return algorithm
*/ */
public VehicleRoutingAlgorithm createAlgorithm(VehicleRoutingProblem vrp){ public VehicleRoutingAlgorithm createAlgorithm(VehicleRoutingProblem vrp) {
AlgorithmConfig algorithmConfig = new AlgorithmConfig(); AlgorithmConfig algorithmConfig = new AlgorithmConfig();
URL resource = Resource.getAsURL("greedySchrimpf.xml"); URL resource = Resource.getAsURL("greedySchrimpf.xml");
new AlgorithmConfigXmlReader(algorithmConfig).read(resource); new AlgorithmConfigXmlReader(algorithmConfig).read(resource);
@ -62,5 +60,4 @@ public class GreedySchrimpfFactory {
} }
} }

View file

@ -18,8 +18,8 @@ import java.util.List;
import java.util.Random; import java.util.Random;
/** /**
* Created by schroeder on 16/01/15. * Created by schroeder on 16/01/15.
*/ */
class InsertionNoiseMaker implements SoftActivityConstraint, IterationStartsListener { class InsertionNoiseMaker implements SoftActivityConstraint, IterationStartsListener {
private final double noiseProbability; private final double noiseProbability;
@ -44,12 +44,12 @@ class InsertionNoiseMaker implements SoftActivityConstraint, IterationStartsList
//@ToDo refactor determining max costs to allow skipping this //@ToDo refactor determining max costs to allow skipping this
private void determineMaxCosts(VehicleRoutingProblem vrp) { private void determineMaxCosts(VehicleRoutingProblem vrp) {
double max = 0.; double max = 0.;
for(Job i : vrp.getJobs().values()){ for (Job i : vrp.getJobs().values()) {
List<Location> fromLocations = getLocations(i); List<Location> fromLocations = getLocations(i);
for(Job j : vrp.getJobs().values()){ for (Job j : vrp.getJobs().values()) {
List<Location> toLocations = getLocations(j); List<Location> toLocations = getLocations(j);
for(Location iLoc : fromLocations){ for (Location iLoc : fromLocations) {
for(Location jLoc : toLocations) { for (Location jLoc : toLocations) {
max = Math.max(max, vrp.getTransportCosts().getTransportCost(iLoc, jLoc, 0, null, vrp.getVehicles().iterator().next())); max = Math.max(max, vrp.getTransportCosts().getTransportCost(iLoc, jLoc, 0, null, vrp.getVehicles().iterator().next()));
} }
} }
@ -60,10 +60,9 @@ class InsertionNoiseMaker implements SoftActivityConstraint, IterationStartsList
private List<Location> getLocations(Job j) { private List<Location> getLocations(Job j) {
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());
} }
@ -72,15 +71,14 @@ class InsertionNoiseMaker implements SoftActivityConstraint, IterationStartsList
@Override @Override
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
public double getCosts(JobInsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) { public double getCosts(JobInsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
if(makeNoise) { if (makeNoise) {
return noiseLevel * maxCosts * random.nextDouble(); return noiseLevel * maxCosts * random.nextDouble();
} }
return 0; return 0;

View file

@ -40,11 +40,11 @@ public class Jsprit {
String name; String name;
Construction(String name){ Construction(String name) {
this.name = name; this.name = name;
} }
public String toString(){ public String toString() {
return name; return name;
} }
@ -63,11 +63,11 @@ public class Jsprit {
String strategyName; String strategyName;
Strategy(String strategyName){ Strategy(String strategyName) {
this.strategyName = strategyName; this.strategyName = strategyName;
} }
public String toString(){ public String toString() {
return strategyName; return strategyName;
} }
} }
@ -97,17 +97,17 @@ public class Jsprit {
String paraName; String paraName;
Parameter(String name){ Parameter(String name) {
this.paraName = name; this.paraName = name;
} }
public String toString(){ public String toString() {
return paraName; return paraName;
} }
} }
public static VehicleRoutingAlgorithm createAlgorithm(VehicleRoutingProblem vehicleRoutingProblem){ public static VehicleRoutingAlgorithm createAlgorithm(VehicleRoutingProblem vehicleRoutingProblem) {
return Jsprit.Builder.newInstance(vehicleRoutingProblem).buildAlgorithm(); return Jsprit.Builder.newInstance(vehicleRoutingProblem).buildAlgorithm();
} }
@ -131,53 +131,53 @@ public class Jsprit {
private Random random = RandomNumberGeneration.newInstance(); private Random random = RandomNumberGeneration.newInstance();
public static Builder newInstance(VehicleRoutingProblem vrp){ public static Builder newInstance(VehicleRoutingProblem vrp) {
return new Builder(vrp); return new Builder(vrp);
} }
private Builder(VehicleRoutingProblem vrp){ private Builder(VehicleRoutingProblem vrp) {
this.vrp = vrp; this.vrp = vrp;
properties = new Properties(createDefaultProperties()); properties = new Properties(createDefaultProperties());
} }
private Properties createDefaultProperties() { private Properties createDefaultProperties() {
Properties defaults = new Properties(); Properties defaults = new Properties();
defaults.put(Strategy.RADIAL_BEST.toString(),"0."); defaults.put(Strategy.RADIAL_BEST.toString(), "0.");
defaults.put(Strategy.RADIAL_REGRET.toString(),".5"); defaults.put(Strategy.RADIAL_REGRET.toString(), ".5");
defaults.put(Strategy.RANDOM_BEST.toString(),".5"); defaults.put(Strategy.RANDOM_BEST.toString(), ".5");
defaults.put(Strategy.RANDOM_REGRET.toString(),".5"); defaults.put(Strategy.RANDOM_REGRET.toString(), ".5");
defaults.put(Strategy.WORST_BEST.toString(),"0."); defaults.put(Strategy.WORST_BEST.toString(), "0.");
defaults.put(Strategy.WORST_REGRET.toString(),"1."); defaults.put(Strategy.WORST_REGRET.toString(), "1.");
defaults.put(Strategy.CLUSTER_BEST.toString(),"0."); defaults.put(Strategy.CLUSTER_BEST.toString(), "0.");
defaults.put(Strategy.CLUSTER_REGRET.toString(),"1."); defaults.put(Strategy.CLUSTER_REGRET.toString(), "1.");
defaults.put(Parameter.FIXED_COST_PARAM.toString(),"0."); defaults.put(Parameter.FIXED_COST_PARAM.toString(), "0.");
defaults.put(Parameter.VEHICLE_SWITCH.toString(),"true"); defaults.put(Parameter.VEHICLE_SWITCH.toString(), "true");
defaults.put(Parameter.ITERATIONS.toString(),"2000"); defaults.put(Parameter.ITERATIONS.toString(), "2000");
defaults.put(Parameter.REGRET_DISTANCE_SCORER.toString(),".05"); defaults.put(Parameter.REGRET_DISTANCE_SCORER.toString(), ".05");
defaults.put(Parameter.REGRET_TIME_WINDOW_SCORER.toString(),"-.1"); defaults.put(Parameter.REGRET_TIME_WINDOW_SCORER.toString(), "-.1");
defaults.put(Parameter.THREADS.toString(),"1"); defaults.put(Parameter.THREADS.toString(), "1");
int minShare = (int)Math.min(20, Math.max(3,vrp.getJobs().size() * 0.05)); int minShare = (int) Math.min(20, Math.max(3, vrp.getJobs().size() * 0.05));
int maxShare = (int)Math.min(50, Math.max(5,vrp.getJobs().size() * 0.3)); int maxShare = (int) Math.min(50, Math.max(5, vrp.getJobs().size() * 0.3));
defaults.put(Parameter.RADIAL_MIN_SHARE.toString(),String.valueOf(minShare)); defaults.put(Parameter.RADIAL_MIN_SHARE.toString(), String.valueOf(minShare));
defaults.put(Parameter.RADIAL_MAX_SHARE.toString(),String.valueOf(maxShare)); defaults.put(Parameter.RADIAL_MAX_SHARE.toString(), String.valueOf(maxShare));
defaults.put(Parameter.WORST_MIN_SHARE.toString(),String.valueOf(minShare)); defaults.put(Parameter.WORST_MIN_SHARE.toString(), String.valueOf(minShare));
defaults.put(Parameter.WORST_MAX_SHARE.toString(),String.valueOf(maxShare)); defaults.put(Parameter.WORST_MAX_SHARE.toString(), String.valueOf(maxShare));
defaults.put(Parameter.CLUSTER_MIN_SHARE.toString(),String.valueOf(minShare)); defaults.put(Parameter.CLUSTER_MIN_SHARE.toString(), String.valueOf(minShare));
defaults.put(Parameter.CLUSTER_MAX_SHARE.toString(),String.valueOf(maxShare)); defaults.put(Parameter.CLUSTER_MAX_SHARE.toString(), String.valueOf(maxShare));
int minShare_ = (int)Math.min(70, Math.max(5,vrp.getJobs().size() * 0.5)); int minShare_ = (int) Math.min(70, Math.max(5, vrp.getJobs().size() * 0.5));
int maxShare_ = (int)Math.min(70, Math.max(5,vrp.getJobs().size() * 0.5)); int maxShare_ = (int) Math.min(70, Math.max(5, vrp.getJobs().size() * 0.5));
defaults.put(Parameter.RANDOM_REGRET_MIN_SHARE.toString(),String.valueOf(minShare_)); defaults.put(Parameter.RANDOM_REGRET_MIN_SHARE.toString(), String.valueOf(minShare_));
defaults.put(Parameter.RANDOM_REGRET_MAX_SHARE.toString(),String.valueOf(maxShare_)); defaults.put(Parameter.RANDOM_REGRET_MAX_SHARE.toString(), String.valueOf(maxShare_));
defaults.put(Parameter.RANDOM_BEST_MIN_SHARE.toString(),String.valueOf(minShare_)); defaults.put(Parameter.RANDOM_BEST_MIN_SHARE.toString(), String.valueOf(minShare_));
defaults.put(Parameter.RANDOM_BEST_MAX_SHARE.toString(),String.valueOf(maxShare_)); defaults.put(Parameter.RANDOM_BEST_MAX_SHARE.toString(), String.valueOf(maxShare_));
defaults.put(Parameter.THRESHOLD_ALPHA.toString(),String.valueOf(0.15)); defaults.put(Parameter.THRESHOLD_ALPHA.toString(), String.valueOf(0.15));
defaults.put(Parameter.THRESHOLD_INI.toString(),String.valueOf(0.03)); defaults.put(Parameter.THRESHOLD_INI.toString(), String.valueOf(0.03));
defaults.put(Parameter.INSERTION_NOISE_LEVEL.toString(),String.valueOf(0.15)); defaults.put(Parameter.INSERTION_NOISE_LEVEL.toString(), String.valueOf(0.15));
defaults.put(Parameter.INSERTION_NOISE_PROB.toString(),String.valueOf(0.2)); defaults.put(Parameter.INSERTION_NOISE_PROB.toString(), String.valueOf(0.2));
defaults.put(Parameter.RUIN_WORST_NOISE_LEVEL.toString(),String.valueOf(0.15)); defaults.put(Parameter.RUIN_WORST_NOISE_LEVEL.toString(), String.valueOf(0.15));
defaults.put(Parameter.RUIN_WORST_NOISE_PROB.toString(),String.valueOf(0.2)); defaults.put(Parameter.RUIN_WORST_NOISE_PROB.toString(), String.valueOf(0.2));
defaults.put(Parameter.VEHICLE_SWITCH.toString(),String.valueOf(true)); defaults.put(Parameter.VEHICLE_SWITCH.toString(), String.valueOf(true));
defaults.put(Parameter.CONSTRUCTION.toString(),Construction.REGRET_INSERTION.toString()); defaults.put(Parameter.CONSTRUCTION.toString(), Construction.REGRET_INSERTION.toString());
return defaults; return defaults;
} }
@ -188,23 +188,23 @@ public class Jsprit {
return this; return this;
} }
public Builder setRandom(Random random){ public Builder setRandom(Random random) {
this.random = random; this.random = random;
return this; return this;
} }
public Builder setProperty(String key, String value){ public Builder setProperty(String key, String value) {
properties.put(key,value); properties.put(key, value);
return this; return this;
} }
public Builder setProperty(Parameter parameter, String value){ public Builder setProperty(Parameter parameter, String value) {
setProperty(parameter.toString(),value); setProperty(parameter.toString(), value);
return this; return this;
} }
public Builder setProperty(Strategy strategy, String value){ public Builder setProperty(Strategy strategy, String value) {
setProperty(strategy.toString(),value); setProperty(strategy.toString(), value);
return this; return this;
} }
@ -224,7 +224,7 @@ public class Jsprit {
return this; return this;
} }
public VehicleRoutingAlgorithm buildAlgorithm(){ public VehicleRoutingAlgorithm buildAlgorithm() {
return new Jsprit(this).create(vrp); return new Jsprit(this).create(vrp);
} }
@ -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;
@ -293,18 +295,17 @@ public class Jsprit {
this.random = builder.random; this.random = builder.random;
} }
private VehicleRoutingAlgorithm create(final VehicleRoutingProblem vrp){ private VehicleRoutingAlgorithm create(final VehicleRoutingProblem vrp) {
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);
} }
if(constraintManager == null){ if (constraintManager == null) {
constraintManager = new ConstraintManager(vrp,stateManager); constraintManager = new ConstraintManager(vrp, stateManager);
} }
double noiseLevel = toDouble(getProperty(Parameter.INSERTION_NOISE_LEVEL.toString())); double noiseLevel = toDouble(getProperty(Parameter.INSERTION_NOISE_LEVEL.toString()));
@ -316,7 +317,7 @@ public class Jsprit {
JobNeighborhoods jobNeighborhoods = new JobNeighborhoodsFactory().createNeighborhoods(vrp, new AvgServiceAndShipmentDistance(vrp.getTransportCosts()), (int) (vrp.getJobs().values().size() * 0.5)); JobNeighborhoods jobNeighborhoods = new JobNeighborhoodsFactory().createNeighborhoods(vrp, new AvgServiceAndShipmentDistance(vrp.getTransportCosts()), (int) (vrp.getJobs().values().size() * 0.5));
jobNeighborhoods.initialise(); jobNeighborhoods.initialise();
RuinRadial radial = new RuinRadial(vrp,vrp.getJobs().size(),jobNeighborhoods); RuinRadial radial = new RuinRadial(vrp, vrp.getJobs().size(), jobNeighborhoods);
radial.setRandom(random); radial.setRandom(random);
radial.setRuinShareFactory(new RuinShareFactoryImpl( radial.setRuinShareFactory(new RuinShareFactoryImpl(
toInteger(properties.getProperty(Parameter.RADIAL_MIN_SHARE.toString())), toInteger(properties.getProperty(Parameter.RADIAL_MIN_SHARE.toString())),
@ -324,7 +325,7 @@ public class Jsprit {
random) random)
); );
final RuinRandom random_for_regret = new RuinRandom(vrp,0.5); final RuinRandom random_for_regret = new RuinRandom(vrp, 0.5);
random_for_regret.setRandom(random); random_for_regret.setRandom(random);
random_for_regret.setRuinShareFactory(new RuinShareFactoryImpl( random_for_regret.setRuinShareFactory(new RuinShareFactoryImpl(
toInteger(properties.getProperty(Parameter.RANDOM_REGRET_MIN_SHARE.toString())), toInteger(properties.getProperty(Parameter.RANDOM_REGRET_MIN_SHARE.toString())),
@ -332,7 +333,7 @@ public class Jsprit {
random) random)
); );
final RuinRandom random_for_best = new RuinRandom(vrp,0.5); final RuinRandom random_for_best = new RuinRandom(vrp, 0.5);
random_for_best.setRandom(random); random_for_best.setRandom(random);
random_for_best.setRuinShareFactory(new RuinShareFactoryImpl( random_for_best.setRuinShareFactory(new RuinShareFactoryImpl(
toInteger(properties.getProperty(Parameter.RANDOM_BEST_MIN_SHARE.toString())), toInteger(properties.getProperty(Parameter.RANDOM_BEST_MIN_SHARE.toString())),
@ -340,7 +341,7 @@ public class Jsprit {
random) random)
); );
final RuinWorst worst = new RuinWorst(vrp, (int) (vrp.getJobs().values().size()*0.5)); final RuinWorst worst = new RuinWorst(vrp, (int) (vrp.getJobs().values().size() * 0.5));
worst.setRandom(random); worst.setRandom(random);
worst.setRuinShareFactory(new RuinShareFactoryImpl( worst.setRuinShareFactory(new RuinShareFactoryImpl(
toInteger(properties.getProperty(Parameter.WORST_MIN_SHARE.toString())), toInteger(properties.getProperty(Parameter.WORST_MIN_SHARE.toString())),
@ -353,17 +354,16 @@ public class Jsprit {
worst.setNoiseMaker(new NoiseMaker() { worst.setNoiseMaker(new NoiseMaker() {
public double makeNoise() { public double makeNoise() {
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.;
} }
}); });
} }
}; };
final RuinClusters clusters = new RuinClusters(vrp,(int) (vrp.getJobs().values().size()*0.5),jobNeighborhoods); final RuinClusters clusters = new RuinClusters(vrp, (int) (vrp.getJobs().values().size() * 0.5), jobNeighborhoods);
clusters.setRandom(random); clusters.setRandom(random);
clusters.setRuinShareFactory(new RuinShareFactoryImpl( clusters.setRuinShareFactory(new RuinShareFactoryImpl(
toInteger(properties.getProperty(Parameter.WORST_MIN_SHARE.toString())), toInteger(properties.getProperty(Parameter.WORST_MIN_SHARE.toString())),
@ -373,16 +373,16 @@ public class Jsprit {
AbstractInsertionStrategy regret; AbstractInsertionStrategy regret;
final RegretInsertion.DefaultScorer scorer; final RegretInsertion.DefaultScorer scorer;
if(noThreads == null){ if (noThreads == null) {
noThreads = toInteger(getProperty(Parameter.THREADS.toString())); noThreads = toInteger(getProperty(Parameter.THREADS.toString()));
} }
if(noThreads > 1){ if (noThreads > 1) {
if(es == null){ if (es == null) {
setupExecutorInternally = true; setupExecutorInternally = true;
es = Executors.newFixedThreadPool(noThreads); es = Executors.newFixedThreadPool(noThreads);
} }
} }
if(es != null) { if (es != null) {
RegretInsertionConcurrent regretInsertion = (RegretInsertionConcurrent) new InsertionBuilder(vrp, fm, stateManager, constraintManager) RegretInsertionConcurrent regretInsertion = (RegretInsertionConcurrent) new InsertionBuilder(vrp, fm, stateManager, constraintManager)
.setInsertionStrategy(InsertionBuilder.Strategy.REGRET) .setInsertionStrategy(InsertionBuilder.Strategy.REGRET)
.setConcurrentMode(es, noThreads) .setConcurrentMode(es, noThreads)
@ -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())))
@ -406,15 +405,14 @@ public class Jsprit {
regret.setRandom(random); regret.setRandom(random);
AbstractInsertionStrategy best; AbstractInsertionStrategy best;
if(vrp.getJobs().size() < 250 || es == null) { if (vrp.getJobs().size() < 250 || es == null) {
BestInsertion bestInsertion = (BestInsertion) new InsertionBuilder(vrp, fm, stateManager, constraintManager) BestInsertion bestInsertion = (BestInsertion) 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())))
.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())))
@ -425,11 +423,11 @@ public class Jsprit {
} }
best.setRandom(random); best.setRandom(random);
final SchrimpfAcceptance schrimpfAcceptance = new SchrimpfAcceptance(1,toDouble(getProperty(Parameter.THRESHOLD_ALPHA.toString()))); final SchrimpfAcceptance schrimpfAcceptance = new SchrimpfAcceptance(1, toDouble(getProperty(Parameter.THRESHOLD_ALPHA.toString())));
IterationStartsListener schrimpfThreshold = new IterationStartsListener() { IterationStartsListener schrimpfThreshold = new IterationStartsListener() {
@Override @Override
public void informIterationStarts(int i, VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions) { public void informIterationStarts(int i, VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions) {
if(i == 1){ if (i == 1) {
double initialThreshold = Solutions.bestOf(solutions).getCost() * toDouble(getProperty(Parameter.THRESHOLD_INI.toString())); double initialThreshold = Solutions.bestOf(solutions).getCost() * toDouble(getProperty(Parameter.THRESHOLD_INI.toString()));
schrimpfAcceptance.setInitialThreshold(initialThreshold); schrimpfAcceptance.setInitialThreshold(initialThreshold);
} }
@ -437,34 +435,34 @@ public class Jsprit {
}; };
SolutionCostCalculator objectiveFunction = getObjectiveFunction(vrp, noiseMaker.maxCosts); SolutionCostCalculator objectiveFunction = getObjectiveFunction(vrp, noiseMaker.maxCosts);
SearchStrategy radial_regret = new SearchStrategy(Strategy.RADIAL_REGRET.toString(),new SelectBest(),schrimpfAcceptance, objectiveFunction); SearchStrategy radial_regret = new SearchStrategy(Strategy.RADIAL_REGRET.toString(), new SelectBest(), schrimpfAcceptance, objectiveFunction);
radial_regret.addModule(new RuinAndRecreateModule(Strategy.RADIAL_REGRET.toString(), regret, radial)); radial_regret.addModule(new RuinAndRecreateModule(Strategy.RADIAL_REGRET.toString(), regret, radial));
SearchStrategy radial_best = new SearchStrategy(Strategy.RADIAL_BEST.toString(),new SelectBest(),schrimpfAcceptance,objectiveFunction); SearchStrategy radial_best = new SearchStrategy(Strategy.RADIAL_BEST.toString(), new SelectBest(), schrimpfAcceptance, objectiveFunction);
radial_best.addModule(new RuinAndRecreateModule(Strategy.RADIAL_BEST.toString(),best,radial)); radial_best.addModule(new RuinAndRecreateModule(Strategy.RADIAL_BEST.toString(), best, radial));
SearchStrategy random_best = new SearchStrategy(Strategy.RANDOM_BEST.toString(),new SelectBest(),schrimpfAcceptance,objectiveFunction); SearchStrategy random_best = new SearchStrategy(Strategy.RANDOM_BEST.toString(), new SelectBest(), schrimpfAcceptance, objectiveFunction);
random_best.addModule(new RuinAndRecreateModule(Strategy.RANDOM_BEST.toString(),best,random_for_best)); random_best.addModule(new RuinAndRecreateModule(Strategy.RANDOM_BEST.toString(), best, random_for_best));
SearchStrategy random_regret = new SearchStrategy(Strategy.RANDOM_REGRET.toString(),new SelectBest(),schrimpfAcceptance,objectiveFunction); SearchStrategy random_regret = new SearchStrategy(Strategy.RANDOM_REGRET.toString(), new SelectBest(), schrimpfAcceptance, objectiveFunction);
random_regret.addModule(new RuinAndRecreateModule(Strategy.RANDOM_REGRET.toString(),regret,random_for_regret)); random_regret.addModule(new RuinAndRecreateModule(Strategy.RANDOM_REGRET.toString(), regret, random_for_regret));
SearchStrategy worst_regret = new SearchStrategy(Strategy.WORST_REGRET.toString(),new SelectBest(),schrimpfAcceptance,objectiveFunction); SearchStrategy worst_regret = new SearchStrategy(Strategy.WORST_REGRET.toString(), new SelectBest(), schrimpfAcceptance, objectiveFunction);
worst_regret.addModule(new RuinAndRecreateModule(Strategy.WORST_REGRET.toString(),regret,worst)); worst_regret.addModule(new RuinAndRecreateModule(Strategy.WORST_REGRET.toString(), regret, worst));
SearchStrategy worst_best = new SearchStrategy(Strategy.WORST_BEST.toString(),new SelectBest(),schrimpfAcceptance,objectiveFunction); SearchStrategy worst_best = new SearchStrategy(Strategy.WORST_BEST.toString(), new SelectBest(), schrimpfAcceptance, objectiveFunction);
worst_best.addModule(new RuinAndRecreateModule(Strategy.WORST_BEST.toString(),best,worst)); worst_best.addModule(new RuinAndRecreateModule(Strategy.WORST_BEST.toString(), best, worst));
final SearchStrategy clusters_regret = new SearchStrategy(Strategy.CLUSTER_REGRET.toString(),new SelectBest(),schrimpfAcceptance,objectiveFunction); final SearchStrategy clusters_regret = new SearchStrategy(Strategy.CLUSTER_REGRET.toString(), new SelectBest(), schrimpfAcceptance, objectiveFunction);
clusters_regret.addModule(new RuinAndRecreateModule(Strategy.CLUSTER_REGRET.toString(),regret,clusters)); clusters_regret.addModule(new RuinAndRecreateModule(Strategy.CLUSTER_REGRET.toString(), regret, clusters));
final SearchStrategy clusters_best = new SearchStrategy(Strategy.CLUSTER_BEST.toString(),new SelectBest(),schrimpfAcceptance,objectiveFunction); final SearchStrategy clusters_best = new SearchStrategy(Strategy.CLUSTER_BEST.toString(), new SelectBest(), schrimpfAcceptance, objectiveFunction);
clusters_best.addModule(new RuinAndRecreateModule(Strategy.CLUSTER_BEST.toString(),best,clusters)); clusters_best.addModule(new RuinAndRecreateModule(Strategy.CLUSTER_BEST.toString(), best, clusters));
PrettyAlgorithmBuilder prettyBuilder = PrettyAlgorithmBuilder.newInstance(vrp, fm, stateManager, constraintManager); PrettyAlgorithmBuilder prettyBuilder = PrettyAlgorithmBuilder.newInstance(vrp, fm, stateManager, constraintManager);
prettyBuilder.setRandom(random); prettyBuilder.setRandom(random);
if(addCoreConstraints){ if (addCoreConstraints) {
prettyBuilder.addCoreStateAndConstraintStuff(); prettyBuilder.addCoreStateAndConstraintStuff();
} }
prettyBuilder.withStrategy(radial_regret, toDouble(getProperty(Strategy.RADIAL_REGRET.toString()))) prettyBuilder.withStrategy(radial_regret, toDouble(getProperty(Strategy.RADIAL_REGRET.toString())))
@ -473,12 +471,11 @@ public class Jsprit {
.withStrategy(random_regret, toDouble(getProperty(Strategy.RANDOM_REGRET.toString()))) .withStrategy(random_regret, toDouble(getProperty(Strategy.RANDOM_REGRET.toString())))
.withStrategy(worst_best, toDouble(getProperty(Strategy.WORST_BEST.toString()))) .withStrategy(worst_best, toDouble(getProperty(Strategy.WORST_BEST.toString())))
.withStrategy(worst_regret, toDouble(getProperty(Strategy.WORST_REGRET.toString()))) .withStrategy(worst_regret, toDouble(getProperty(Strategy.WORST_REGRET.toString())))
.withStrategy(clusters_regret,toDouble(getProperty(Strategy.CLUSTER_REGRET.toString()))) .withStrategy(clusters_regret, toDouble(getProperty(Strategy.CLUSTER_REGRET.toString())))
.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);
} }
@ -504,7 +501,7 @@ public class Jsprit {
private void handleExecutorShutdown(VehicleRoutingAlgorithm vra) { private void handleExecutorShutdown(VehicleRoutingAlgorithm vra) {
if(setupExecutorInternally){ if (setupExecutorInternally) {
vra.addListener(new AlgorithmEndsListener() { vra.addListener(new AlgorithmEndsListener() {
@Override @Override
@ -514,7 +511,7 @@ public class Jsprit {
}); });
} }
if(es != null) { if (es != null) {
Runtime.getRuntime().addShutdownHook(new Thread() { Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() { public void run() {
if (!es.isShutdown()) { if (!es.isShutdown()) {
@ -526,7 +523,7 @@ public class Jsprit {
} }
} }
String getProperty(String key){ String getProperty(String key) {
return properties.getProperty(key); return properties.getProperty(key);
} }
@ -543,21 +540,21 @@ public class Jsprit {
} }
private SolutionCostCalculator getObjectiveFunction(final VehicleRoutingProblem vrp, final double maxCosts) { private SolutionCostCalculator getObjectiveFunction(final VehicleRoutingProblem vrp, final double maxCosts) {
if(objectiveFunction != null) return objectiveFunction; if (objectiveFunction != null) return objectiveFunction;
SolutionCostCalculator solutionCostCalculator = new SolutionCostCalculator() { SolutionCostCalculator solutionCostCalculator = new SolutionCostCalculator() {
@Override @Override
public double getCosts(VehicleRoutingProblemSolution solution) { public double getCosts(VehicleRoutingProblemSolution solution) {
double costs = 0.; double costs = 0.;
for(VehicleRoute route : solution.getRoutes()){ for (VehicleRoute route : solution.getRoutes()) {
costs += route.getVehicle().getType().getVehicleCostParams().fix; costs += route.getVehicle().getType().getVehicleCostParams().fix;
TourActivity prevAct = route.getStart(); TourActivity prevAct = route.getStart();
for(TourActivity act : route.getActivities()){ for (TourActivity act : route.getActivities()) {
costs += vrp.getTransportCosts().getTransportCost(prevAct.getLocation(),act.getLocation(),prevAct.getEndTime(),route.getDriver(),route.getVehicle()); costs += vrp.getTransportCosts().getTransportCost(prevAct.getLocation(), act.getLocation(), prevAct.getEndTime(), route.getDriver(), route.getVehicle());
costs += vrp.getActivityCosts().getActivityCost(act,act.getArrTime(),route.getDriver(),route.getVehicle()); costs += vrp.getActivityCosts().getActivityCost(act, act.getArrTime(), route.getDriver(), route.getVehicle());
prevAct = act; prevAct = act;
} }
costs += vrp.getTransportCosts().getTransportCost(prevAct.getLocation(),route.getEnd().getLocation(),prevAct.getEndTime(),route.getDriver(),route.getVehicle()); costs += vrp.getTransportCosts().getTransportCost(prevAct.getLocation(), route.getEnd().getLocation(), prevAct.getEndTime(), route.getDriver(), route.getVehicle());
} }
costs += solution.getUnassignedJobs().size() * maxCosts * 2; costs += solution.getUnassignedJobs().size() * maxCosts * 2;
return costs; return costs;

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 {
@ -54,7 +52,7 @@ public class SchrimpfFactory {
* @param vrp the underlying vehicle routing problem * @param vrp the underlying vehicle routing problem
* @return algorithm * @return algorithm
*/ */
public VehicleRoutingAlgorithm createAlgorithm(VehicleRoutingProblem vrp){ public VehicleRoutingAlgorithm createAlgorithm(VehicleRoutingProblem vrp) {
AlgorithmConfig algorithmConfig = new AlgorithmConfig(); AlgorithmConfig algorithmConfig = new AlgorithmConfig();
URL resource = Resource.getAsURL("schrimpf.xml"); URL resource = Resource.getAsURL("schrimpf.xml");
new AlgorithmConfigXmlReader(algorithmConfig).read(resource); new AlgorithmConfigXmlReader(algorithmConfig).read(resource);
@ -62,5 +60,4 @@ public class SchrimpfFactory {
} }
} }

View file

@ -22,12 +22,12 @@ public class AlgorithmConfig {
private XMLConfiguration xmlConfig; private XMLConfiguration xmlConfig;
public AlgorithmConfig(){ public AlgorithmConfig() {
xmlConfig = new XMLConfiguration(); xmlConfig = new XMLConfiguration();
} }
public XMLConfiguration getXMLConfiguration(){ public XMLConfiguration getXMLConfiguration() {
return xmlConfig; return xmlConfig;
} }
} }

View file

@ -45,19 +45,19 @@ public class AlgorithmConfigXmlReader {
return this; return this;
} }
public AlgorithmConfigXmlReader(AlgorithmConfig algorithmConfig){ public AlgorithmConfigXmlReader(AlgorithmConfig algorithmConfig) {
this.algorithmConfig = algorithmConfig; this.algorithmConfig = algorithmConfig;
} }
public void read(URL url){ public void read(URL url) {
log.debug("read algorithm: " + url); log.debug("read algorithm: " + url);
algorithmConfig.getXMLConfiguration().setURL(url); algorithmConfig.getXMLConfiguration().setURL(url);
algorithmConfig.getXMLConfiguration().setAttributeSplittingDisabled(true); algorithmConfig.getXMLConfiguration().setAttributeSplittingDisabled(true);
algorithmConfig.getXMLConfiguration().setDelimiterParsingDisabled(true); algorithmConfig.getXMLConfiguration().setDelimiterParsingDisabled(true);
if(schemaValidation){ if (schemaValidation) {
final InputStream resource = Resource.getAsInputStream("algorithm_schema.xsd"); final InputStream resource = Resource.getAsInputStream("algorithm_schema.xsd");
if(resource != null) { if (resource != null) {
EntityResolver resolver = new EntityResolver() { EntityResolver resolver = new EntityResolver() {
@Override @Override
@ -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.");
} }
} }
@ -85,7 +84,7 @@ public class AlgorithmConfigXmlReader {
} }
public void read(String filename){ public void read(String filename) {
log.debug("read algorithm-config from file " + filename); log.debug("read algorithm-config from file " + filename);
URL url = Resource.getAsURL(filename); URL url = Resource.getAsURL(filename);
read(url); read(url);

View file

@ -37,77 +37,75 @@ class InsertionFactory {
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public static InsertionStrategy createInsertion(VehicleRoutingProblem vrp, HierarchicalConfiguration config, public static InsertionStrategy createInsertion(VehicleRoutingProblem vrp, HierarchicalConfiguration config,
VehicleFleetManager vehicleFleetManager, StateManager stateManager, List<PrioritizedVRAListener> algorithmListeners, ExecutorService executorService, int nuOfThreads, ConstraintManager constraintManager, boolean addDefaultCostCalculators){ VehicleFleetManager vehicleFleetManager, StateManager stateManager, List<PrioritizedVRAListener> algorithmListeners, ExecutorService executorService, int nuOfThreads, ConstraintManager constraintManager, boolean addDefaultCostCalculators) {
if(config.containsKey("[@name]")){ if (config.containsKey("[@name]")) {
String insertionName = config.getString("[@name]"); String insertionName = config.getString("[@name]");
if(!insertionName.equals("bestInsertion") && !insertionName.equals("regretInsertion")){ if (!insertionName.equals("bestInsertion") && !insertionName.equals("regretInsertion")) {
throw new IllegalStateException(insertionName + " is not supported. use either \"bestInsertion\" or \"regretInsertion\""); throw new IllegalStateException(insertionName + " is not supported. use either \"bestInsertion\" or \"regretInsertion\"");
} }
InsertionBuilder iBuilder = new InsertionBuilder(vrp, vehicleFleetManager, stateManager, constraintManager); InsertionBuilder iBuilder = new InsertionBuilder(vrp, vehicleFleetManager, stateManager, constraintManager);
if(executorService != null){ if (executorService != null) {
iBuilder.setConcurrentMode(executorService, nuOfThreads); iBuilder.setConcurrentMode(executorService, nuOfThreads);
} }
if(config.containsKey("level")){ if (config.containsKey("level")) {
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
if(mem != null) memory = Integer.parseInt(mem); log.warn("parameter route[@forwardLooking] is missing. by default it is 0 which equals to local level");
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) {
String val = config.getString("considerFixedCosts"); String val = config.getString("considerFixedCosts");
if(val == null) val = config.getString("considerFixedCost"); if (val == null) val = config.getString("considerFixedCost");
if(val.equals("true")){ if (val.equals("true")) {
double fixedCostWeight = 0.5; double fixedCostWeight = 0.5;
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");
} }
} }
String timeSliceString = config.getString("experimental[@timeSlice]"); String timeSliceString = config.getString("experimental[@timeSlice]");
String neighbors = config.getString("experimental[@neighboringSlices]"); String neighbors = config.getString("experimental[@neighboringSlices]");
if(timeSliceString != null && neighbors != null){ if (timeSliceString != null && neighbors != null) {
iBuilder.experimentalTimeScheduler(Double.parseDouble(timeSliceString),Integer.parseInt(neighbors)); iBuilder.experimentalTimeScheduler(Double.parseDouble(timeSliceString), Integer.parseInt(neighbors));
} }
String allowVehicleSwitch = config.getString("allowVehicleSwitch"); String allowVehicleSwitch = config.getString("allowVehicleSwitch");
if(allowVehicleSwitch != null){ if (allowVehicleSwitch != null) {
iBuilder.setAllowVehicleSwitch(Boolean.parseBoolean(allowVehicleSwitch)); iBuilder.setAllowVehicleSwitch(Boolean.parseBoolean(allowVehicleSwitch));
} }
if(insertionName.equals("regretInsertion")){ if (insertionName.equals("regretInsertion")) {
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;
@ -70,7 +71,7 @@ public class VehicleRoutingAlgorithms {
Class<K> getType(); Class<K> getType();
} }
static class AcceptorKey implements AbstractKey<SolutionAcceptor>{ static class AcceptorKey implements AbstractKey<SolutionAcceptor> {
private ModKey modKey; private ModKey modKey;
@ -115,7 +116,7 @@ public class VehicleRoutingAlgorithms {
} }
static class SelectorKey implements AbstractKey<SolutionSelector>{ static class SelectorKey implements AbstractKey<SolutionSelector> {
private ModKey modKey; private ModKey modKey;
@ -151,7 +152,6 @@ public class VehicleRoutingAlgorithms {
} }
@Override @Override
public Class<SolutionSelector> getType() { public Class<SolutionSelector> getType() {
return SolutionSelector.class; return SolutionSelector.class;
@ -159,7 +159,7 @@ public class VehicleRoutingAlgorithms {
} }
static class StrategyModuleKey implements AbstractKey<SearchStrategyModule>{ static class StrategyModuleKey implements AbstractKey<SearchStrategyModule> {
private ModKey modKey; private ModKey modKey;
@ -195,7 +195,6 @@ public class VehicleRoutingAlgorithms {
} }
@Override @Override
public Class<SearchStrategyModule> getType() { public Class<SearchStrategyModule> getType() {
return SearchStrategyModule.class; return SearchStrategyModule.class;
@ -203,7 +202,7 @@ public class VehicleRoutingAlgorithms {
} }
static class RuinStrategyKey implements AbstractKey<RuinStrategy>{ static class RuinStrategyKey implements AbstractKey<RuinStrategy> {
private ModKey modKey; private ModKey modKey;
@ -239,7 +238,6 @@ public class VehicleRoutingAlgorithms {
} }
@Override @Override
public Class<RuinStrategy> getType() { public Class<RuinStrategy> getType() {
return RuinStrategy.class; return RuinStrategy.class;
@ -247,7 +245,7 @@ public class VehicleRoutingAlgorithms {
} }
static class InsertionStrategyKey implements AbstractKey<InsertionStrategy>{ static class InsertionStrategyKey implements AbstractKey<InsertionStrategy> {
private ModKey modKey; private ModKey modKey;
@ -283,7 +281,6 @@ public class VehicleRoutingAlgorithms {
} }
@Override @Override
public Class<InsertionStrategy> getType() { public Class<InsertionStrategy> getType() {
return InsertionStrategy.class; return InsertionStrategy.class;
@ -294,7 +291,7 @@ public class VehicleRoutingAlgorithms {
private Map<AbstractKey<?>, Object> map = new HashMap<AbstractKey<?>, Object>(); private Map<AbstractKey<?>, Object> map = new HashMap<AbstractKey<?>, Object>();
public <T> T get(AbstractKey<T> key) { public <T> T get(AbstractKey<T> key) {
if(map.get(key) == null) return null; if (map.get(key) == null) return null;
return key.getType().cast(map.get(key)); return key.getType().cast(map.get(key));
} }
@ -302,7 +299,7 @@ public class VehicleRoutingAlgorithms {
return key.getType().cast(map.put(key, key.getType().cast(value))); return key.getType().cast(map.put(key, key.getType().cast(value)));
} }
public Set<AbstractKey<?>> keySet(){ public Set<AbstractKey<?>> keySet() {
return map.keySet(); return map.keySet();
} }
} }
@ -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.
@ -360,11 +359,12 @@ public class VehicleRoutingAlgorithms {
* @param algorithmConfig the algorithm config * @param algorithmConfig the algorithm config
* @return {@link jsprit.core.algorithm.VehicleRoutingAlgorithm} * @return {@link jsprit.core.algorithm.VehicleRoutingAlgorithm}
*/ */
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){
return createAlgo(vrp,algorithmConfig.getXMLConfiguration(),nThreads, null); public static VehicleRoutingAlgorithm createAlgorithm(final VehicleRoutingProblem vrp, int nThreads, final AlgorithmConfig algorithmConfig) {
return createAlgo(vrp, algorithmConfig.getXMLConfiguration(), nThreads, null);
} }
/** /**
@ -374,17 +374,18 @@ public class VehicleRoutingAlgorithms {
* @param configURL config url * @param configURL config url
* @return {@link jsprit.core.algorithm.VehicleRoutingAlgorithm} * @return {@link jsprit.core.algorithm.VehicleRoutingAlgorithm}
*/ */
public static VehicleRoutingAlgorithm readAndCreateAlgorithm(final VehicleRoutingProblem vrp, final URL configURL){ public static VehicleRoutingAlgorithm readAndCreateAlgorithm(final VehicleRoutingProblem vrp, final URL configURL) {
AlgorithmConfig algorithmConfig = new AlgorithmConfig(); AlgorithmConfig algorithmConfig = new AlgorithmConfig();
AlgorithmConfigXmlReader xmlReader = new AlgorithmConfigXmlReader(algorithmConfig); AlgorithmConfigXmlReader xmlReader = new AlgorithmConfigXmlReader(algorithmConfig);
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);
xmlReader.read(configURL); xmlReader.read(configURL);
return createAlgo(vrp,algorithmConfig.getXMLConfiguration(),nThreads, null); return createAlgo(vrp, algorithmConfig.getXMLConfiguration(), nThreads, null);
} }
/** /**
@ -394,35 +395,35 @@ public class VehicleRoutingAlgorithms {
* @param configFileName the config filename (and location) * @param configFileName the config filename (and location)
* @return {@link jsprit.core.algorithm.VehicleRoutingAlgorithm} * @return {@link jsprit.core.algorithm.VehicleRoutingAlgorithm}
*/ */
public static VehicleRoutingAlgorithm readAndCreateAlgorithm(final VehicleRoutingProblem vrp, final String configFileName){ public static VehicleRoutingAlgorithm readAndCreateAlgorithm(final VehicleRoutingProblem vrp, final String configFileName) {
AlgorithmConfig algorithmConfig = new AlgorithmConfig(); AlgorithmConfig algorithmConfig = new AlgorithmConfig();
AlgorithmConfigXmlReader xmlReader = new AlgorithmConfigXmlReader(algorithmConfig); AlgorithmConfigXmlReader xmlReader = new AlgorithmConfigXmlReader(algorithmConfig);
xmlReader.read(configFileName); xmlReader.read(configFileName);
return createAlgo(vrp,algorithmConfig.getXMLConfiguration(),0, null); return createAlgo(vrp, algorithmConfig.getXMLConfiguration(), 0, null);
} }
public static VehicleRoutingAlgorithm readAndCreateAlgorithm(final VehicleRoutingProblem vrp, final String configFileName, StateManager stateManager){ public static VehicleRoutingAlgorithm readAndCreateAlgorithm(final VehicleRoutingProblem vrp, final String configFileName, StateManager stateManager) {
AlgorithmConfig algorithmConfig = new AlgorithmConfig(); AlgorithmConfig algorithmConfig = new AlgorithmConfig();
AlgorithmConfigXmlReader xmlReader = new AlgorithmConfigXmlReader(algorithmConfig); AlgorithmConfigXmlReader xmlReader = new AlgorithmConfigXmlReader(algorithmConfig);
xmlReader.read(configFileName); xmlReader.read(configFileName);
return createAlgo(vrp,algorithmConfig.getXMLConfiguration(),0, stateManager); return createAlgo(vrp, algorithmConfig.getXMLConfiguration(), 0, stateManager);
} }
public static VehicleRoutingAlgorithm readAndCreateAlgorithm(final VehicleRoutingProblem vrp, int nThreads, final String configFileName, StateManager stateManager){ public static VehicleRoutingAlgorithm readAndCreateAlgorithm(final VehicleRoutingProblem vrp, int nThreads, final String configFileName, StateManager stateManager) {
AlgorithmConfig algorithmConfig = new AlgorithmConfig(); AlgorithmConfig algorithmConfig = new AlgorithmConfig();
AlgorithmConfigXmlReader xmlReader = new AlgorithmConfigXmlReader(algorithmConfig); AlgorithmConfigXmlReader xmlReader = new AlgorithmConfigXmlReader(algorithmConfig);
xmlReader.read(configFileName); xmlReader.read(configFileName);
return createAlgo(vrp,algorithmConfig.getXMLConfiguration(), nThreads, stateManager); return createAlgo(vrp, algorithmConfig.getXMLConfiguration(), nThreads, stateManager);
} }
public static VehicleRoutingAlgorithm readAndCreateAlgorithm(VehicleRoutingProblem vrp, int nThreads, String configFileName) { public static VehicleRoutingAlgorithm readAndCreateAlgorithm(VehicleRoutingProblem vrp, int nThreads, String configFileName) {
AlgorithmConfig algorithmConfig = new AlgorithmConfig(); AlgorithmConfig algorithmConfig = new AlgorithmConfig();
AlgorithmConfigXmlReader xmlReader = new AlgorithmConfigXmlReader(algorithmConfig); AlgorithmConfigXmlReader xmlReader = new AlgorithmConfigXmlReader(algorithmConfig);
xmlReader.read(configFileName); xmlReader.read(configFileName);
return createAlgo(vrp,algorithmConfig.getXMLConfiguration(),nThreads, null); return createAlgo(vrp, algorithmConfig.getXMLConfiguration(), nThreads, null);
} }
private static class OpenRouteStateVerifier implements StateUpdater, ReverseActivityVisitor{ private static class OpenRouteStateVerifier implements StateUpdater, ReverseActivityVisitor {
private End end; private End end;
@ -438,9 +439,9 @@ public class VehicleRoutingAlgorithms {
@Override @Override
public void visit(TourActivity activity) { public void visit(TourActivity activity) {
if(firstAct){ if (firstAct) {
firstAct=false; firstAct = false;
if(!vehicle.isReturnToDepot()){ if (!vehicle.isReturnToDepot()) {
assert activity.getLocation().getId().equals(end.getLocation().getId()) : "route end and last activity are not equal even route is open. this should not be."; assert activity.getLocation().getId().equals(end.getLocation().getId()) : "route end and last activity are not equal even route is open. this should not be.";
} }
} }
@ -454,13 +455,12 @@ public class VehicleRoutingAlgorithms {
} }
private static VehicleRoutingAlgorithm createAlgo(final VehicleRoutingProblem vrp, XMLConfiguration config, int nuOfThreads, StateManager stateMan){ private static VehicleRoutingAlgorithm createAlgo(final VehicleRoutingProblem vrp, XMLConfiguration config, int nuOfThreads, StateManager stateMan) {
//create state-manager //create state-manager
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();
@ -475,17 +475,18 @@ public class VehicleRoutingAlgorithms {
* define constraints * define constraints
*/ */
//constraint manager //constraint manager
ConstraintManager constraintManager = new ConstraintManager(vrp,stateManager); ConstraintManager constraintManager = new ConstraintManager(vrp, stateManager);
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);
} }
public static VehicleRoutingAlgorithm readAndCreateAlgorithm(final VehicleRoutingProblem vrp, AlgorithmConfig config, public static VehicleRoutingAlgorithm readAndCreateAlgorithm(final VehicleRoutingProblem vrp, AlgorithmConfig config,
int nuOfThreads, SolutionCostCalculator solutionCostCalculator, final StateManager stateManager, ConstraintManager constraintManager, boolean addDefaultCostCalculators) { int nuOfThreads, SolutionCostCalculator solutionCostCalculator, final StateManager stateManager, ConstraintManager constraintManager, boolean addDefaultCostCalculators) {
return readAndCreateAlgorithm(vrp, config.getXMLConfiguration(),nuOfThreads, solutionCostCalculator, stateManager, constraintManager, addDefaultCostCalculators); return readAndCreateAlgorithm(vrp, config.getXMLConfiguration(), nuOfThreads, solutionCostCalculator, stateManager, constraintManager, addDefaultCostCalculators);
} }
private static VehicleRoutingAlgorithm readAndCreateAlgorithm(final VehicleRoutingProblem vrp, XMLConfiguration config, private static VehicleRoutingAlgorithm readAndCreateAlgorithm(final VehicleRoutingProblem vrp, XMLConfiguration config,
@ -502,13 +503,13 @@ public class VehicleRoutingAlgorithms {
//threading //threading
final ExecutorService executorService; final ExecutorService executorService;
if(nuOfThreads > 0){ if (nuOfThreads > 0) {
log.debug("setup executor-service with " + nuOfThreads + " threads"); log.debug("setup executor-service with " + nuOfThreads + " threads");
executorService = Executors.newFixedThreadPool(nuOfThreads); executorService = Executors.newFixedThreadPool(nuOfThreads);
algorithmListeners.add(new PrioritizedVRAListener(Priority.LOW, new AlgorithmEndsListener() { algorithmListeners.add(new PrioritizedVRAListener(Priority.LOW, new AlgorithmEndsListener() {
@Override @Override
public void informAlgorithmEnds(VehicleRoutingProblem problem,Collection<VehicleRoutingProblemSolution> solutions) { public void informAlgorithmEnds(VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions) {
log.debug("shutdown executor-service"); log.debug("shutdown executor-service");
executorService.shutdown(); executorService.shutdown();
} }
@ -521,16 +522,15 @@ public class VehicleRoutingAlgorithms {
System.exit(0); System.exit(0);
} }
}); });
Runtime.getRuntime().addShutdownHook(new Thread(){ Runtime.getRuntime().addShutdownHook(new Thread() {
public void run(){ public void run() {
if(!executorService.isShutdown()){ if (!executorService.isShutdown()) {
System.err.println("shutdowHook shuts down executorService"); System.err.println("shutdowHook shuts down executorService");
executorService.shutdown(); executorService.shutdown();
} }
} }
}); });
} } else executorService = null;
else executorService = null;
//create fleetmanager //create fleetmanager
@ -538,22 +538,21 @@ public class VehicleRoutingAlgorithms {
String switchString = config.getString("construction.insertion.allowVehicleSwitch"); String switchString = config.getString("construction.insertion.allowVehicleSwitch");
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());
timeWindowUpdater.setVehiclesToUpdate(new UpdateVehicleDependentPracticalTimeWindows.VehiclesToUpdate() { timeWindowUpdater.setVehiclesToUpdate(new UpdateVehicleDependentPracticalTimeWindows.VehiclesToUpdate() {
Map<VehicleTypeKey,Vehicle> uniqueTypes = new HashMap<VehicleTypeKey,Vehicle>(); Map<VehicleTypeKey, Vehicle> uniqueTypes = new HashMap<VehicleTypeKey, Vehicle>();
@Override @Override
public Collection<Vehicle> get(VehicleRoute vehicleRoute) { public Collection<Vehicle> get(VehicleRoute vehicleRoute) {
if(uniqueTypes.isEmpty()){ if (uniqueTypes.isEmpty()) {
for( Vehicle v : vrp.getVehicles()){ for (Vehicle v : vrp.getVehicles()) {
if(!uniqueTypes.containsKey(v.getVehicleTypeIdentifier())){ if (!uniqueTypes.containsKey(v.getVehicleTypeIdentifier())) {
uniqueTypes.put(v.getVehicleTypeIdentifier(),v); uniqueTypes.put(v.getVehicleTypeIdentifier(), v);
} }
} }
} }
@ -564,56 +563,57 @@ 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));
stateManager.addStateUpdater(new UpdateVariableCosts(vrp.getActivityCosts(), vrp.getTransportCosts(), stateManager, activityPolicy)); stateManager.addStateUpdater(new UpdateVariableCosts(vrp.getActivityCosts(), vrp.getTransportCosts(), stateManager, activityPolicy));
final SolutionCostCalculator costCalculator; final SolutionCostCalculator costCalculator;
if(solutionCostCalculator==null) costCalculator = getDefaultCostCalculator(stateManager); if (solutionCostCalculator == null) costCalculator = getDefaultCostCalculator(stateManager);
else costCalculator = solutionCostCalculator; else costCalculator = solutionCostCalculator;
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");
List<HierarchicalConfiguration> strategyConfigs = config.configurationsAt("strategy.searchStrategies.searchStrategy"); List<HierarchicalConfiguration> strategyConfigs = config.configurationsAt("strategy.searchStrategies.searchStrategy");
for(HierarchicalConfiguration strategyConfig : strategyConfigs){ for (HierarchicalConfiguration strategyConfig : strategyConfigs) {
String name = getName(strategyConfig); String name = getName(strategyConfig);
SolutionAcceptor acceptor = getAcceptor(strategyConfig,vrp,algorithmListeners,definedClasses,solutionMemory); SolutionAcceptor acceptor = getAcceptor(strategyConfig, vrp, algorithmListeners, definedClasses, solutionMemory);
SolutionSelector selector = getSelector(strategyConfig,vrp,algorithmListeners,definedClasses); SolutionSelector selector = getSelector(strategyConfig, vrp, algorithmListeners, definedClasses);
SearchStrategy strategy = new SearchStrategy(name, selector, acceptor, costCalculator); SearchStrategy strategy = new SearchStrategy(name, selector, acceptor, costCalculator);
strategy.setName(name); strategy.setName(name);
List<HierarchicalConfiguration> modulesConfig = strategyConfig.configurationsAt("modules.module"); List<HierarchicalConfiguration> modulesConfig = strategyConfig.configurationsAt("modules.module");
for(HierarchicalConfiguration moduleConfig : modulesConfig){ for (HierarchicalConfiguration moduleConfig : modulesConfig) {
SearchStrategyModule module = buildModule(moduleConfig,vrp,vehicleFleetManager,stateManager,algorithmListeners,definedClasses,executorService,nuOfThreads, constraintManager, addDefaultCostCalculators); SearchStrategyModule module = buildModule(moduleConfig, vrp, vehicleFleetManager, stateManager, algorithmListeners, definedClasses, executorService, nuOfThreads, constraintManager, addDefaultCostCalculators);
strategy.addModule(module); strategy.addModule(module);
} }
prettyAlgorithmBuilder.withStrategy(strategy,strategyConfig.getDouble("probability")); prettyAlgorithmBuilder.withStrategy(strategy, strategyConfig.getDouble("probability"));
} }
//construct algorithm //construct algorithm
VehicleRoutingAlgorithm metaAlgorithm = prettyAlgorithmBuilder.build(); VehicleRoutingAlgorithm metaAlgorithm = prettyAlgorithmBuilder.build();
int maxIterations = getMaxIterations(config); int maxIterations = getMaxIterations(config);
if(maxIterations > -1) metaAlgorithm.setMaxIterations(maxIterations); if (maxIterations > -1) metaAlgorithm.setMaxIterations(maxIterations);
//define prematureBreak //define prematureBreak
PrematureAlgorithmTermination prematureAlgorithmTermination = getPrematureTermination(config, algorithmListeners); PrematureAlgorithmTermination prematureAlgorithmTermination = getPrematureTermination(config, algorithmListeners);
if(prematureAlgorithmTermination != null) metaAlgorithm.setPrematureAlgorithmTermination(prematureAlgorithmTermination); if (prematureAlgorithmTermination != null)
else{ metaAlgorithm.setPrematureAlgorithmTermination(prematureAlgorithmTermination);
else {
List<HierarchicalConfiguration> terminationCriteria = config.configurationsAt("terminationCriteria.termination"); List<HierarchicalConfiguration> terminationCriteria = config.configurationsAt("terminationCriteria.termination");
for(HierarchicalConfiguration terminationConfig : terminationCriteria){ for (HierarchicalConfiguration terminationConfig : terminationCriteria) {
PrematureAlgorithmTermination termination = getTerminationCriterion(terminationConfig, algorithmListeners); PrematureAlgorithmTermination termination = getTerminationCriterion(terminationConfig, algorithmListeners);
if(termination != null) metaAlgorithm.addTerminationCriterion(termination); if (termination != null) metaAlgorithm.addTerminationCriterion(termination);
} }
} }
for(PrioritizedVRAListener l : algorithmListeners){ for (PrioritizedVRAListener l : algorithmListeners) {
metaAlgorithm.getAlgorithmListeners().add(l); metaAlgorithm.getAlgorithmListeners().add(l);
} }
return metaAlgorithm; return metaAlgorithm;
@ -621,8 +621,8 @@ public class VehicleRoutingAlgorithms {
private static int getMaxIterations(XMLConfiguration config) { private static int getMaxIterations(XMLConfiguration config) {
String maxIterationsString = config.getString("iterations"); String maxIterationsString = config.getString("iterations");
if(maxIterationsString == null) maxIterationsString = config.getString("maxIterations"); if (maxIterationsString == null) maxIterationsString = config.getString("maxIterations");
if(maxIterationsString != null) return (Integer.parseInt(maxIterationsString)); if (maxIterationsString != null) return (Integer.parseInt(maxIterationsString));
return -1; return -1;
} }
@ -631,11 +631,10 @@ public class VehicleRoutingAlgorithms {
} }
private static VehicleFleetManager createFleetManager(final VehicleRoutingProblem vrp) { private static VehicleFleetManager createFleetManager(final VehicleRoutingProblem vrp) {
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. " +
@ -644,32 +643,32 @@ public class VehicleRoutingAlgorithms {
private static PrematureAlgorithmTermination getTerminationCriterion(HierarchicalConfiguration config, Set<PrioritizedVRAListener> algorithmListeners) { private static PrematureAlgorithmTermination getTerminationCriterion(HierarchicalConfiguration config, Set<PrioritizedVRAListener> algorithmListeners) {
String basedOn = config.getString("[@basedOn]"); String basedOn = config.getString("[@basedOn]");
if(basedOn == null){ if (basedOn == null) {
log.debug("set default prematureBreak, i.e. no premature break at all."); log.debug("set default prematureBreak, i.e. no premature break at all.");
return null; return null;
} }
if(basedOn.equals("iterations")){ if (basedOn.equals("iterations")) {
log.debug("set prematureBreak based on iterations"); log.debug("set prematureBreak based on iterations");
String iter = config.getString("iterations"); String iter = config.getString("iterations");
if(iter == null) throw new IllegalStateException("iterations is missing"); if (iter == null) throw new IllegalStateException("iterations is missing");
int iterations = Integer.valueOf(iter); int iterations = Integer.valueOf(iter);
return new IterationWithoutImprovementTermination(iterations); return new IterationWithoutImprovementTermination(iterations);
} }
if(basedOn.equals("time")){ if (basedOn.equals("time")) {
log.debug("set prematureBreak based on time"); log.debug("set prematureBreak based on time");
String timeString = config.getString("time"); String timeString = config.getString("time");
if(timeString == null) throw new IllegalStateException("time is missing"); if (timeString == null) throw new IllegalStateException("time is missing");
long time = Long.parseLong(timeString); long time = Long.parseLong(timeString);
TimeTermination timeBreaker = new TimeTermination(time); TimeTermination timeBreaker = new TimeTermination(time);
algorithmListeners.add(new PrioritizedVRAListener(Priority.LOW, timeBreaker)); algorithmListeners.add(new PrioritizedVRAListener(Priority.LOW, timeBreaker));
return timeBreaker; return timeBreaker;
} }
if(basedOn.equals("variationCoefficient")){ if (basedOn.equals("variationCoefficient")) {
log.debug("set prematureBreak based on variation coefficient"); log.debug("set prematureBreak based on variation coefficient");
String thresholdString = config.getString("threshold"); String thresholdString = config.getString("threshold");
String iterationsString = config.getString("iterations"); String iterationsString = config.getString("iterations");
if(thresholdString == null) throw new IllegalStateException("threshold is missing"); if (thresholdString == null) throw new IllegalStateException("threshold is missing");
if(iterationsString == null) throw new IllegalStateException("iterations is missing"); if (iterationsString == null) throw new IllegalStateException("iterations is missing");
double threshold = Double.valueOf(thresholdString); double threshold = Double.valueOf(thresholdString);
int iterations = Integer.valueOf(iterationsString); int iterations = Integer.valueOf(iterationsString);
VariationCoefficientTermination variationCoefficientBreaker = new VariationCoefficientTermination(iterations, threshold); VariationCoefficientTermination variationCoefficientBreaker = new VariationCoefficientTermination(iterations, threshold);
@ -681,32 +680,32 @@ public class VehicleRoutingAlgorithms {
private static PrematureAlgorithmTermination getPrematureTermination(XMLConfiguration config, Set<PrioritizedVRAListener> algorithmListeners) { private static PrematureAlgorithmTermination getPrematureTermination(XMLConfiguration config, Set<PrioritizedVRAListener> algorithmListeners) {
String basedOn = config.getString("prematureBreak[@basedOn]"); String basedOn = config.getString("prematureBreak[@basedOn]");
if(basedOn == null){ if (basedOn == null) {
log.debug("set default prematureBreak, i.e. no premature break at all."); log.debug("set default prematureBreak, i.e. no premature break at all.");
return null; return null;
} }
if(basedOn.equals("iterations")){ if (basedOn.equals("iterations")) {
log.debug("set prematureBreak based on iterations"); log.debug("set prematureBreak based on iterations");
String iter = config.getString("prematureBreak.iterations"); String iter = config.getString("prematureBreak.iterations");
if(iter == null) throw new IllegalStateException("prematureBreak.iterations is missing"); if (iter == null) throw new IllegalStateException("prematureBreak.iterations is missing");
int iterations = Integer.valueOf(iter); int iterations = Integer.valueOf(iter);
return new IterationWithoutImprovementTermination(iterations); return new IterationWithoutImprovementTermination(iterations);
} }
if(basedOn.equals("time")){ if (basedOn.equals("time")) {
log.debug("set prematureBreak based on time"); log.debug("set prematureBreak based on time");
String timeString = config.getString("prematureBreak.time"); String timeString = config.getString("prematureBreak.time");
if(timeString == null) throw new IllegalStateException("prematureBreak.time is missing"); if (timeString == null) throw new IllegalStateException("prematureBreak.time is missing");
long time = Long.parseLong(timeString); long time = Long.parseLong(timeString);
TimeTermination timeBreaker = new TimeTermination(time); TimeTermination timeBreaker = new TimeTermination(time);
algorithmListeners.add(new PrioritizedVRAListener(Priority.LOW, timeBreaker)); algorithmListeners.add(new PrioritizedVRAListener(Priority.LOW, timeBreaker));
return timeBreaker; return timeBreaker;
} }
if(basedOn.equals("variationCoefficient")){ if (basedOn.equals("variationCoefficient")) {
log.debug("set prematureBreak based on variation coefficient"); log.debug("set prematureBreak based on variation coefficient");
String thresholdString = config.getString("prematureBreak.threshold"); String thresholdString = config.getString("prematureBreak.threshold");
String iterationsString = config.getString("prematureBreak.iterations"); String iterationsString = config.getString("prematureBreak.iterations");
if(thresholdString == null) throw new IllegalStateException("prematureBreak.threshold is missing"); if (thresholdString == null) throw new IllegalStateException("prematureBreak.threshold is missing");
if(iterationsString == null) throw new IllegalStateException("prematureBreak.iterations is missing"); if (iterationsString == null) throw new IllegalStateException("prematureBreak.iterations is missing");
double threshold = Double.valueOf(thresholdString); double threshold = Double.valueOf(thresholdString);
int iterations = Integer.valueOf(iterationsString); int iterations = Integer.valueOf(iterationsString);
VariationCoefficientTermination variationCoefficientBreaker = new VariationCoefficientTermination(iterations, threshold); VariationCoefficientTermination variationCoefficientBreaker = new VariationCoefficientTermination(iterations, threshold);
@ -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 "";
@ -724,43 +724,44 @@ public class VehicleRoutingAlgorithms {
private static InsertionStrategy createInitialSolution(XMLConfiguration config, final VehicleRoutingProblem vrp, VehicleFleetManager vehicleFleetManager, final StateManager routeStates, Set<PrioritizedVRAListener> algorithmListeners, TypedMap definedClasses, ExecutorService executorService, int nuOfThreads, final SolutionCostCalculator solutionCostCalculator, ConstraintManager constraintManager, boolean addDefaultCostCalculators) { private static InsertionStrategy createInitialSolution(XMLConfiguration config, final VehicleRoutingProblem vrp, VehicleFleetManager vehicleFleetManager, final StateManager routeStates, Set<PrioritizedVRAListener> algorithmListeners, TypedMap definedClasses, ExecutorService executorService, int nuOfThreads, final SolutionCostCalculator solutionCostCalculator, ConstraintManager constraintManager, boolean addDefaultCostCalculators) {
List<HierarchicalConfiguration> modConfigs = config.configurationsAt("construction.insertion"); List<HierarchicalConfiguration> modConfigs = config.configurationsAt("construction.insertion");
if(modConfigs == null) return null; if (modConfigs == null) return null;
if(modConfigs.isEmpty()) return null; if (modConfigs.isEmpty()) return null;
if(modConfigs.size() != 1) throw new IllegalStateException("#construction.modules != 1. 1 expected"); if (modConfigs.size() != 1) throw new IllegalStateException("#construction.modules != 1. 1 expected");
HierarchicalConfiguration modConfig = modConfigs.get(0); HierarchicalConfiguration modConfig = modConfigs.get(0);
String insertionName = modConfig.getString("[@name]"); String insertionName = modConfig.getString("[@name]");
if(insertionName == null) throw new IllegalStateException("insertion[@name] is missing."); if (insertionName == null) throw new IllegalStateException("insertion[@name] is missing.");
String insertionId = modConfig.getString("[@id]"); String insertionId = modConfig.getString("[@id]");
if(insertionId == null) insertionId = "noId"; if (insertionId == null) insertionId = "noId";
ModKey modKey = makeKey(insertionName,insertionId); ModKey modKey = makeKey(insertionName, insertionId);
InsertionStrategyKey insertionStrategyKey = new InsertionStrategyKey(modKey); InsertionStrategyKey insertionStrategyKey = new InsertionStrategyKey(modKey);
InsertionStrategy insertionStrategy = definedClasses.get(insertionStrategyKey); InsertionStrategy insertionStrategy = definedClasses.get(insertionStrategyKey);
if(insertionStrategy == null){ if (insertionStrategy == null) {
List<PrioritizedVRAListener> prioListeners = new ArrayList<PrioritizedVRAListener>(); List<PrioritizedVRAListener> prioListeners = new ArrayList<PrioritizedVRAListener>();
insertionStrategy = createInsertionStrategy(modConfig, vrp, vehicleFleetManager, routeStates, prioListeners, executorService, nuOfThreads, constraintManager, addDefaultCostCalculators); insertionStrategy = createInsertionStrategy(modConfig, vrp, vehicleFleetManager, routeStates, prioListeners, executorService, nuOfThreads, constraintManager, addDefaultCostCalculators);
algorithmListeners.addAll(prioListeners); algorithmListeners.addAll(prioListeners);
definedClasses.put(insertionStrategyKey,insertionStrategy); definedClasses.put(insertionStrategyKey, insertionStrategy);
} }
return insertionStrategy; return insertionStrategy;
} }
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);
SelectorKey selectorKey = new SelectorKey(modKey); SelectorKey selectorKey = new SelectorKey(modKey);
SolutionSelector definedSelector = definedSelectors.get(selectorKey); SolutionSelector definedSelector = definedSelectors.get(selectorKey);
if(definedSelector != null) { if (definedSelector != null) {
return definedSelector; return definedSelector;
} }
if(selectorName.equals("selectRandomly")){ if (selectorName.equals("selectRandomly")) {
SelectRandomly selector = SelectRandomly.getInstance(); SelectRandomly selector = SelectRandomly.getInstance();
definedSelectors.put(selectorKey, selector); definedSelectors.put(selectorKey, selector);
return selector; return selector;
} }
if(selectorName.equals("selectBest")){ if (selectorName.equals("selectBest")) {
SelectBest selector = SelectBest.getInstance(); SelectBest selector = SelectBest.getInstance();
definedSelectors.put(selectorKey, selector); definedSelectors.put(selectorKey, selector);
return selector; return selector;
@ -768,47 +769,46 @@ public class VehicleRoutingAlgorithms {
throw new IllegalStateException("solutionSelector is not know. Currently, it only knows \"selectRandomly\" and \"selectBest\""); throw new IllegalStateException("solutionSelector is not know. Currently, it only knows \"selectRandomly\" and \"selectBest\"");
} }
private static ModKey makeKey(String name, String id){ private static ModKey makeKey(String name, String id) {
return new ModKey(name, id); return new ModKey(name, id);
} }
private static SolutionAcceptor getAcceptor(HierarchicalConfiguration strategyConfig, VehicleRoutingProblem vrp, Set<PrioritizedVRAListener> algorithmListeners, TypedMap typedMap, int solutionMemory) { private static SolutionAcceptor getAcceptor(HierarchicalConfiguration strategyConfig, VehicleRoutingProblem vrp, Set<PrioritizedVRAListener> algorithmListeners, TypedMap typedMap, int solutionMemory) {
String acceptorName = strategyConfig.getString("acceptor[@name]"); String acceptorName = strategyConfig.getString("acceptor[@name]");
if(acceptorName == null) throw new IllegalStateException("no solution acceptor is defined"); if (acceptorName == null) throw new IllegalStateException("no solution acceptor is defined");
String acceptorId = strategyConfig.getString("acceptor[@id]"); String acceptorId = strategyConfig.getString("acceptor[@id]");
if(acceptorId == null) acceptorId = "noId"; if (acceptorId == null) acceptorId = "noId";
AcceptorKey acceptorKey = new AcceptorKey(makeKey(acceptorName,acceptorId)); AcceptorKey acceptorKey = new AcceptorKey(makeKey(acceptorName, acceptorId));
SolutionAcceptor definedAcceptor = typedMap.get(acceptorKey); SolutionAcceptor definedAcceptor = typedMap.get(acceptorKey);
if(definedAcceptor != null) return definedAcceptor; if (definedAcceptor != null) return definedAcceptor;
if(acceptorName.equals("acceptNewRemoveWorst")){ if (acceptorName.equals("acceptNewRemoveWorst")) {
GreedyAcceptance acceptor = new GreedyAcceptance(solutionMemory); GreedyAcceptance acceptor = new GreedyAcceptance(solutionMemory);
typedMap.put(acceptorKey, acceptor); typedMap.put(acceptorKey, acceptor);
return acceptor; return acceptor;
} }
if(acceptorName.equals("acceptNewRemoveFirst")){ if (acceptorName.equals("acceptNewRemoveFirst")) {
AcceptNewRemoveFirst acceptor = new AcceptNewRemoveFirst(solutionMemory); AcceptNewRemoveFirst acceptor = new AcceptNewRemoveFirst(solutionMemory);
typedMap.put(acceptorKey, acceptor); typedMap.put(acceptorKey, acceptor);
return acceptor; return acceptor;
} }
if(acceptorName.equals("greedyAcceptance")){ if (acceptorName.equals("greedyAcceptance")) {
GreedyAcceptance acceptor = new GreedyAcceptance(solutionMemory); GreedyAcceptance acceptor = new GreedyAcceptance(solutionMemory);
typedMap.put(acceptorKey, acceptor); typedMap.put(acceptorKey, acceptor);
return acceptor; return acceptor;
} }
if(acceptorName.equals("greedyAcceptance_minVehFirst")){ if (acceptorName.equals("greedyAcceptance_minVehFirst")) {
GreedyAcceptance_minVehFirst acceptor = new GreedyAcceptance_minVehFirst(solutionMemory); GreedyAcceptance_minVehFirst acceptor = new GreedyAcceptance_minVehFirst(solutionMemory);
typedMap.put(acceptorKey, acceptor); typedMap.put(acceptorKey, acceptor);
return acceptor; return acceptor;
} }
if(acceptorName.equals("schrimpfAcceptance")){ if (acceptorName.equals("schrimpfAcceptance")) {
String nuWarmupIterations = strategyConfig.getString("acceptor.warmup"); String nuWarmupIterations = strategyConfig.getString("acceptor.warmup");
double alpha = strategyConfig.getDouble("acceptor.alpha"); double alpha = strategyConfig.getDouble("acceptor.alpha");
SchrimpfAcceptance schrimpf = new SchrimpfAcceptance(solutionMemory, alpha); SchrimpfAcceptance schrimpf = new SchrimpfAcceptance(solutionMemory, alpha);
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);
} }
@ -816,15 +816,14 @@ public class VehicleRoutingAlgorithms {
typedMap.put(acceptorKey, schrimpf); typedMap.put(acceptorKey, schrimpf);
return schrimpf; return schrimpf;
} }
if(acceptorName.equals("experimentalSchrimpfAcceptance")){ if (acceptorName.equals("experimentalSchrimpfAcceptance")) {
int iterOfSchrimpf = strategyConfig.getInt("acceptor.warmup"); int iterOfSchrimpf = strategyConfig.getInt("acceptor.warmup");
double alpha = strategyConfig.getDouble("acceptor.alpha"); double alpha = strategyConfig.getDouble("acceptor.alpha");
ExperimentalSchrimpfAcceptance schrimpf = new ExperimentalSchrimpfAcceptance(solutionMemory, alpha, iterOfSchrimpf); ExperimentalSchrimpfAcceptance schrimpf = new ExperimentalSchrimpfAcceptance(solutionMemory, alpha, iterOfSchrimpf);
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");
} }
} }
@ -832,43 +831,43 @@ public class VehicleRoutingAlgorithms {
private static SearchStrategyModule buildModule(HierarchicalConfiguration moduleConfig, final VehicleRoutingProblem vrp, VehicleFleetManager vehicleFleetManager, private static SearchStrategyModule buildModule(HierarchicalConfiguration moduleConfig, final VehicleRoutingProblem vrp, VehicleFleetManager vehicleFleetManager,
final StateManager routeStates, Set<PrioritizedVRAListener> algorithmListeners, TypedMap definedClasses, ExecutorService executorService, int nuOfThreads, ConstraintManager constraintManager, boolean addDefaultCostCalculators) { final StateManager routeStates, Set<PrioritizedVRAListener> algorithmListeners, TypedMap definedClasses, ExecutorService executorService, int nuOfThreads, ConstraintManager constraintManager, boolean addDefaultCostCalculators) {
String moduleName = moduleConfig.getString("[@name]"); String moduleName = moduleConfig.getString("[@name]");
if(moduleName == null) throw new IllegalStateException("module(-name) is missing."); if (moduleName == null) throw new IllegalStateException("module(-name) is missing.");
String moduleId = moduleConfig.getString("[@id]"); String moduleId = moduleConfig.getString("[@id]");
if(moduleId == null) moduleId = "noId"; if (moduleId == null) moduleId = "noId";
ModKey modKey = makeKey(moduleName,moduleId); ModKey modKey = makeKey(moduleName, moduleId);
StrategyModuleKey strategyModuleKey = new StrategyModuleKey(modKey); StrategyModuleKey strategyModuleKey = new StrategyModuleKey(modKey);
SearchStrategyModule definedModule = definedClasses.get(strategyModuleKey); SearchStrategyModule definedModule = definedClasses.get(strategyModuleKey);
if(definedModule != null) return definedModule; if (definedModule != null) return definedModule;
if(moduleName.equals("ruin_and_recreate")){ if (moduleName.equals("ruin_and_recreate")) {
String ruin_name = moduleConfig.getString("ruin[@name]"); String ruin_name = moduleConfig.getString("ruin[@name]");
if(ruin_name == null) throw new IllegalStateException("module.ruin[@name] is missing."); if (ruin_name == null) throw new IllegalStateException("module.ruin[@name] is missing.");
String ruin_id = moduleConfig.getString("ruin[@id]"); String ruin_id = moduleConfig.getString("ruin[@id]");
if(ruin_id == null) ruin_id = "noId"; if (ruin_id == null) ruin_id = "noId";
String shareToRuinString = moduleConfig.getString("ruin.share"); String shareToRuinString = moduleConfig.getString("ruin.share");
if(shareToRuinString == null) throw new IllegalStateException("module.ruin.share is missing."); if (shareToRuinString == null) throw new IllegalStateException("module.ruin.share is missing.");
double shareToRuin = Double.valueOf(shareToRuinString); double shareToRuin = Double.valueOf(shareToRuinString);
final RuinStrategy ruin; final RuinStrategy ruin;
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);
InsertionStrategyKey insertionStrategyKey = new InsertionStrategyKey(insertionKey); InsertionStrategyKey insertionStrategyKey = new InsertionStrategyKey(insertionKey);
InsertionStrategy insertion = definedClasses.get(insertionStrategyKey); InsertionStrategy insertion = definedClasses.get(insertionStrategyKey);
if(insertion == null){ if (insertion == null) {
List<HierarchicalConfiguration> insertionConfigs = moduleConfig.configurationsAt("insertion"); List<HierarchicalConfiguration> insertionConfigs = moduleConfig.configurationsAt("insertion");
if(insertionConfigs.size() != 1) throw new IllegalStateException("this should be 1"); if (insertionConfigs.size() != 1) throw new IllegalStateException("this should be 1");
List<PrioritizedVRAListener> prioListeners = new ArrayList<PrioritizedVRAListener>(); List<PrioritizedVRAListener> prioListeners = new ArrayList<PrioritizedVRAListener>();
insertion = createInsertionStrategy(insertionConfigs.get(0), vrp, vehicleFleetManager, routeStates, prioListeners, executorService, nuOfThreads, constraintManager, addDefaultCostCalculators); insertion = createInsertionStrategy(insertionConfigs.get(0), vrp, vehicleFleetManager, routeStates, prioListeners, executorService, nuOfThreads, constraintManager, addDefaultCostCalculators);
algorithmListeners.addAll(prioListeners); algorithmListeners.addAll(prioListeners);
@ -889,7 +888,7 @@ public class VehicleRoutingAlgorithms {
private static RuinStrategy getRadialRuin(final VehicleRoutingProblem vrp, final StateManager routeStates, TypedMap definedClasses, ModKey modKey, double shareToRuin, JobDistance jobDistance) { private static RuinStrategy getRadialRuin(final VehicleRoutingProblem vrp, final StateManager routeStates, TypedMap definedClasses, ModKey modKey, double shareToRuin, JobDistance jobDistance) {
RuinStrategyKey stratKey = new RuinStrategyKey(modKey); RuinStrategyKey stratKey = new RuinStrategyKey(modKey);
RuinStrategy ruin = definedClasses.get(stratKey); RuinStrategy ruin = definedClasses.get(stratKey);
if(ruin == null){ if (ruin == null) {
ruin = new RadialRuinStrategyFactory(shareToRuin, jobDistance).createStrategy(vrp); ruin = new RadialRuinStrategyFactory(shareToRuin, jobDistance).createStrategy(vrp);
definedClasses.put(stratKey, ruin); definedClasses.put(stratKey, ruin);
} }
@ -899,18 +898,16 @@ public class VehicleRoutingAlgorithms {
private static RuinStrategy getRandomRuin(final VehicleRoutingProblem vrp, final StateManager routeStates, TypedMap definedClasses, ModKey modKey, double shareToRuin) { private static RuinStrategy getRandomRuin(final VehicleRoutingProblem vrp, final StateManager routeStates, TypedMap definedClasses, ModKey modKey, double shareToRuin) {
RuinStrategyKey stratKey = new RuinStrategyKey(modKey); RuinStrategyKey stratKey = new RuinStrategyKey(modKey);
RuinStrategy ruin = definedClasses.get(stratKey); RuinStrategy ruin = definedClasses.get(stratKey);
if(ruin == null){ if (ruin == null) {
ruin = new RandomRuinStrategyFactory(shareToRuin).createStrategy(vrp); ruin = new RandomRuinStrategyFactory(shareToRuin).createStrategy(vrp);
definedClasses.put(stratKey, ruin); definedClasses.put(stratKey, ruin);
} }
return ruin; return ruin;
} }
private static InsertionStrategy createInsertionStrategy(HierarchicalConfiguration moduleConfig, VehicleRoutingProblem vrp,VehicleFleetManager vehicleFleetManager, StateManager routeStates, List<PrioritizedVRAListener> algorithmListeners, ExecutorService executorService, int nuOfThreads, ConstraintManager constraintManager, boolean addDefaultCostCalculators) { private static InsertionStrategy createInsertionStrategy(HierarchicalConfiguration moduleConfig, VehicleRoutingProblem vrp, VehicleFleetManager vehicleFleetManager, StateManager routeStates, List<PrioritizedVRAListener> algorithmListeners, ExecutorService executorService, int nuOfThreads, ConstraintManager constraintManager, boolean addDefaultCostCalculators) {
return InsertionFactory.createInsertion(vrp, moduleConfig, vehicleFleetManager, routeStates, algorithmListeners, executorService, nuOfThreads, constraintManager, addDefaultCostCalculators); return InsertionFactory.createInsertion(vrp, moduleConfig, vehicleFleetManager, routeStates, algorithmListeners, executorService, nuOfThreads, constraintManager, addDefaultCostCalculators);
} }
} }

View file

@ -22,9 +22,7 @@ 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,9 +23,7 @@ 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,10 +22,7 @@ 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,9 +22,7 @@ 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

@ -16,6 +16,6 @@
******************************************************************************/ ******************************************************************************/
package jsprit.core.algorithm.listener; package jsprit.core.algorithm.listener;
public interface SearchStrategyListener extends VehicleRoutingAlgorithmListener{ public interface SearchStrategyListener extends VehicleRoutingAlgorithmListener {
} }

View file

@ -16,6 +16,6 @@
******************************************************************************/ ******************************************************************************/
package jsprit.core.algorithm.listener; package jsprit.core.algorithm.listener;
public interface SearchStrategyModuleListener extends VehicleRoutingAlgorithmListener{ public interface SearchStrategyModuleListener extends VehicleRoutingAlgorithmListener {
} }

View file

@ -23,9 +23,7 @@ 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;
} }
@ -86,17 +87,14 @@ public class VehicleRoutingAlgorithmListeners {
@Override @Override
public int compare(PrioritizedVRAListener o1, PrioritizedVRAListener o2) { public int compare(PrioritizedVRAListener o1, PrioritizedVRAListener o2) {
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;
@ -106,76 +104,76 @@ public class VehicleRoutingAlgorithmListeners {
public Collection<VehicleRoutingAlgorithmListener> getAlgorithmListeners() { public Collection<VehicleRoutingAlgorithmListener> getAlgorithmListeners() {
List<VehicleRoutingAlgorithmListener> list = new ArrayList<VehicleRoutingAlgorithmListener>(); List<VehicleRoutingAlgorithmListener> list = new ArrayList<VehicleRoutingAlgorithmListener>();
for(PrioritizedVRAListener l : algorithmListeners){ for (PrioritizedVRAListener l : algorithmListeners) {
list.add(l.getListener()); list.add(l.getListener());
} }
return Collections.unmodifiableCollection(list); return Collections.unmodifiableCollection(list);
} }
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) {
algorithmListeners.add(new PrioritizedVRAListener(priority, listener)); algorithmListeners.add(new PrioritizedVRAListener(priority, listener));
} }
public void addListener(VehicleRoutingAlgorithmListener listener){ public void addListener(VehicleRoutingAlgorithmListener listener) {
addListener(listener, Priority.LOW); addListener(listener, Priority.LOW);
} }
public void algorithmEnds(VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions) { public void algorithmEnds(VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions) {
for(PrioritizedVRAListener l : algorithmListeners){ for (PrioritizedVRAListener l : algorithmListeners) {
if(l.getListener() instanceof AlgorithmEndsListener){ if (l.getListener() instanceof AlgorithmEndsListener) {
((AlgorithmEndsListener)l.getListener()).informAlgorithmEnds(problem, solutions); ((AlgorithmEndsListener) l.getListener()).informAlgorithmEnds(problem, solutions);
} }
} }
} }
public void iterationEnds(int i, VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions) { public void iterationEnds(int i, VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions) {
for(PrioritizedVRAListener l : algorithmListeners){ for (PrioritizedVRAListener l : algorithmListeners) {
if(l.getListener() instanceof IterationEndsListener){ if (l.getListener() instanceof IterationEndsListener) {
((IterationEndsListener)l.getListener()).informIterationEnds(i,problem, solutions); ((IterationEndsListener) l.getListener()).informIterationEnds(i, problem, solutions);
} }
} }
} }
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) {
((IterationStartsListener)l.getListener()).informIterationStarts(i,problem, solutions); ((IterationStartsListener) l.getListener()).informIterationStarts(i, problem, solutions);
} }
} }
} }
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) {
((AlgorithmStartsListener)l.getListener()).informAlgorithmStarts(problem, algorithm, solutions); ((AlgorithmStartsListener) l.getListener()).informAlgorithmStarts(problem, algorithm, solutions);
} }
} }
} }
public void add(PrioritizedVRAListener l){ public void add(PrioritizedVRAListener l) {
algorithmListeners.add(l); algorithmListeners.add(l);
} }
public void addAll(Collection<PrioritizedVRAListener> algorithmListeners) { public void addAll(Collection<PrioritizedVRAListener> algorithmListeners) {
for(PrioritizedVRAListener l : algorithmListeners){ for (PrioritizedVRAListener l : algorithmListeners) {
this.algorithmListeners.add(l); this.algorithmListeners.add(l);
} }
} }
public void selectedStrategy(SearchStrategy.DiscoveredSolution discoveredSolution, VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions) { public void selectedStrategy(SearchStrategy.DiscoveredSolution discoveredSolution, VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions) {
for(PrioritizedVRAListener l : algorithmListeners){ for (PrioritizedVRAListener l : algorithmListeners) {
if(l.getListener() instanceof StrategySelectedListener){ if (l.getListener() instanceof StrategySelectedListener) {
((StrategySelectedListener)l.getListener()).informSelectedStrategy(discoveredSolution, problem, solutions); ((StrategySelectedListener) l.getListener()).informSelectedStrategy(discoveredSolution, problem, solutions);
} }
} }
} }

View file

@ -30,7 +30,7 @@ import java.util.HashSet;
import java.util.Set; import java.util.Set;
public class RuinAndRecreateModule implements SearchStrategyModule{ public class RuinAndRecreateModule implements SearchStrategyModule {
private InsertionStrategy insertion; private InsertionStrategy insertion;
@ -65,15 +65,15 @@ public class RuinAndRecreateModule implements SearchStrategyModule{
@Override @Override
public void addModuleListener(SearchStrategyModuleListener moduleListener) { public void addModuleListener(SearchStrategyModuleListener moduleListener) {
if(moduleListener instanceof InsertionListener){ if (moduleListener instanceof InsertionListener) {
InsertionListener iListener = (InsertionListener) moduleListener; InsertionListener iListener = (InsertionListener) moduleListener;
if(!insertion.getListeners().contains(iListener)){ if (!insertion.getListeners().contains(iListener)) {
insertion.addListener(iListener); insertion.addListener(iListener);
} }
} }
if(moduleListener instanceof RuinListener){ if (moduleListener instanceof RuinListener) {
RuinListener rListener = (RuinListener) moduleListener; RuinListener rListener = (RuinListener) moduleListener;
if(!ruin.getListeners().contains(rListener)){ if (!ruin.getListeners().contains(rListener)) {
ruin.addListener(rListener); ruin.addListener(rListener);
} }
} }

View file

@ -33,7 +33,7 @@ import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Random; import java.util.Random;
public abstract class AbstractInsertionStrategy implements InsertionStrategy{ public abstract class AbstractInsertionStrategy implements InsertionStrategy {
protected class Insertion { protected class Insertion {
@ -84,9 +84,9 @@ public abstract class AbstractInsertionStrategy implements InsertionStrategy{
} }
@Override @Override
public Collection<Job> insertJobs(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs){ public Collection<Job> insertJobs(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs) {
insertionsListeners.informInsertionStarts(vehicleRoutes, unassignedJobs); insertionsListeners.informInsertionStarts(vehicleRoutes, unassignedJobs);
Collection<Job> badJobs = insertUnassignedJobs(vehicleRoutes,unassignedJobs); Collection<Job> badJobs = insertUnassignedJobs(vehicleRoutes, unassignedJobs);
insertionsListeners.informInsertionEndsListeners(vehicleRoutes); insertionsListeners.informInsertionEndsListeners(vehicleRoutes);
return badJobs; return badJobs;
} }
@ -109,13 +109,13 @@ 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());
} }
for(Event e : iData.getEvents()){ for (Event e : iData.getEvents()) {
eventListeners.inform(e); eventListeners.inform(e);
} }
insertionsListeners.informJobInserted(unassignedJob, inRoute, iData.getInsertionCost(), iData.getAdditionalTime()); insertionsListeners.informJobInserted(unassignedJob, inRoute, iData.getInsertionCost(), iData.getAdditionalTime());

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,34 +36,33 @@ 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;
} }
public double getCosts(JobInsertionContext insertionContext){ public double getCosts(JobInsertionContext insertionContext) {
double delta_access = 0.0; double delta_access = 0.0;
double delta_egress = 0.0; double delta_egress = 0.0;
VehicleRoute currentRoute = insertionContext.getRoute(); VehicleRoute currentRoute = insertionContext.getRoute();
Vehicle newVehicle = insertionContext.getNewVehicle(); Vehicle newVehicle = insertionContext.getNewVehicle();
Driver newDriver = insertionContext.getNewDriver(); Driver newDriver = insertionContext.getNewDriver();
double newVehicleDepartureTime = insertionContext.getNewDepTime(); double newVehicleDepartureTime = insertionContext.getNewDepTime();
if(!currentRoute.isEmpty()){ if (!currentRoute.isEmpty()) {
double accessTransportCostNew = routingCosts.getTransportCost(newVehicle.getStartLocation(), currentRoute.getActivities().get(0).getLocation(), newVehicleDepartureTime, newDriver, newVehicle); double accessTransportCostNew = routingCosts.getTransportCost(newVehicle.getStartLocation(), currentRoute.getActivities().get(0).getLocation(), newVehicleDepartureTime, newDriver, newVehicle);
double accessTransportCostOld = routingCosts.getTransportCost(currentRoute.getStart().getLocation(), currentRoute.getActivities().get(0).getLocation(), currentRoute.getDepartureTime(), currentRoute.getDriver(), currentRoute.getVehicle()); double accessTransportCostOld = routingCosts.getTransportCost(currentRoute.getStart().getLocation(), currentRoute.getActivities().get(0).getLocation(), currentRoute.getDepartureTime(), currentRoute.getDriver(), currentRoute.getVehicle());
delta_access = accessTransportCostNew - accessTransportCostOld; delta_access = accessTransportCostNew - accessTransportCostOld;
if(newVehicle.isReturnToDepot()){ if (newVehicle.isReturnToDepot()) {
TourActivity lastActivityBeforeEndOfRoute = currentRoute.getActivities().get(currentRoute.getActivities().size()-1); TourActivity lastActivityBeforeEndOfRoute = currentRoute.getActivities().get(currentRoute.getActivities().size() - 1);
double lastActivityEndTimeWithOldVehicleAndDepartureTime = lastActivityBeforeEndOfRoute.getEndTime(); double lastActivityEndTimeWithOldVehicleAndDepartureTime = lastActivityBeforeEndOfRoute.getEndTime();
double lastActivityEndTimeEstimationWithNewVehicleAndNewDepartureTime = Math.max(0.0, lastActivityEndTimeWithOldVehicleAndDepartureTime + (newVehicleDepartureTime - currentRoute.getDepartureTime())); double lastActivityEndTimeEstimationWithNewVehicleAndNewDepartureTime = Math.max(0.0, lastActivityEndTimeWithOldVehicleAndDepartureTime + (newVehicleDepartureTime - currentRoute.getDepartureTime()));
double egressTransportCostNew = routingCosts.getTransportCost(lastActivityBeforeEndOfRoute.getLocation(), newVehicle.getEndLocation() , lastActivityEndTimeEstimationWithNewVehicleAndNewDepartureTime, newDriver, newVehicle); double egressTransportCostNew = routingCosts.getTransportCost(lastActivityBeforeEndOfRoute.getLocation(), newVehicle.getEndLocation(), lastActivityEndTimeEstimationWithNewVehicleAndNewDepartureTime, newDriver, newVehicle);
double egressTransportCostOld = routingCosts.getTransportCost(lastActivityBeforeEndOfRoute.getLocation(), currentRoute.getEnd().getLocation(), lastActivityEndTimeWithOldVehicleAndDepartureTime, currentRoute.getDriver(), currentRoute.getVehicle()); double egressTransportCostOld = routingCosts.getTransportCost(lastActivityBeforeEndOfRoute.getLocation(), currentRoute.getEnd().getLocation(), lastActivityEndTimeWithOldVehicleAndDepartureTime, currentRoute.getDriver(), currentRoute.getVehicle());
delta_egress = egressTransportCostNew - egressTransportCostOld; delta_egress = egressTransportCostNew - egressTransportCostOld;

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,15 +40,14 @@ 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
* @param vehicle vehicle running the path * @param vehicle vehicle running the path
* @return cost of path * @return cost of path
*/ */
public double costOfPath(final List<TourActivity> path, final double depTime, final Driver driver, final Vehicle vehicle){ public double costOfPath(final List<TourActivity> path, final double depTime, final Driver driver, final Vehicle vehicle) {
if(path.isEmpty()){ if (path.isEmpty()) {
return 0.0; return 0.0;
} }
double cost = 0.0; double cost = 0.0;
@ -58,10 +56,10 @@ final class AuxilliaryCostCalculator {
double startCost = 0.0; double startCost = 0.0;
cost += startCost; cost += startCost;
double departureTimePrevAct = depTime; double departureTimePrevAct = depTime;
while(actIter.hasNext()){ while (actIter.hasNext()) {
TourActivity act = actIter.next(); TourActivity act = actIter.next();
if(act instanceof End){ if (act instanceof End) {
if(!vehicle.isReturnToDepot()){ if (!vehicle.isReturnToDepot()) {
return cost; return cost;
} }
} }

View file

@ -30,15 +30,12 @@ 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 {
private static Logger logger = LogManager.getLogger(BestInsertion.class); private static Logger logger = LogManager.getLogger(BestInsertion.class);
@ -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
@ -69,28 +66,28 @@ public final class BestInsertion extends AbstractInsertionStrategy{
List<Job> badJobs = new ArrayList<Job>(unassignedJobs.size()); List<Job> badJobs = new ArrayList<Job>(unassignedJobs.size());
List<Job> unassignedJobList = new ArrayList<Job>(unassignedJobs); List<Job> unassignedJobList = new ArrayList<Job>(unassignedJobs);
Collections.shuffle(unassignedJobList, random); Collections.shuffle(unassignedJobList, random);
for(Job unassignedJob : unassignedJobList){ for (Job unassignedJob : unassignedJobList) {
Insertion bestInsertion = null; Insertion bestInsertion = null;
double bestInsertionCost = Double.MAX_VALUE; double bestInsertionCost = Double.MAX_VALUE;
for(VehicleRoute vehicleRoute : vehicleRoutes){ for (VehicleRoute vehicleRoute : vehicleRoutes) {
InsertionData iData = bestInsertionCostCalculator.getInsertionData(vehicleRoute, unassignedJob, NO_NEW_VEHICLE_YET, NO_NEW_DEPARTURE_TIME_YET, NO_NEW_DRIVER_YET, bestInsertionCost); InsertionData iData = bestInsertionCostCalculator.getInsertionData(vehicleRoute, unassignedJob, NO_NEW_VEHICLE_YET, NO_NEW_DEPARTURE_TIME_YET, NO_NEW_DRIVER_YET, bestInsertionCost);
if(iData instanceof NoInsertionFound) { if (iData instanceof NoInsertionFound) {
continue; continue;
} }
if(iData.getInsertionCost() < bestInsertionCost + noiseMaker.makeNoise()){ if (iData.getInsertionCost() < bestInsertionCost + noiseMaker.makeNoise()) {
bestInsertion = new Insertion(vehicleRoute,iData); bestInsertion = new Insertion(vehicleRoute, iData);
bestInsertionCost = iData.getInsertionCost(); bestInsertionCost = iData.getInsertionCost();
} }
} }
VehicleRoute newRoute = VehicleRoute.emptyRoute(); VehicleRoute newRoute = VehicleRoute.emptyRoute();
InsertionData newIData = bestInsertionCostCalculator.getInsertionData(newRoute, unassignedJob, NO_NEW_VEHICLE_YET, NO_NEW_DEPARTURE_TIME_YET, NO_NEW_DRIVER_YET, bestInsertionCost); InsertionData newIData = bestInsertionCostCalculator.getInsertionData(newRoute, unassignedJob, NO_NEW_VEHICLE_YET, NO_NEW_DEPARTURE_TIME_YET, NO_NEW_DRIVER_YET, bestInsertionCost);
if(!(newIData instanceof NoInsertionFound)){ if (!(newIData instanceof NoInsertionFound)) {
if(newIData.getInsertionCost() < bestInsertionCost + noiseMaker.makeNoise()){ if (newIData.getInsertionCost() < bestInsertionCost + noiseMaker.makeNoise()) {
bestInsertion = new Insertion(newRoute,newIData); bestInsertion = new Insertion(newRoute, newIData);
vehicleRoutes.add(newRoute); vehicleRoutes.add(newRoute);
} }
} }
if(bestInsertion == null) badJobs.add(unassignedJob); if (bestInsertion == null) badJobs.add(unassignedJob);
else insertJob(unassignedJob, bestInsertion.getInsertionData(), bestInsertion.getRoute()); else insertJob(unassignedJob, bestInsertion.getInsertionData(), bestInsertion.getRoute());
} }
return badJobs; return badJobs;

View file

@ -58,11 +58,11 @@ public class BestInsertionBuilder {
private int nNeighbors; private int nNeighbors;
private boolean timeScheduling=false; private boolean timeScheduling = false;
private boolean allowVehicleSwitch=true; private boolean allowVehicleSwitch = true;
private boolean addDefaultCostCalc=true; private boolean addDefaultCostCalc = true;
public BestInsertionBuilder(VehicleRoutingProblem vrp, VehicleFleetManager vehicleFleetManager, StateManager stateManager, ConstraintManager constraintManager) { public BestInsertionBuilder(VehicleRoutingProblem vrp, VehicleFleetManager vehicleFleetManager, StateManager stateManager, ConstraintManager constraintManager) {
super(); super();
@ -72,25 +72,31 @@ public class BestInsertionBuilder {
this.fleetManager = vehicleFleetManager; this.fleetManager = vehicleFleetManager;
} }
public BestInsertionBuilder setRouteLevel(int forwardLooking, int memory){ public BestInsertionBuilder setRouteLevel(int forwardLooking, int memory) {
local = false; local = false;
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;
this.forwaredLooking = forwardLooking; this.forwaredLooking = forwardLooking;
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
@ -99,24 +105,26 @@ public class BestInsertionBuilder {
* @param addDefaultMarginalCostCalculation * @param addDefaultMarginalCostCalculation
* @return * @return
*/ */
public BestInsertionBuilder setLocalLevel(boolean addDefaultMarginalCostCalculation){ public BestInsertionBuilder setLocalLevel(boolean addDefaultMarginalCostCalculation) {
local = true; local = true;
addDefaultCostCalc = addDefaultMarginalCostCalculation; addDefaultCostCalc = addDefaultMarginalCostCalculation;
return this; return this;
} }
public BestInsertionBuilder considerFixedCosts(double weightOfFixedCosts){ public BestInsertionBuilder considerFixedCosts(double weightOfFixedCosts) {
this.weightOfFixedCosts = weightOfFixedCosts; this.weightOfFixedCosts = weightOfFixedCosts;
this.considerFixedCosts = true; this.considerFixedCosts = true;
return this; return this;
} }
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;
this.nuOfThreads = nuOfThreads; this.nuOfThreads = nuOfThreads;
return this; return this;
@ -127,10 +135,9 @@ public class BestInsertionBuilder {
List<InsertionListener> iListeners = new ArrayList<InsertionListener>(); List<InsertionListener> iListeners = new ArrayList<InsertionListener>();
List<PrioritizedVRAListener> algorithmListeners = new ArrayList<PrioritizedVRAListener>(); List<PrioritizedVRAListener> algorithmListeners = new ArrayList<PrioritizedVRAListener>();
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);
@ -138,35 +145,34 @@ public class BestInsertionBuilder {
calcBuilder.setVehicleRoutingProblem(vrp); calcBuilder.setVehicleRoutingProblem(vrp);
calcBuilder.setVehicleFleetManager(fleetManager); calcBuilder.setVehicleFleetManager(fleetManager);
calcBuilder.setActivityInsertionCostsCalculator(actInsertionCostsCalculator); calcBuilder.setActivityInsertionCostsCalculator(actInsertionCostsCalculator);
if(considerFixedCosts) { if (considerFixedCosts) {
calcBuilder.considerFixedCosts(weightOfFixedCosts); calcBuilder.considerFixedCosts(weightOfFixedCosts);
} }
if(timeScheduling){ if (timeScheduling) {
calcBuilder.experimentalTimeScheduler(timeSlice, nNeighbors); calcBuilder.experimentalTimeScheduler(timeSlice, nNeighbors);
} }
calcBuilder.setAllowVehicleSwitch(allowVehicleSwitch); calcBuilder.setAllowVehicleSwitch(allowVehicleSwitch);
JobInsertionCostsCalculator jobInsertions = calcBuilder.build(); JobInsertionCostsCalculator jobInsertions = calcBuilder.build();
InsertionStrategy bestInsertion; InsertionStrategy bestInsertion;
if(executor == null){ if (executor == null) {
bestInsertion = new BestInsertion(jobInsertions,vrp); bestInsertion = new BestInsertion(jobInsertions, vrp);
} else {
bestInsertion = new BestInsertionConcurrent(jobInsertions, executor, nuOfThreads, vrp);
} }
else{ for (InsertionListener l : iListeners) bestInsertion.addListener(l);
bestInsertion = new BestInsertionConcurrent(jobInsertions,executor,nuOfThreads,vrp);
}
for(InsertionListener l : iListeners) bestInsertion.addListener(l);
return bestInsertion; return bestInsertion;
} }
/** /**
* @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) {
this.timeSlice=timeSlice; this.timeSlice = timeSlice;
this.nNeighbors=nNeighbors; this.nNeighbors = nNeighbors;
timeScheduling=true; timeScheduling = true;
} }
public void setAllowVehicleSwitch(boolean allowVehicleSwitch) { public void setAllowVehicleSwitch(boolean allowVehicleSwitch) {
@ -174,6 +180,4 @@ public class BestInsertionBuilder {
} }
} }

View file

@ -30,15 +30,11 @@ 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 {
static class Batch { static class Batch {
List<VehicleRoute> routes = new ArrayList<VehicleRoute>(); List<VehicleRoute> routes = new ArrayList<VehicleRoute>();
@ -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
@ -107,16 +103,16 @@ public final class BestInsertionConcurrent extends AbstractInsertionStrategy{
List<Job> badJobs = new ArrayList<Job>(unassignedJobs.size()); List<Job> badJobs = new ArrayList<Job>(unassignedJobs.size());
List<Job> unassignedJobList = new ArrayList<Job>(unassignedJobs); List<Job> unassignedJobList = new ArrayList<Job>(unassignedJobs);
Collections.shuffle(unassignedJobList, random); Collections.shuffle(unassignedJobList, random);
List<Batch> batches = distributeRoutes(vehicleRoutes,nuOfBatches); List<Batch> batches = distributeRoutes(vehicleRoutes, nuOfBatches);
for(final Job unassignedJob : unassignedJobList){ for (final Job unassignedJob : unassignedJobList) {
Insertion bestInsertion = null; Insertion bestInsertion = null;
double bestInsertionCost = Double.MAX_VALUE; double bestInsertionCost = Double.MAX_VALUE;
for(final Batch batch : batches){ for (final Batch batch : batches) {
completionService.submit(new Callable<Insertion>() { completionService.submit(new Callable<Insertion>() {
@Override @Override
public Insertion call() throws Exception { public Insertion call() throws Exception {
return getBestInsertion(batch,unassignedJob); return getBestInsertion(batch, unassignedJob);
} }
}); });
@ -131,22 +127,21 @@ public final class BestInsertionConcurrent extends AbstractInsertionStrategy{
bestInsertionCost = insertion.getInsertionData().getInsertionCost(); bestInsertionCost = insertion.getInsertionData().getInsertionCost();
} }
} }
} 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();
InsertionData newIData = bestInsertionCostCalculator.getInsertionData(newRoute, unassignedJob, NO_NEW_VEHICLE_YET, NO_NEW_DEPARTURE_TIME_YET, NO_NEW_DRIVER_YET, bestInsertionCost); InsertionData newIData = bestInsertionCostCalculator.getInsertionData(newRoute, unassignedJob, NO_NEW_VEHICLE_YET, NO_NEW_DEPARTURE_TIME_YET, NO_NEW_DRIVER_YET, bestInsertionCost);
if(newIData.getInsertionCost() < bestInsertionCost){ if (newIData.getInsertionCost() < bestInsertionCost) {
bestInsertion = new Insertion(newRoute,newIData); bestInsertion = new Insertion(newRoute, newIData);
vehicleRoutes.add(newRoute); vehicleRoutes.add(newRoute);
batches.get(random.nextInt(batches.size())).routes.add(newRoute); batches.get(random.nextInt(batches.size())).routes.add(newRoute);
} }
if(bestInsertion == null) badJobs.add(unassignedJob); if (bestInsertion == null) badJobs.add(unassignedJob);
else insertJob(unassignedJob, bestInsertion.getInsertionData(), bestInsertion.getRoute()); else insertJob(unassignedJob, bestInsertion.getInsertionData(), bestInsertion.getRoute());
} }
return badJobs; return badJobs;
@ -155,13 +150,13 @@ public final class BestInsertionConcurrent extends AbstractInsertionStrategy{
private Insertion getBestInsertion(Batch batch, Job unassignedJob) { private Insertion getBestInsertion(Batch batch, Job unassignedJob) {
Insertion bestInsertion = null; Insertion bestInsertion = null;
double bestInsertionCost = Double.MAX_VALUE; double bestInsertionCost = Double.MAX_VALUE;
for(VehicleRoute vehicleRoute : batch.routes){ for (VehicleRoute vehicleRoute : batch.routes) {
InsertionData iData = bestInsertionCostCalculator.getInsertionData(vehicleRoute, unassignedJob, NO_NEW_VEHICLE_YET, NO_NEW_DEPARTURE_TIME_YET, NO_NEW_DRIVER_YET, bestInsertionCost); InsertionData iData = bestInsertionCostCalculator.getInsertionData(vehicleRoute, unassignedJob, NO_NEW_VEHICLE_YET, NO_NEW_DEPARTURE_TIME_YET, NO_NEW_DRIVER_YET, bestInsertionCost);
if(iData instanceof NoInsertionFound) { if (iData instanceof NoInsertionFound) {
continue; continue;
} }
if(iData.getInsertionCost() < bestInsertionCost){ if (iData.getInsertionCost() < bestInsertionCost) {
bestInsertion = new Insertion(vehicleRoute,iData); bestInsertion = new Insertion(vehicleRoute, iData);
bestInsertionCost = iData.getInsertionCost(); bestInsertionCost = iData.getInsertionCost();
} }
} }
@ -170,26 +165,25 @@ public final class BestInsertionConcurrent extends AbstractInsertionStrategy{
private List<Batch> distributeRoutes(Collection<VehicleRoute> vehicleRoutes, int nuOfBatches) { private List<Batch> distributeRoutes(Collection<VehicleRoute> vehicleRoutes, int nuOfBatches) {
List<Batch> batches = new ArrayList<Batch>(); List<Batch> batches = new ArrayList<Batch>();
for(int i=0;i<nuOfBatches;i++) batches.add(new Batch()); for (int i = 0; i < nuOfBatches; i++) batches.add(new Batch());
/* /*
* if route.size < nuOfBatches add as much routes as empty batches are available * if route.size < nuOfBatches add as much routes as empty batches are available
* else add one empty route anyway * else add one empty route anyway
*/ */
if(vehicleRoutes.size()<nuOfBatches){ if (vehicleRoutes.size() < nuOfBatches) {
int nOfNewRoutes = nuOfBatches-vehicleRoutes.size(); int nOfNewRoutes = nuOfBatches - vehicleRoutes.size();
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());
} }
/* /*
* distribute routes to batches equally * distribute routes to batches equally
*/ */
int count = 0; int count = 0;
for(VehicleRoute route : vehicleRoutes){ for (VehicleRoute route : vehicleRoutes) {
if(count == nuOfBatches) count=0; if (count == nuOfBatches) count = 0;
batches.get(count).routes.add(route); batches.get(count).routes.add(route);
count++; count++;
} }

View file

@ -15,22 +15,24 @@ import java.util.List;
import java.util.Random; import java.util.Random;
class CalculatesServiceInsertionWithTimeScheduling implements JobInsertionCostsCalculator{ class CalculatesServiceInsertionWithTimeScheduling implements JobInsertionCostsCalculator {
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>();
if(vehicleRoutes.isEmpty()){ if (vehicleRoutes.isEmpty()) {
// System.out.println("hmm"); // System.out.println("hmm");
} }
for(VehicleRoute route : vehicleRoutes){ for (VehicleRoute route : vehicleRoutes) {
// if(route.getDepartureTime() == 21600.){ // if(route.getDepartureTime() == 21600.){
// System.out.println("hu"); // System.out.println("hu");
// } // }
@ -60,18 +62,17 @@ class CalculatesServiceInsertionWithTimeScheduling implements JobInsertionCostsC
@Override @Override
public String toString() { public String toString() {
return "[name="+this.getClass().toString()+"]"; return "[name=" + this.getClass().toString() + "]";
} }
@Override @Override
public InsertionData getInsertionData(VehicleRoute currentRoute, Job jobToInsert, Vehicle newVehicle, double newVehicleDepartureTime, Driver newDriver, double bestKnownScore) { public InsertionData getInsertionData(VehicleRoute currentRoute, Job jobToInsert, Vehicle newVehicle, double newVehicleDepartureTime, Driver newDriver, double bestKnownScore) {
double departureTime = newVehicleDepartureTime; double departureTime = newVehicleDepartureTime;
if(currentRoute.isEmpty()){ if (currentRoute.isEmpty()) {
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();
} }
@ -82,7 +83,7 @@ class CalculatesServiceInsertionWithTimeScheduling implements JobInsertionCostsC
return insertionData; return insertionData;
} }
public void setDepartureTimeKnowledge(List<Double> departureTimes){ public void setDepartureTimeKnowledge(List<Double> departureTimes) {
departureTimeKnowledge=departureTimes; departureTimeKnowledge = departureTimes;
} }
} }

View file

@ -27,7 +27,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
class CalculatesServiceInsertionWithTimeSchedulingInSlices implements JobInsertionCostsCalculator{ class CalculatesServiceInsertionWithTimeSchedulingInSlices implements JobInsertionCostsCalculator {
private static Logger log = LogManager.getLogger(CalculatesServiceInsertionWithTimeSchedulingInSlices.class); private static Logger log = LogManager.getLogger(CalculatesServiceInsertionWithTimeSchedulingInSlices.class);
@ -48,38 +48,37 @@ class CalculatesServiceInsertionWithTimeSchedulingInSlices implements JobInserti
@Override @Override
public String toString() { public String toString() {
return "[name="+this.getClass().toString()+"][timeSlice="+timeSlice+"][#timeSlice="+nOfDepartureTimes+"]"; return "[name=" + this.getClass().toString() + "][timeSlice=" + timeSlice + "][#timeSlice=" + nOfDepartureTimes + "]";
} }
@Override @Override
public InsertionData getInsertionData(VehicleRoute currentRoute, Job jobToInsert, Vehicle newVehicle, double newVehicleDepartureTime, Driver newDriver, double bestKnownScore) { public InsertionData getInsertionData(VehicleRoute currentRoute, Job jobToInsert, Vehicle newVehicle, double newVehicleDepartureTime, Driver newDriver, double bestKnownScore) {
List<Double> vehicleDepartureTimes = new ArrayList<Double>(); List<Double> vehicleDepartureTimes = new ArrayList<Double>();
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();
// double latestEnd = newVehicle.getLatestArrival(); // double latestEnd = newVehicle.getLatestArrival();
for(int i=0;i<nOfDepartureTimes;i++){ for (int i = 0; i < nOfDepartureTimes; i++) {
double neighborStartTime_earlier = currentStart - (i+1)*timeSlice; double neighborStartTime_earlier = currentStart - (i + 1) * timeSlice;
// if(neighborStartTime_earlier > earliestDeparture) { // if(neighborStartTime_earlier > earliestDeparture) {
vehicleDepartureTimes.add(neighborStartTime_earlier); vehicleDepartureTimes.add(neighborStartTime_earlier);
// } // }
double neighborStartTime_later = currentStart + (i+1)*timeSlice; double neighborStartTime_later = currentStart + (i + 1) * timeSlice;
// if(neighborStartTime_later < latestEnd) { // if(neighborStartTime_later < latestEnd) {
vehicleDepartureTimes.add(neighborStartTime_later); vehicleDepartureTimes.add(neighborStartTime_later);
// } // }
} }
InsertionData bestIData = null; InsertionData bestIData = null;
for(Double departureTime : vehicleDepartureTimes){ for (Double departureTime : vehicleDepartureTimes) {
InsertionData iData = jic.getInsertionData(currentRoute, jobToInsert, newVehicle, departureTime, newDriver, bestKnownScore); InsertionData iData = jic.getInsertionData(currentRoute, jobToInsert, newVehicle, departureTime, newDriver, bestKnownScore);
if(bestIData == null) bestIData = iData; if (bestIData == null) bestIData = iData;
else if(iData.getInsertionCost() < bestIData.getInsertionCost()){ else if (iData.getInsertionCost() < bestIData.getInsertionCost()) {
iData.setVehicleDepartureTime(departureTime); iData.setVehicleDepartureTime(departureTime);
bestIData = iData; bestIData = iData;
} }

View file

@ -26,7 +26,7 @@ import jsprit.core.problem.solution.route.VehicleRoute;
import java.util.Collection; import java.util.Collection;
final class ConfigureFixCostCalculator implements InsertionStartsListener, JobInsertedListener{ final class ConfigureFixCostCalculator implements InsertionStartsListener, JobInsertedListener {
VehicleRoutingProblem vrp; VehicleRoutingProblem vrp;
@ -48,7 +48,7 @@ final class ConfigureFixCostCalculator implements InsertionStartsListener, JobIn
@Override @Override
public void informInsertionStarts(Collection<VehicleRoute> routes, Collection<Job> unassignedJobs) { public void informInsertionStarts(Collection<VehicleRoute> routes, Collection<Job> unassignedJobs) {
this.nuOfJobsToRecreate = unassignedJobs.size(); this.nuOfJobsToRecreate = unassignedJobs.size();
double completenessRatio = (1-((double)nuOfJobsToRecreate/(double)vrp.getJobs().values().size())); double completenessRatio = (1 - ((double) nuOfJobsToRecreate / (double) vrp.getJobs().values().size()));
calcConsideringFix.setSolutionCompletenessRatio(completenessRatio); calcConsideringFix.setSolutionCompletenessRatio(completenessRatio);
// log.debug("initialise completenessRatio to " + completenessRatio); // log.debug("initialise completenessRatio to " + completenessRatio);
} }
@ -56,7 +56,7 @@ final class ConfigureFixCostCalculator implements InsertionStartsListener, JobIn
@Override @Override
public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) { public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) {
nuOfJobsToRecreate--; nuOfJobsToRecreate--;
double completenessRatio = (1-((double)nuOfJobsToRecreate/(double)vrp.getJobs().values().size())); double completenessRatio = (1 - ((double) nuOfJobsToRecreate / (double) vrp.getJobs().values().size()));
calcConsideringFix.setSolutionCompletenessRatio(completenessRatio); calcConsideringFix.setSolutionCompletenessRatio(completenessRatio);
// log.debug("set completenessRatio to " + completenessRatio); // log.debug("set completenessRatio to " + completenessRatio);
} }

View file

@ -27,14 +27,14 @@ public class ConfigureLocalActivityInsertionCalculator implements InsertionStart
@Override @Override
public void informInsertionStarts(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs) { public void informInsertionStarts(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs) {
this.nuOfJobsToRecreate = unassignedJobs.size(); this.nuOfJobsToRecreate = unassignedJobs.size();
double completenessRatio = (1-((double)nuOfJobsToRecreate/(double)vrp.getJobs().values().size())); double completenessRatio = (1 - ((double) nuOfJobsToRecreate / (double) vrp.getJobs().values().size()));
localActivityInsertionCostsCalculator.setSolutionCompletenessRatio(Math.max(0.5,completenessRatio)); localActivityInsertionCostsCalculator.setSolutionCompletenessRatio(Math.max(0.5, completenessRatio));
} }
@Override @Override
public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) { public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) {
nuOfJobsToRecreate--; nuOfJobsToRecreate--;
double completenessRatio = (1-((double)nuOfJobsToRecreate/(double)vrp.getJobs().values().size())); double completenessRatio = (1 - ((double) nuOfJobsToRecreate / (double) vrp.getJobs().values().size()));
localActivityInsertionCostsCalculator.setSolutionCompletenessRatio(Math.max(0.5,completenessRatio)); localActivityInsertionCostsCalculator.setSolutionCompletenessRatio(Math.max(0.5, completenessRatio));
} }
} }

View file

@ -28,7 +28,7 @@ import jsprit.core.problem.solution.route.state.RouteAndActivityStateGetter;
import java.util.Collection; import java.util.Collection;
public class DellAmicoFixCostCalculator implements SoftRouteConstraint, InsertionStartsListener, JobInsertedListener{ public class DellAmicoFixCostCalculator implements SoftRouteConstraint, InsertionStartsListener, JobInsertedListener {
private int nuOfJobsToRecreate; private int nuOfJobsToRecreate;
@ -38,7 +38,7 @@ public class DellAmicoFixCostCalculator implements SoftRouteConstraint, Insertio
public DellAmicoFixCostCalculator(final int nuOfJobs, final RouteAndActivityStateGetter stateGetter) { public DellAmicoFixCostCalculator(final int nuOfJobs, final RouteAndActivityStateGetter stateGetter) {
super(); super();
this.nuOfJobs=nuOfJobs; this.nuOfJobs = nuOfJobs;
calculator = new JobInsertionConsideringFixCostsCalculator(null, stateGetter); calculator = new JobInsertionConsideringFixCostsCalculator(null, stateGetter);
} }
@ -50,14 +50,14 @@ public class DellAmicoFixCostCalculator implements SoftRouteConstraint, Insertio
@Override @Override
public void informInsertionStarts(Collection<VehicleRoute> routes, Collection<Job> unassignedJobs) { public void informInsertionStarts(Collection<VehicleRoute> routes, Collection<Job> unassignedJobs) {
this.nuOfJobsToRecreate = unassignedJobs.size(); this.nuOfJobsToRecreate = unassignedJobs.size();
double completenessRatio = (1-((double)nuOfJobsToRecreate/(double)nuOfJobs)); double completenessRatio = (1 - ((double) nuOfJobsToRecreate / (double) nuOfJobs));
calculator.setSolutionCompletenessRatio(completenessRatio); calculator.setSolutionCompletenessRatio(completenessRatio);
} }
@Override @Override
public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) { public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) {
nuOfJobsToRecreate--; nuOfJobsToRecreate--;
double completenessRatio = (1-((double)nuOfJobsToRecreate/(double)nuOfJobs)); double completenessRatio = (1 - ((double) nuOfJobsToRecreate / (double) nuOfJobs));
calculator.setSolutionCompletenessRatio(completenessRatio); calculator.setSolutionCompletenessRatio(completenessRatio);
System.out.println(completenessRatio); System.out.println(completenessRatio);
} }

View file

@ -16,8 +16,8 @@ class EventListeners {
listeners.add(new InsertBreakListener()); listeners.add(new InsertBreakListener());
} }
public void inform(Event event){ public void inform(Event event) {
for(EventListener l : listeners){ for (EventListener l : listeners) {
l.inform(event); l.inform(event);
} }
} }

View file

@ -7,14 +7,14 @@ class InsertActivityListener implements EventListener {
@Override @Override
public void inform(Event event) { public void inform(Event event) {
if(event instanceof InsertActivity){ if (event instanceof InsertActivity) {
InsertActivity insertActivity = (InsertActivity) event; InsertActivity insertActivity = (InsertActivity) event;
if(!insertActivity.getNewVehicle().isReturnToDepot()){ if (!insertActivity.getNewVehicle().isReturnToDepot()) {
if(insertActivity.getIndex()>=insertActivity.getVehicleRoute().getActivities().size()){ if (insertActivity.getIndex() >= insertActivity.getVehicleRoute().getActivities().size()) {
insertActivity.getVehicleRoute().getEnd().setLocation(insertActivity.getActivity().getLocation()); insertActivity.getVehicleRoute().getEnd().setLocation(insertActivity.getActivity().getLocation());
} }
} }
insertActivity.getVehicleRoute().getTourActivities().addActivity(insertActivity.getIndex(),((InsertActivity) event).getActivity()); insertActivity.getVehicleRoute().getTourActivities().addActivity(insertActivity.getIndex(), ((InsertActivity) event).getActivity());
} }
} }

View file

@ -38,10 +38,10 @@ class Inserter {
} }
class JobExceptionHandler implements JobInsertionHandler{ class JobExceptionHandler implements JobInsertionHandler {
@Override @Override
public void handleJobInsertion(Job job, InsertionData iData,VehicleRoute route) { public void handleJobInsertion(Job job, InsertionData iData, VehicleRoute route) {
throw new IllegalStateException("job insertion is not supported. Do not know job type."); throw new IllegalStateException("job insertion is not supported. Do not know job type.");
} }
@ -52,7 +52,7 @@ class Inserter {
} }
class ServiceInsertionHandler implements JobInsertionHandler{ class ServiceInsertionHandler implements JobInsertionHandler {
private TourActivityFactory activityFactory = new DefaultTourActivityFactory(); private TourActivityFactory activityFactory = new DefaultTourActivityFactory();
@ -66,24 +66,23 @@ class Inserter {
@Override @Override
public void handleJobInsertion(Job job, InsertionData iData, VehicleRoute route) { public void handleJobInsertion(Job job, InsertionData iData, VehicleRoute route) {
if(job instanceof Service){ if (job instanceof Service) {
route.setVehicleAndDepartureTime(iData.getSelectedVehicle(),iData.getVehicleDepartureTime()); route.setVehicleAndDepartureTime(iData.getSelectedVehicle(), iData.getVehicleDepartureTime());
if(!iData.getSelectedVehicle().isReturnToDepot()){ if (!iData.getSelectedVehicle().isReturnToDepot()) {
if(iData.getDeliveryInsertionIndex()>=route.getTourActivities().getActivities().size()){ if (iData.getDeliveryInsertionIndex() >= route.getTourActivities().getActivities().size()) {
setEndLocation(route,(Service)job); setEndLocation(route, (Service) job);
} }
} }
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) {
route.getEnd().setLocation(service.getLocation()); route.getEnd().setLocation(service.getLocation());
} }
public void setNextHandler(JobInsertionHandler jobInsertionHandler){ public void setNextHandler(JobInsertionHandler jobInsertionHandler) {
this.delegator = jobInsertionHandler; this.delegator = jobInsertionHandler;
} }
@ -103,27 +102,26 @@ class Inserter {
@Override @Override
public void handleJobInsertion(Job job, InsertionData iData, VehicleRoute route) { public void handleJobInsertion(Job job, InsertionData iData, VehicleRoute route) {
if(job instanceof Shipment){ if (job instanceof Shipment) {
List<AbstractActivity> acts = vehicleRoutingProblem.copyAndGetActivities(job); List<AbstractActivity> acts = vehicleRoutingProblem.copyAndGetActivities(job);
TourActivity pickupShipment = acts.get(0); TourActivity pickupShipment = acts.get(0);
TourActivity deliverShipment = acts.get(1); TourActivity deliverShipment = acts.get(1);
route.setVehicleAndDepartureTime(iData.getSelectedVehicle(),iData.getVehicleDepartureTime()); route.setVehicleAndDepartureTime(iData.getSelectedVehicle(), iData.getVehicleDepartureTime());
if(!iData.getSelectedVehicle().isReturnToDepot()){ if (!iData.getSelectedVehicle().isReturnToDepot()) {
if(iData.getDeliveryInsertionIndex()>=route.getActivities().size()){ if (iData.getDeliveryInsertionIndex() >= route.getActivities().size()) {
setEndLocation(route,(Shipment)job); setEndLocation(route, (Shipment) job);
} }
} }
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) {
route.getEnd().setLocation(shipment.getDeliveryLocation()); route.getEnd().setLocation(shipment.getDeliveryLocation());
} }
public void setNextHandler(JobInsertionHandler jobInsertionHandler){ public void setNextHandler(JobInsertionHandler jobInsertionHandler) {
this.delegator = jobInsertionHandler; this.delegator = jobInsertionHandler;
} }
@ -142,12 +140,13 @@ class Inserter {
jobInsertionHandler.setNextHandler(new ShipmentInsertionHandler(vehicleRoutingProblem)); jobInsertionHandler.setNextHandler(new ShipmentInsertionHandler(vehicleRoutingProblem));
} }
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))
if(job == null) throw new IllegalStateException("cannot insert null-job"); throw new IllegalStateException("insertionData null. cannot insert job.");
if(!(vehicleRoute.getVehicle().getId().equals(insertionData.getSelectedVehicle().getId()))){ if (job == null) throw new IllegalStateException("cannot insert null-job");
if (!(vehicleRoute.getVehicle().getId().equals(insertionData.getSelectedVehicle().getId()))) {
insertionListeners.informVehicleSwitched(vehicleRoute, vehicleRoute.getVehicle(), insertionData.getSelectedVehicle()); insertionListeners.informVehicleSwitched(vehicleRoute, vehicleRoute.getVehicle(), insertionData.getSelectedVehicle());
vehicleRoute.setVehicleAndDepartureTime(insertionData.getSelectedVehicle(), insertionData.getVehicleDepartureTime()); vehicleRoute.setVehicleAndDepartureTime(insertionData.getSelectedVehicle(), insertionData.getVehicleDepartureTime());
} }

View file

@ -62,11 +62,11 @@ public class InsertionBuilder {
private int nNeighbors; private int nNeighbors;
private boolean timeScheduling=false; private boolean timeScheduling = false;
private boolean allowVehicleSwitch=true; private boolean allowVehicleSwitch = true;
private boolean addDefaultCostCalc=true; private boolean addDefaultCostCalc = true;
private Strategy strategy = Strategy.BEST; private Strategy strategy = Strategy.BEST;
@ -78,19 +78,19 @@ public class InsertionBuilder {
this.fleetManager = vehicleFleetManager; this.fleetManager = vehicleFleetManager;
} }
public InsertionBuilder setInsertionStrategy(Strategy strategy){ public InsertionBuilder setInsertionStrategy(Strategy strategy) {
this.strategy = strategy; this.strategy = strategy;
return this; return this;
} }
public InsertionBuilder setRouteLevel(int forwardLooking, int memory){ public InsertionBuilder setRouteLevel(int forwardLooking, int memory) {
local = false; local = false;
this.forwaredLooking = forwardLooking; this.forwaredLooking = forwardLooking;
this.memory = memory; this.memory = memory;
return this; return this;
} }
public InsertionBuilder setRouteLevel(int forwardLooking, int memory, boolean addDefaultMarginalCostCalculation){ public InsertionBuilder setRouteLevel(int forwardLooking, int memory, boolean addDefaultMarginalCostCalculation) {
local = false; local = false;
this.forwaredLooking = forwardLooking; this.forwaredLooking = forwardLooking;
this.memory = memory; this.memory = memory;
@ -98,7 +98,7 @@ public class InsertionBuilder {
return this; return this;
} }
public InsertionBuilder setLocalLevel(){ public InsertionBuilder setLocalLevel() {
local = true; local = true;
return this; return this;
} }
@ -110,24 +110,24 @@ public class InsertionBuilder {
* @param addDefaultMarginalCostCalculation * @param addDefaultMarginalCostCalculation
* @return * @return
*/ */
public InsertionBuilder setLocalLevel(boolean addDefaultMarginalCostCalculation){ public InsertionBuilder setLocalLevel(boolean addDefaultMarginalCostCalculation) {
local = true; local = true;
addDefaultCostCalc = addDefaultMarginalCostCalculation; addDefaultCostCalc = addDefaultMarginalCostCalculation;
return this; return this;
} }
public InsertionBuilder considerFixedCosts(double weightOfFixedCosts){ public InsertionBuilder considerFixedCosts(double weightOfFixedCosts) {
this.weightOfFixedCosts = weightOfFixedCosts; this.weightOfFixedCosts = weightOfFixedCosts;
this.considerFixedCosts = true; this.considerFixedCosts = true;
return this; return this;
} }
public InsertionBuilder setActivityInsertionCostCalculator(ActivityInsertionCostsCalculator activityInsertionCostsCalculator){ public InsertionBuilder setActivityInsertionCostCalculator(ActivityInsertionCostsCalculator activityInsertionCostsCalculator) {
this.actInsertionCostsCalculator = activityInsertionCostsCalculator; this.actInsertionCostsCalculator = activityInsertionCostsCalculator;
return this; return this;
} }
public InsertionBuilder setConcurrentMode(ExecutorService executor, int nuOfThreads){ public InsertionBuilder setConcurrentMode(ExecutorService executor, int nuOfThreads) {
this.executor = executor; this.executor = executor;
this.nuOfThreads = nuOfThreads; this.nuOfThreads = nuOfThreads;
return this; return this;
@ -138,10 +138,9 @@ public class InsertionBuilder {
List<InsertionListener> iListeners = new ArrayList<InsertionListener>(); List<InsertionListener> iListeners = new ArrayList<InsertionListener>();
List<PrioritizedVRAListener> algorithmListeners = new ArrayList<PrioritizedVRAListener>(); List<PrioritizedVRAListener> algorithmListeners = new ArrayList<PrioritizedVRAListener>();
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,46 +148,43 @@ public class InsertionBuilder {
calcBuilder.setVehicleRoutingProblem(vrp); calcBuilder.setVehicleRoutingProblem(vrp);
calcBuilder.setVehicleFleetManager(fleetManager); calcBuilder.setVehicleFleetManager(fleetManager);
calcBuilder.setActivityInsertionCostsCalculator(actInsertionCostsCalculator); calcBuilder.setActivityInsertionCostsCalculator(actInsertionCostsCalculator);
if(considerFixedCosts) { if (considerFixedCosts) {
calcBuilder.considerFixedCosts(weightOfFixedCosts); calcBuilder.considerFixedCosts(weightOfFixedCosts);
} }
if(timeScheduling){ if (timeScheduling) {
calcBuilder.experimentalTimeScheduler(timeSlice, nNeighbors); calcBuilder.experimentalTimeScheduler(timeSlice, nNeighbors);
} }
calcBuilder.setAllowVehicleSwitch(allowVehicleSwitch); calcBuilder.setAllowVehicleSwitch(allowVehicleSwitch);
JobInsertionCostsCalculator costCalculator = calcBuilder.build(); JobInsertionCostsCalculator costCalculator = calcBuilder.build();
InsertionStrategy insertion; InsertionStrategy insertion;
if(strategy.equals(Strategy.BEST)) { if (strategy.equals(Strategy.BEST)) {
if (executor == null) { if (executor == null) {
insertion = new BestInsertion(costCalculator, vrp); insertion = new BestInsertion(costCalculator, vrp);
} 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 {
insertion = new RegretInsertionConcurrent(costCalculator, vrp, executor);
} }
else { } else throw new IllegalStateException("you should never get here");
insertion = new RegretInsertionConcurrent(costCalculator,vrp,executor); for (InsertionListener l : iListeners) insertion.addListener(l);
}
}
else throw new IllegalStateException("you should never get here");
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) {
this.timeSlice=timeSlice; this.timeSlice = timeSlice;
this.nNeighbors=nNeighbors; this.nNeighbors = nNeighbors;
timeScheduling=true; timeScheduling = true;
} }
public InsertionBuilder setAllowVehicleSwitch(boolean allowVehicleSwitch) { public InsertionBuilder setAllowVehicleSwitch(boolean allowVehicleSwitch) {
@ -197,6 +193,4 @@ public class InsertionBuilder {
} }
} }

View file

@ -27,11 +27,10 @@ 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 {
public static class NoInsertionFound extends InsertionData{ public static class NoInsertionFound extends InsertionData {
public NoInsertionFound() { public NoInsertionFound() {
super(Double.MAX_VALUE, NO_INDEX, NO_INDEX, null, null); super(Double.MAX_VALUE, NO_INDEX, NO_INDEX, null, null);
@ -49,7 +48,7 @@ public class InsertionData {
* *
* @return * @return
*/ */
public static InsertionData createEmptyInsertionData(){ public static InsertionData createEmptyInsertionData() {
return noInsertion; return noInsertion;
} }
@ -71,7 +70,7 @@ public class InsertionData {
private List<Event> events = new ArrayList<Event>(); private List<Event> events = new ArrayList<Event>();
List<Event> getEvents(){ List<Event> getEvents() {
return events; return events;
} }
@ -89,7 +88,7 @@ public class InsertionData {
this.additionalTime = additionalTime; this.additionalTime = additionalTime;
} }
public InsertionData(double insertionCost, int pickupInsertionIndex, int deliveryInsertionIndex, Vehicle vehicle, Driver driver){ public InsertionData(double insertionCost, int pickupInsertionIndex, int deliveryInsertionIndex, Vehicle vehicle, Driver driver) {
this.insertionCost = insertionCost; this.insertionCost = insertionCost;
this.pickupInsertionIndex = pickupInsertionIndex; this.pickupInsertionIndex = pickupInsertionIndex;
this.deliveryInsertionIndex = deliveryInsertionIndex; this.deliveryInsertionIndex = deliveryInsertionIndex;
@ -99,7 +98,7 @@ public class InsertionData {
@Override @Override
public String toString() { public String toString() {
return "[iCost="+insertionCost+"][pickupIndex="+pickupInsertionIndex+"][deliveryIndex="+deliveryInsertionIndex+"][depTime="+departureTime+"][vehicle="+selectedVehicle+"][driver="+selectedDriver+"]"; return "[iCost=" + insertionCost + "][pickupIndex=" + pickupInsertionIndex + "][deliveryIndex=" + deliveryInsertionIndex + "][depTime=" + departureTime + "][vehicle=" + selectedVehicle + "][driver=" + selectedDriver + "]";
} }
/** /**
@ -107,7 +106,7 @@ public class InsertionData {
* *
* @return * @return
*/ */
public int getDeliveryInsertionIndex(){ public int getDeliveryInsertionIndex() {
return deliveryInsertionIndex; return deliveryInsertionIndex;
} }
@ -116,7 +115,7 @@ public class InsertionData {
* *
* @return * @return
*/ */
public int getPickupInsertionIndex(){ public int getPickupInsertionIndex() {
return pickupInsertionIndex; return pickupInsertionIndex;
} }
@ -143,7 +142,7 @@ public class InsertionData {
* *
* @return * @return
*/ */
public Driver getSelectedDriver(){ public Driver getSelectedDriver() {
return selectedDriver; return selectedDriver;
} }
@ -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

@ -27,17 +27,17 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
class JobCalculatorSwitcher implements JobInsertionCostsCalculator{ class JobCalculatorSwitcher implements JobInsertionCostsCalculator {
private Map<Class<? extends Job>,JobInsertionCostsCalculator> calcMap = new HashMap<Class<? extends Job>, JobInsertionCostsCalculator>(); private Map<Class<? extends Job>, JobInsertionCostsCalculator> calcMap = new HashMap<Class<? extends Job>, JobInsertionCostsCalculator>();
void put(Class<? extends Job> jobClass, JobInsertionCostsCalculator jic){ void put(Class<? extends Job> jobClass, JobInsertionCostsCalculator jic) {
calcMap.put(jobClass, jic); calcMap.put(jobClass, jic);
} }
public InsertionData getInsertionData(VehicleRoute currentRoute, Job jobToInsert, Vehicle newVehicle, double newVehicleDepartureTime, Driver newDriver, double bestKnownScore){ public InsertionData getInsertionData(VehicleRoute currentRoute, Job jobToInsert, Vehicle newVehicle, double newVehicleDepartureTime, Driver newDriver, double bestKnownScore) {
JobInsertionCostsCalculator jic = calcMap.get(jobToInsert.getClass()); JobInsertionCostsCalculator jic = calcMap.get(jobToInsert.getClass());
if(jic==null) throw new IllegalStateException("cannot find calculator for " + jobToInsert.getClass()); if (jic == null) throw new IllegalStateException("cannot find calculator for " + jobToInsert.getClass());
return jic.getInsertionData(currentRoute, jobToInsert, newVehicle, newVehicleDepartureTime, newDriver, bestKnownScore); return jic.getInsertionData(currentRoute, jobToInsert, newVehicle, newVehicleDepartureTime, newDriver, bestKnownScore);
} }

View file

@ -30,7 +30,7 @@ import jsprit.core.problem.vehicle.VehicleImpl.NoVehicle;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
final class JobInsertionConsideringFixCostsCalculator implements JobInsertionCostsCalculator, SoftRouteConstraint{ final class JobInsertionConsideringFixCostsCalculator implements JobInsertionCostsCalculator, SoftRouteConstraint {
private static final Logger logger = LogManager.getLogger(JobInsertionConsideringFixCostsCalculator.class); private static final Logger logger = LogManager.getLogger(JobInsertionConsideringFixCostsCalculator.class);
@ -46,17 +46,17 @@ 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
public InsertionData getInsertionData(final VehicleRoute currentRoute, final Job jobToInsert, final Vehicle newVehicle, double newVehicleDepartureTime, final Driver newDriver, final double bestKnownPrice) { public InsertionData getInsertionData(final VehicleRoute currentRoute, final Job jobToInsert, final Vehicle newVehicle, double newVehicleDepartureTime, final Driver newDriver, final double bestKnownPrice) {
double fixcost_contribution = getFixCostContribution(currentRoute,jobToInsert, newVehicle); double fixcost_contribution = getFixCostContribution(currentRoute, jobToInsert, newVehicle);
if(fixcost_contribution > bestKnownPrice){ if (fixcost_contribution > bestKnownPrice) {
return InsertionData.createEmptyInsertionData(); return InsertionData.createEmptyInsertionData();
} }
InsertionData iData = standardServiceInsertion.getInsertionData(currentRoute, jobToInsert, newVehicle, newVehicleDepartureTime, newDriver, bestKnownPrice); InsertionData iData = standardServiceInsertion.getInsertionData(currentRoute, jobToInsert, newVehicle, newVehicleDepartureTime, newDriver, bestKnownPrice);
if(iData instanceof NoInsertionFound){ if (iData instanceof NoInsertionFound) {
return iData; return iData;
} }
double totalInsertionCost = iData.getInsertionCost() + fixcost_contribution; double totalInsertionCost = iData.getInsertionCost() + fixcost_contribution;
@ -70,22 +70,22 @@ final class JobInsertionConsideringFixCostsCalculator implements JobInsertionCos
final Job jobToInsert, final Vehicle newVehicle) { final Job jobToInsert, final Vehicle newVehicle) {
double relFixCost = getDeltaRelativeFixCost(currentRoute, newVehicle, jobToInsert); double relFixCost = getDeltaRelativeFixCost(currentRoute, newVehicle, jobToInsert);
double absFixCost = getDeltaAbsoluteFixCost(currentRoute, newVehicle, jobToInsert); double absFixCost = getDeltaAbsoluteFixCost(currentRoute, newVehicle, jobToInsert);
double deltaFixCost = (1-solution_completeness_ratio)*relFixCost + solution_completeness_ratio*absFixCost; double deltaFixCost = (1 - solution_completeness_ratio) * relFixCost + solution_completeness_ratio * absFixCost;
double fixcost_contribution = weight_deltaFixCost*solution_completeness_ratio*deltaFixCost; double fixcost_contribution = weight_deltaFixCost * solution_completeness_ratio * deltaFixCost;
return fixcost_contribution; return fixcost_contribution;
} }
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
public String toString() { public String toString() {
return "[name=calculatesServiceInsertionConsideringFixCost][weightOfFixedCostSavings="+weight_deltaFixCost+"]"; return "[name=calculatesServiceInsertionConsideringFixCost][weightOfFixedCostSavings=" + weight_deltaFixCost + "]";
} }
public void setSolutionCompletenessRatio(double ratio){ public void setSolutionCompletenessRatio(double ratio) {
solution_completeness_ratio = ratio; solution_completeness_ratio = ratio;
} }
@ -93,12 +93,12 @@ final class JobInsertionConsideringFixCostsCalculator implements JobInsertionCos
Capacity load = Capacity.addup(getCurrentMaxLoadInRoute(route), job.getSize()); Capacity load = Capacity.addup(getCurrentMaxLoadInRoute(route), job.getSize());
// double load = getCurrentMaxLoadInRoute(route) + job.getCapacityDemand(); // double load = getCurrentMaxLoadInRoute(route) + job.getCapacityDemand();
double currentFix = 0.0; double currentFix = 0.0;
if(route.getVehicle() != null){ if (route.getVehicle() != null) {
if(!(route.getVehicle() instanceof NoVehicle)){ if (!(route.getVehicle() instanceof NoVehicle)) {
currentFix += route.getVehicle().getType().getVehicleCostParams().fix; currentFix += route.getVehicle().getType().getVehicleCostParams().fix;
} }
} }
if(!newVehicle.getType().getCapacityDimensions().isGreaterOrEqual(load)){ if (!newVehicle.getType().getCapacityDimensions().isGreaterOrEqual(load)) {
return Double.MAX_VALUE; return Double.MAX_VALUE;
} }
return newVehicle.getType().getVehicleCostParams().fix - currentFix; return newVehicle.getType().getVehicleCostParams().fix - currentFix;
@ -110,21 +110,21 @@ final class JobInsertionConsideringFixCostsCalculator implements JobInsertionCos
Capacity load = Capacity.addup(currentLoad, job.getSize()); Capacity load = Capacity.addup(currentLoad, job.getSize());
// double load = currentLoad + job.getCapacityDemand(); // double load = currentLoad + job.getCapacityDemand();
double currentRelFix = 0.0; double currentRelFix = 0.0;
if(route.getVehicle() != null){ if (route.getVehicle() != null) {
if(!(route.getVehicle() instanceof NoVehicle)){ if (!(route.getVehicle() instanceof NoVehicle)) {
currentRelFix += route.getVehicle().getType().getVehicleCostParams().fix * Capacity.divide(currentLoad, route.getVehicle().getType().getCapacityDimensions()); currentRelFix += route.getVehicle().getType().getVehicleCostParams().fix * Capacity.divide(currentLoad, route.getVehicle().getType().getCapacityDimensions());
} }
} }
if(!newVehicle.getType().getCapacityDimensions().isGreaterOrEqual(load)){ if (!newVehicle.getType().getCapacityDimensions().isGreaterOrEqual(load)) {
return Double.MAX_VALUE; return Double.MAX_VALUE;
} }
double relativeFixCost = newVehicle.getType().getVehicleCostParams().fix* (Capacity.divide(load, newVehicle.getType().getCapacityDimensions())) - currentRelFix; double relativeFixCost = newVehicle.getType().getVehicleCostParams().fix * (Capacity.divide(load, newVehicle.getType().getCapacityDimensions())) - currentRelFix;
return relativeFixCost; return relativeFixCost;
} }
private Capacity getCurrentMaxLoadInRoute(VehicleRoute route) { private Capacity getCurrentMaxLoadInRoute(VehicleRoute route) {
Capacity maxLoad = stateGetter.getRouteState(route, InternalStates.MAXLOAD, Capacity.class); Capacity maxLoad = stateGetter.getRouteState(route, InternalStates.MAXLOAD, Capacity.class);
if(maxLoad == null) maxLoad = Capacity.Builder.newInstance().build(); if (maxLoad == null) maxLoad = Capacity.Builder.newInstance().build();
return maxLoad; return maxLoad;
} }

View file

@ -22,7 +22,7 @@ import jsprit.core.problem.solution.route.VehicleRoute;
import jsprit.core.problem.vehicle.Vehicle; import jsprit.core.problem.vehicle.Vehicle;
public interface JobInsertionCostsCalculator { public interface JobInsertionCostsCalculator {
public InsertionData getInsertionData(VehicleRoute currentRoute, Job newJob, Vehicle newVehicle, double newVehicleDepartureTime, Driver newDriver, double bestKnownCosts); public InsertionData getInsertionData(VehicleRoute currentRoute, Job newJob, Vehicle newVehicle, double newVehicleDepartureTime, Driver newDriver, double bestKnownCosts);

View file

@ -44,17 +44,17 @@ public class JobInsertionCostsCalculatorLightFactory {
* @param constraintManager constraint manager * @param constraintManager constraint manager
* @return insertion calculator * @return insertion calculator
*/ */
public static JobInsertionCostsCalculatorLight createStandardCalculator(VehicleRoutingProblem vrp, VehicleFleetManager fleetManager, StateManager stateManager, ConstraintManager constraintManager){ public static JobInsertionCostsCalculatorLight createStandardCalculator(VehicleRoutingProblem vrp, VehicleFleetManager fleetManager, StateManager stateManager, ConstraintManager constraintManager) {
List<VehicleRoutingAlgorithmListeners.PrioritizedVRAListener> al = new ArrayList<VehicleRoutingAlgorithmListeners.PrioritizedVRAListener>(); List<VehicleRoutingAlgorithmListeners.PrioritizedVRAListener> al = new ArrayList<VehicleRoutingAlgorithmListeners.PrioritizedVRAListener>();
List<InsertionListener> il = new ArrayList<InsertionListener>(); List<InsertionListener> il = new ArrayList<InsertionListener>();
JobInsertionCostsCalculatorBuilder builder = new JobInsertionCostsCalculatorBuilder(il,al); JobInsertionCostsCalculatorBuilder builder = new JobInsertionCostsCalculatorBuilder(il, al);
builder.setVehicleRoutingProblem(vrp).setConstraintManager(constraintManager).setStateManager(stateManager).setVehicleFleetManager(fleetManager); builder.setVehicleRoutingProblem(vrp).setConstraintManager(constraintManager).setStateManager(stateManager).setVehicleFleetManager(fleetManager);
final JobInsertionCostsCalculator calculator = builder.build(); final JobInsertionCostsCalculator calculator = builder.build();
return new JobInsertionCostsCalculatorLight() { return new JobInsertionCostsCalculatorLight() {
@Override @Override
public InsertionData getInsertionData(Job unassignedJob, VehicleRoute route, double bestKnownCosts) { public InsertionData getInsertionData(Job unassignedJob, VehicleRoute route, double bestKnownCosts) {
return calculator.getInsertionData(route,unassignedJob,AbstractInsertionStrategy.NO_NEW_VEHICLE_YET,AbstractInsertionStrategy.NO_NEW_DEPARTURE_TIME_YET,AbstractInsertionStrategy.NO_NEW_DRIVER_YET,bestKnownCosts); return calculator.getInsertionData(route, unassignedJob, AbstractInsertionStrategy.NO_NEW_VEHICLE_YET, AbstractInsertionStrategy.NO_NEW_DEPARTURE_TIME_YET, AbstractInsertionStrategy.NO_NEW_DRIVER_YET, bestKnownCosts);
} }
}; };

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

@ -18,7 +18,7 @@
******************************************************************************/ ******************************************************************************/
package jsprit.core.algorithm.recreate; package jsprit.core.algorithm.recreate;
public class NoSolutionFoundException extends IllegalStateException{ public class NoSolutionFoundException extends IllegalStateException {
public NoSolutionFoundException(String errorMsg) { public NoSolutionFoundException(String errorMsg) {
super(errorMsg); super(errorMsg);

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

@ -32,16 +32,15 @@ import java.util.List;
import java.util.concurrent.*; 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
@ -75,15 +74,16 @@ public class RegretInsertionConcurrent extends AbstractInsertionStrategy {
@Override @Override
public String toString() { public String toString() {
return "[name=regretInsertion][additionalScorer="+scoringFunction+"]"; return "[name=regretInsertion][additionalScorer=" + scoringFunction + "]";
} }
/** /**
* 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) {
@ -94,14 +94,14 @@ public class RegretInsertionConcurrent extends AbstractInsertionStrategy {
List<Job> unassignedJobList = new ArrayList<Job>(jobs); List<Job> unassignedJobList = new ArrayList<Job>(jobs);
List<Job> badJobList = new ArrayList<Job>(); List<Job> badJobList = new ArrayList<Job>();
ScoredJob bestScoredJob = nextJob(routes, unassignedJobList, badJobList); ScoredJob bestScoredJob = nextJob(routes, unassignedJobList, badJobList);
if(bestScoredJob != null){ if (bestScoredJob != null) {
if(bestScoredJob.isNewRoute()){ if (bestScoredJob.isNewRoute()) {
routes.add(bestScoredJob.getRoute()); routes.add(bestScoredJob.getRoute());
} }
insertJob(bestScoredJob.getJob(),bestScoredJob.getInsertionData(),bestScoredJob.getRoute()); insertJob(bestScoredJob.getJob(), bestScoredJob.getInsertionData(), bestScoredJob.getRoute());
jobs.remove(bestScoredJob.getJob()); jobs.remove(bestScoredJob.getJob());
} }
for(Job j : badJobList) { for (Job j : badJobList) {
jobs.remove(j); jobs.remove(j);
badJobs.add(j); badJobs.add(j);
} }
@ -123,38 +123,28 @@ public class RegretInsertionConcurrent extends AbstractInsertionStrategy {
}); });
} }
try{ try {
for(int i=0; i < unassignedJobList.size(); i++){ for (int i = 0; i < unassignedJobList.size(); i++) {
Future<ScoredJob> fsj = completionService.take(); Future<ScoredJob> fsj = completionService.take();
ScoredJob sJob = fsj.get(); ScoredJob sJob = fsj.get();
if(sJob instanceof RegretInsertion.BadJob){ if (sJob instanceof RegretInsertion.BadJob) {
badJobList.add(sJob.getJob()); badJobList.add(sJob.getJob());
continue; continue;
} }
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
* *
@ -32,7 +31,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
class RouteLevelActivityInsertionCostsEstimator implements ActivityInsertionCostsCalculator{ class RouteLevelActivityInsertionCostsEstimator implements ActivityInsertionCostsCalculator {
private VehicleRoutingActivityCosts activityCosts; private VehicleRoutingActivityCosts activityCosts;
@ -52,28 +51,31 @@ 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).
*/ */
double forwardPathCost_newVehicle = auxilliaryPathCostCalculator.costOfPath(path, depTimeAtPrevAct, iFacts.getNewDriver(), iFacts.getNewVehicle()); double forwardPathCost_newVehicle = auxilliaryPathCostCalculator.costOfPath(path, depTimeAtPrevAct, iFacts.getNewDriver(), iFacts.getNewVehicle());
return forwardPathCost_newVehicle - (actCostsOld(iFacts.getRoute(), path.get(path.size()-1)) - actCostsOld(iFacts.getRoute(), prevAct)); return forwardPathCost_newVehicle - (actCostsOld(iFacts.getRoute(), path.get(path.size() - 1)) - actCostsOld(iFacts.getRoute(), prevAct));
} }
private double actCostsOld(VehicleRoute vehicleRoute, TourActivity act) { private double actCostsOld(VehicleRoute vehicleRoute, TourActivity act) {
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.;
return cost_at_act; return cost_at_act;
} }
@ -81,12 +83,12 @@ class RouteLevelActivityInsertionCostsEstimator implements ActivityInsertionCost
List<TourActivity> forwardLookingPath = new ArrayList<TourActivity>(); List<TourActivity> forwardLookingPath = new ArrayList<TourActivity>();
int nuOfActsInPath = 0; int nuOfActsInPath = 0;
int index = actIndex + 1; int index = actIndex + 1;
while(index < route.getTourActivities().getActivities().size() && nuOfActsInPath < nuOfActivities2LookForward){ while (index < route.getTourActivities().getActivities().size() && nuOfActsInPath < nuOfActivities2LookForward) {
forwardLookingPath.add(route.getTourActivities().getActivities().get(index)); forwardLookingPath.add(route.getTourActivities().getActivities().get(index));
index++; index++;
nuOfActsInPath++; nuOfActsInPath++;
} }
if(nuOfActsInPath < nuOfActivities2LookForward){ if (nuOfActsInPath < nuOfActivities2LookForward) {
forwardLookingPath.add(route.getEnd()); forwardLookingPath.add(route.getEnd());
} }
return forwardLookingPath; return forwardLookingPath;

View file

@ -39,9 +39,8 @@ 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 {
private static final Logger logger = LogManager.getLogger(ServiceInsertionCalculator.class); private static final Logger logger = LogManager.getLogger(ServiceInsertionCalculator.class);
@ -70,10 +69,10 @@ 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) {
this.activityFactory = jobActivityFactory; this.activityFactory = jobActivityFactory;
} }
@ -85,12 +84,11 @@ 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) {
JobInsertionContext insertionContext = new JobInsertionContext(currentRoute, jobToInsert, newVehicle, newDriver, newVehicleDepartureTime); JobInsertionContext insertionContext = new JobInsertionContext(currentRoute, jobToInsert, newVehicle, newDriver, newVehicleDepartureTime);
Service service = (Service)jobToInsert; Service service = (Service) jobToInsert;
int insertionIndex = InsertionData.NO_INDEX; int insertionIndex = InsertionData.NO_INDEX;
TourActivity deliveryAct2Insert = activityFactory.createActivities(service).get(0); TourActivity deliveryAct2Insert = activityFactory.createActivities(service).get(0);
@ -99,7 +97,7 @@ final class ServiceInsertionCalculator implements JobInsertionCostsCalculator{
/* /*
check hard constraints at route level check hard constraints at route level
*/ */
if(!hardRouteLevelConstraint.fulfilled(insertionContext)){ if (!hardRouteLevelConstraint.fulfilled(insertionContext)) {
return InsertionData.createEmptyInsertionData(); return InsertionData.createEmptyInsertionData();
} }
@ -123,24 +121,23 @@ final class ServiceInsertionCalculator implements JobInsertionCostsCalculator{
int actIndex = 0; int actIndex = 0;
Iterator<TourActivity> activityIterator = currentRoute.getActivities().iterator(); Iterator<TourActivity> activityIterator = currentRoute.getActivities().iterator();
boolean tourEnd = false; boolean tourEnd = false;
while(!tourEnd){ while (!tourEnd) {
TourActivity nextAct; TourActivity nextAct;
if(activityIterator.hasNext()) nextAct = activityIterator.next(); if (activityIterator.hasNext()) nextAct = activityIterator.next();
else{ else {
nextAct = end; nextAct = end;
tourEnd = true; tourEnd = true;
} }
ConstraintsStatus status = hardActivityLevelConstraint.fulfilled(insertionContext, prevAct, deliveryAct2Insert, nextAct, prevActStartTime); ConstraintsStatus status = hardActivityLevelConstraint.fulfilled(insertionContext, prevAct, deliveryAct2Insert, nextAct, prevActStartTime);
if(status.equals(ConstraintsStatus.FULFILLED)){ if (status.equals(ConstraintsStatus.FULFILLED)) {
//from job2insert induced costs at activity level //from job2insert induced costs at activity level
double additionalICostsAtActLevel = softActivityConstraint.getCosts(insertionContext, prevAct, deliveryAct2Insert, nextAct, prevActStartTime); double additionalICostsAtActLevel = softActivityConstraint.getCosts(insertionContext, prevAct, deliveryAct2Insert, nextAct, prevActStartTime);
double additionalTransportationCosts = additionalTransportCostsCalculator.getCosts(insertionContext, prevAct, nextAct, deliveryAct2Insert, prevActStartTime); double additionalTransportationCosts = additionalTransportCostsCalculator.getCosts(insertionContext, prevAct, nextAct, deliveryAct2Insert, prevActStartTime);
if(additionalICostsAtRouteLevel + additionalICostsAtActLevel + additionalTransportationCosts < bestCost){ if (additionalICostsAtRouteLevel + additionalICostsAtActLevel + additionalTransportationCosts < bestCost) {
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);
@ -148,12 +145,12 @@ final class ServiceInsertionCalculator implements JobInsertionCostsCalculator{
prevAct = nextAct; prevAct = nextAct;
actIndex++; actIndex++;
} }
if(insertionIndex == InsertionData.NO_INDEX) { if (insertionIndex == InsertionData.NO_INDEX) {
return InsertionData.createEmptyInsertionData(); return InsertionData.createEmptyInsertionData();
} }
InsertionData insertionData = new InsertionData(bestCost, InsertionData.NO_INDEX, insertionIndex, newVehicle, newDriver); InsertionData insertionData = new InsertionData(bestCost, InsertionData.NO_INDEX, insertionIndex, newVehicle, newDriver);
insertionData.getEvents().add(new InsertActivity(currentRoute,newVehicle,deliveryAct2Insert,insertionIndex)); insertionData.getEvents().add(new InsertActivity(currentRoute, newVehicle, deliveryAct2Insert, insertionIndex));
insertionData.getEvents().add(new SwitchVehicle(currentRoute,newVehicle,newVehicleDepartureTime)); insertionData.getEvents().add(new SwitchVehicle(currentRoute, newVehicle, newVehicleDepartureTime));
insertionData.setVehicleDepartureTime(newVehicleDepartureTime); insertionData.setVehicleDepartureTime(newVehicleDepartureTime);
return insertionData; return insertionData;
} }

View file

@ -45,9 +45,7 @@ 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);
@ -68,20 +66,20 @@ final class ServiceInsertionOnRouteLevelCalculator implements JobInsertionCostsC
private ActivityInsertionCostsCalculator activityInsertionCostsCalculator; private ActivityInsertionCostsCalculator activityInsertionCostsCalculator;
private int nuOfActsForwardLooking = 0; private int nuOfActsForwardLooking = 0;
// //
private int memorySize = 2; private int memorySize = 2;
private Start start; private Start start;
private End end; private End end;
public void setJobActivityFactory(JobActivityFactory jobActivityFactory){ public void setJobActivityFactory(JobActivityFactory jobActivityFactory) {
this.activityFactory=jobActivityFactory; this.activityFactory = jobActivityFactory;
} }
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,22 +90,22 @@ 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);
} }
public void setStates(RouteAndActivityStateGetter stateManager){ public void setStates(RouteAndActivityStateGetter stateManager) {
this.stateManager = stateManager; this.stateManager = stateManager;
} }
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
public String toString() { public String toString() {
return "[name=calculatesServiceInsertionOnRouteLevel][solutionMemory="+memorySize+"][forwardLooking="+nuOfActsForwardLooking+"]"; return "[name=calculatesServiceInsertionOnRouteLevel][solutionMemory=" + memorySize + "][forwardLooking=" + nuOfActsForwardLooking + "]";
} }
/** /**
@ -115,16 +113,16 @@ 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)) {
return InsertionData.createEmptyInsertionData(); return InsertionData.createEmptyInsertionData();
} }
@ -140,7 +138,7 @@ final class ServiceInsertionOnRouteLevelCalculator implements JobInsertionCostsC
TourActivities tour = currentRoute.getTourActivities(); TourActivities tour = currentRoute.getTourActivities();
double best_insertion_costs = best_known_insertion_costs; double best_insertion_costs = best_known_insertion_costs;
Service service = (Service)jobToInsert; Service service = (Service) jobToInsert;
/** /**
@ -163,9 +161,9 @@ final class ServiceInsertionOnRouteLevelCalculator implements JobInsertionCostsC
* j=nextAct * j=nextAct
* k=serviceAct2Insert * k=serviceAct2Insert
*/ */
for(TourActivity nextAct : tour.getActivities()){ for (TourActivity nextAct : tour.getActivities()) {
ConstraintsStatus hardActivityConstraintsStatus = hardActivityLevelConstraint.fulfilled(insertionContext, prevAct, serviceAct2Insert, nextAct, prevActDepTime_newVehicle); ConstraintsStatus hardActivityConstraintsStatus = hardActivityLevelConstraint.fulfilled(insertionContext, prevAct, serviceAct2Insert, nextAct, prevActDepTime_newVehicle);
if(hardActivityConstraintsStatus.equals(ConstraintsStatus.FULFILLED)){ if (hardActivityConstraintsStatus.equals(ConstraintsStatus.FULFILLED)) {
/** /**
* builds a path on this route forwardPath={i,k,j,j+1,j+2,...,j+nuOfActsForwardLooking} * builds a path on this route forwardPath={i,k,j,j+1,j+2,...,j+nuOfActsForwardLooking}
*/ */
@ -174,16 +172,15 @@ final class ServiceInsertionOnRouteLevelCalculator implements JobInsertionCostsC
/** /**
* insertion_cost_approximation = c({0,1,...,i},newVehicle) + c({i,k,j,j+1,j+2,...,j+nuOfActsForwardLooking},newVehicle) - c({0,1,...,i,j,j+1,...,j+nuOfActsForwardLooking},oldVehicle) * insertion_cost_approximation = c({0,1,...,i},newVehicle) + c({i,k,j,j+1,j+2,...,j+nuOfActsForwardLooking},newVehicle) - c({0,1,...,i,j,j+1,...,j+nuOfActsForwardLooking},oldVehicle)
*/ */
double insertion_cost_approximation = sumOf_prevCosts_newVehicle - sumOf_prevCosts_oldVehicle(currentRoute,prevAct) + actInsertionCosts; double insertion_cost_approximation = sumOf_prevCosts_newVehicle - sumOf_prevCosts_oldVehicle(currentRoute, prevAct) + actInsertionCosts;
/** /**
* memorize it in insertion-queue * memorize it in insertion-queue
*/ */
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;
} }
@ -216,21 +213,21 @@ final class ServiceInsertionOnRouteLevelCalculator implements JobInsertionCostsC
actIndex++; actIndex++;
} }
if(!loopBroken){ if (!loopBroken) {
End nextAct = end; End nextAct = end;
ConstraintsStatus hardActivityConstraintsStatus = hardActivityLevelConstraint.fulfilled(insertionContext, prevAct, serviceAct2Insert, nextAct, prevActDepTime_newVehicle); ConstraintsStatus hardActivityConstraintsStatus = hardActivityLevelConstraint.fulfilled(insertionContext, prevAct, serviceAct2Insert, nextAct, prevActDepTime_newVehicle);
if(hardActivityConstraintsStatus.equals(ConstraintsStatus.FULFILLED)){ if (hardActivityConstraintsStatus.equals(ConstraintsStatus.FULFILLED)) {
double actInsertionCosts = activityInsertionCostsCalculator.getCosts(insertionContext, prevAct, nextAct, serviceAct2Insert, prevActDepTime_newVehicle); double actInsertionCosts = activityInsertionCostsCalculator.getCosts(insertionContext, prevAct, nextAct, serviceAct2Insert, prevActDepTime_newVehicle);
/** /**
* insertion_cost_approximation = c({0,1,...,i},newVehicle) + c({i,k,j,j+1,j+2,...,j+nuOfActsForwardLooking},newVehicle) - c({0,1,...,i,j,j+1,...,j+nuOfActsForwardLooking},oldVehicle) * insertion_cost_approximation = c({0,1,...,i},newVehicle) + c({i,k,j,j+1,j+2,...,j+nuOfActsForwardLooking},newVehicle) - c({0,1,...,i,j,j+1,...,j+nuOfActsForwardLooking},oldVehicle)
*/ */
double insertion_cost_approximation = sumOf_prevCosts_newVehicle - sumOf_prevCosts_oldVehicle(currentRoute,prevAct) + actInsertionCosts; double insertion_cost_approximation = sumOf_prevCosts_newVehicle - sumOf_prevCosts_oldVehicle(currentRoute, prevAct) + actInsertionCosts;
/** /**
* memorize it in insertion-queue * memorize it in insertion-queue
*/ */
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));
} }
@ -244,18 +241,17 @@ final class ServiceInsertionOnRouteLevelCalculator implements JobInsertionCostsC
* *
*/ */
if(memorySize==0){ // return bestInsertion if (memorySize == 0) { // return bestInsertion
InsertionData insertion = bestInsertionsQueue.poll(); InsertionData insertion = bestInsertionsQueue.poll();
if(insertion != null){ if (insertion != null) {
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();
if(data == null){ if (data == null) {
continue; continue;
} }
/** /**
@ -265,46 +261,44 @@ final class ServiceInsertionOnRouteLevelCalculator implements JobInsertionCostsC
wholeTour.add(start); wholeTour.add(start);
wholeTour.addAll(currentRoute.getTourActivities().getActivities()); wholeTour.addAll(currentRoute.getTourActivities().getActivities());
wholeTour.add(end); wholeTour.add(end);
wholeTour.add(data.getDeliveryInsertionIndex()+1, serviceAct2Insert); wholeTour.add(data.getDeliveryInsertionIndex() + 1, serviceAct2Insert);
/** /**
* compute cost-diff of tour with and without new activity --> insertion_costs * compute cost-diff of tour with and without new activity --> insertion_costs
*/ */
Double currentRouteCosts = stateManager.getRouteState(currentRoute, InternalStates.COSTS, Double.class); Double currentRouteCosts = stateManager.getRouteState(currentRoute, InternalStates.COSTS, Double.class);
if(currentRouteCosts == null) currentRouteCosts = 0.; if (currentRouteCosts == null) currentRouteCosts = 0.;
double insertion_costs = auxilliaryPathCostCalculator.costOfPath(wholeTour, start.getEndTime(), newDriver, newVehicle) - currentRouteCosts; double insertion_costs = auxilliaryPathCostCalculator.costOfPath(wholeTour, start.getEndTime(), newDriver, newVehicle) - currentRouteCosts;
/** /**
* if better than best known, make it the best known * if better than best known, make it the best known
*/ */
if(insertion_costs < best_insertion_costs){ if (insertion_costs < best_insertion_costs) {
best_insertion_index = data.getDeliveryInsertionIndex(); best_insertion_index = data.getDeliveryInsertionIndex();
best_insertion_costs = insertion_costs; best_insertion_costs = insertion_costs;
} }
} }
} }
if(best_insertion_index == InsertionData.NO_INDEX) return InsertionData.createEmptyInsertionData(); if (best_insertion_index == InsertionData.NO_INDEX) return InsertionData.createEmptyInsertionData();
InsertionData insertionData = new InsertionData(best_insertion_costs, InsertionData.NO_INDEX, best_insertion_index, newVehicle, newDriver); InsertionData insertionData = new InsertionData(best_insertion_costs, InsertionData.NO_INDEX, best_insertion_index, newVehicle, newDriver);
insertionData.setVehicleDepartureTime(start.getEndTime()); insertionData.setVehicleDepartureTime(start.getEndTime());
return insertionData; return insertionData;
} }
private void initialiseStartAndEnd(final Vehicle newVehicle, double newVehicleDepartureTime) { private void initialiseStartAndEnd(final Vehicle newVehicle, double newVehicleDepartureTime) {
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);
start.setEndTime(newVehicleDepartureTime); start.setEndTime(newVehicleDepartureTime);
} }
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());
@ -313,11 +307,10 @@ final class ServiceInsertionOnRouteLevelCalculator implements JobInsertionCostsC
private double sumOf_prevCosts_oldVehicle(VehicleRoute vehicleRoute, TourActivity act) { private double sumOf_prevCosts_oldVehicle(VehicleRoute vehicleRoute, TourActivity act) {
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;
} }
@ -326,10 +319,9 @@ final class ServiceInsertionOnRouteLevelCalculator implements JobInsertionCostsC
@Override @Override
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,9 +37,7 @@ 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,10 +66,10 @@ 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) {
this.activityFactory = activityFactory; this.activityFactory = activityFactory;
} }
@ -83,12 +81,11 @@ 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) {
JobInsertionContext insertionContext = new JobInsertionContext(currentRoute, jobToInsert, newVehicle, newDriver, newVehicleDepartureTime); JobInsertionContext insertionContext = new JobInsertionContext(currentRoute, jobToInsert, newVehicle, newDriver, newVehicleDepartureTime);
Shipment shipment = (Shipment)jobToInsert; Shipment shipment = (Shipment) jobToInsert;
TourActivity pickupShipment = activityFactory.createActivities(shipment).get(0); TourActivity pickupShipment = activityFactory.createActivities(shipment).get(0);
TourActivity deliverShipment = activityFactory.createActivities(shipment).get(1); TourActivity deliverShipment = activityFactory.createActivities(shipment).get(1);
insertionContext.getAssociatedActivities().add(pickupShipment); insertionContext.getAssociatedActivities().add(pickupShipment);
@ -97,7 +94,7 @@ final class ShipmentInsertionCalculator implements JobInsertionCostsCalculator{
/* /*
check hard route constraints check hard route constraints
*/ */
if(!hardRouteLevelConstraint.fulfilled(insertionContext)){ if (!hardRouteLevelConstraint.fulfilled(insertionContext)) {
return InsertionData.createEmptyInsertionData(); return InsertionData.createEmptyInsertionData();
} }
/* /*
@ -127,29 +124,27 @@ final class ShipmentInsertionCalculator implements JobInsertionCostsCalculator{
//pickupShipmentLoop //pickupShipmentLoop
List<TourActivity> activities = currentRoute.getTourActivities().getActivities(); List<TourActivity> activities = currentRoute.getTourActivities().getActivities();
while(!tourEnd){ while (!tourEnd) {
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);
prevActEndTime = CalculationUtils.getActivityEndTime(nextActArrTime, nextAct); prevActEndTime = CalculationUtils.getActivityEndTime(nextActArrTime, nextAct);
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);
double pickupAIC = calculate(insertionContext,prevAct,pickupShipment, nextAct,prevActEndTime); double pickupAIC = calculate(insertionContext, prevAct, pickupShipment, nextAct, prevActEndTime);
TourActivity prevAct_deliveryLoop = pickupShipment; TourActivity prevAct_deliveryLoop = pickupShipment;
double shipmentPickupArrTime = prevActEndTime + transportCosts.getTransportTime(prevAct.getLocation(), pickupShipment.getLocation(), prevActEndTime, newDriver, newVehicle); double shipmentPickupArrTime = prevActEndTime + transportCosts.getTransportTime(prevAct.getLocation(), pickupShipment.getLocation(), prevActEndTime, newDriver, newVehicle);
@ -168,31 +163,29 @@ final class ShipmentInsertionCalculator implements JobInsertionCostsCalculator{
//deliverShipmentLoop //deliverShipmentLoop
int j = i; int j = i;
boolean tourEnd_deliveryLoop = false; boolean tourEnd_deliveryLoop = false;
while(!tourEnd_deliveryLoop){ while (!tourEnd_deliveryLoop) {
// for(int j=i;j<activities.size();j++){ // for(int j=i;j<activities.size();j++){
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;
} }
ConstraintsStatus deliverShipmentConstraintStatus = hardActivityLevelConstraint.fulfilled(insertionContext, prevAct_deliveryLoop, deliverShipment, nextAct_deliveryLoop, prevActEndTime_deliveryLoop); ConstraintsStatus deliverShipmentConstraintStatus = hardActivityLevelConstraint.fulfilled(insertionContext, prevAct_deliveryLoop, deliverShipment, nextAct_deliveryLoop, prevActEndTime_deliveryLoop);
if(deliverShipmentConstraintStatus.equals(ConstraintsStatus.FULFILLED)){ if (deliverShipmentConstraintStatus.equals(ConstraintsStatus.FULFILLED)) {
double additionalDeliveryICosts = softActivityConstraint.getCosts(insertionContext, prevAct_deliveryLoop, deliverShipment, nextAct_deliveryLoop, prevActEndTime_deliveryLoop); double additionalDeliveryICosts = softActivityConstraint.getCosts(insertionContext, prevAct_deliveryLoop, deliverShipment, nextAct_deliveryLoop, prevActEndTime_deliveryLoop);
double deliveryAIC = calculate(insertionContext,prevAct_deliveryLoop,deliverShipment, nextAct_deliveryLoop,prevActEndTime_deliveryLoop); double deliveryAIC = calculate(insertionContext, prevAct_deliveryLoop, deliverShipment, nextAct_deliveryLoop, prevActEndTime_deliveryLoop);
double totalActivityInsertionCosts = pickupAIC + deliveryAIC double totalActivityInsertionCosts = pickupAIC + deliveryAIC
+ additionalICostsAtRouteLevel + additionalPickupICosts + additionalDeliveryICosts; + additionalICostsAtRouteLevel + additionalPickupICosts + additionalDeliveryICosts;
if(totalActivityInsertionCosts < bestCost){ if (totalActivityInsertionCosts < bestCost) {
bestCost = totalActivityInsertionCosts; bestCost = totalActivityInsertionCosts;
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
@ -207,14 +200,14 @@ final class ShipmentInsertionCalculator implements JobInsertionCostsCalculator{
prevAct = nextAct; prevAct = nextAct;
i++; i++;
} }
if(pickupInsertionIndex == InsertionData.NO_INDEX) { if (pickupInsertionIndex == InsertionData.NO_INDEX) {
return InsertionData.createEmptyInsertionData(); return InsertionData.createEmptyInsertionData();
} }
InsertionData insertionData = new InsertionData(bestCost, pickupInsertionIndex, deliveryInsertionIndex, newVehicle, newDriver); InsertionData insertionData = new InsertionData(bestCost, pickupInsertionIndex, deliveryInsertionIndex, newVehicle, newDriver);
insertionData.setVehicleDepartureTime(newVehicleDepartureTime); insertionData.setVehicleDepartureTime(newVehicleDepartureTime);
insertionData.getEvents().add(new InsertActivity(currentRoute,newVehicle,deliverShipment,deliveryInsertionIndex)); insertionData.getEvents().add(new InsertActivity(currentRoute, newVehicle, deliverShipment, deliveryInsertionIndex));
insertionData.getEvents().add(new InsertActivity(currentRoute,newVehicle,pickupShipment,pickupInsertionIndex)); insertionData.getEvents().add(new InsertActivity(currentRoute, newVehicle, pickupShipment, pickupInsertionIndex));
insertionData.getEvents().add(new SwitchVehicle(currentRoute,newVehicle,newVehicleDepartureTime)); insertionData.getEvents().add(new SwitchVehicle(currentRoute, newVehicle, newVehicleDepartureTime));
return insertionData; return insertionData;
} }

View file

@ -7,13 +7,13 @@ import org.apache.logging.log4j.Logger;
/** /**
* Created by schroeder on 19/05/15. * Created by schroeder on 19/05/15.
*/ */
class SwitchVehicleListener implements EventListener{ class SwitchVehicleListener implements EventListener {
private static final Logger logger = LogManager.getLogger(); private static final Logger logger = LogManager.getLogger();
@Override @Override
public void inform(Event event) { public void inform(Event event) {
if(event instanceof SwitchVehicle){ if (event instanceof SwitchVehicle) {
SwitchVehicle switchVehicle = (SwitchVehicle) event; SwitchVehicle switchVehicle = (SwitchVehicle) event;
if(vehiclesDifferent((SwitchVehicle) event)) { if(vehiclesDifferent((SwitchVehicle) event)) {
logger.trace("switch vehicle (" + ((SwitchVehicle) event).getRoute().getVehicle().getId() + " to " + ((SwitchVehicle) event).getVehicle().getId() + ")"); logger.trace("switch vehicle (" + ((SwitchVehicle) event).getRoute().getVehicle().getId() + " to " + ((SwitchVehicle) event).getVehicle().getId() + ")");

View file

@ -23,7 +23,7 @@ import jsprit.core.problem.solution.route.activity.End;
import jsprit.core.problem.solution.route.activity.TourActivity; import jsprit.core.problem.solution.route.activity.TourActivity;
import jsprit.core.util.CalculationUtils; import jsprit.core.util.CalculationUtils;
public class VariableTransportCostCalculator implements SoftActivityConstraint{ public class VariableTransportCostCalculator implements SoftActivityConstraint {
private VehicleRoutingTransportCosts routingCosts; private VehicleRoutingTransportCosts routingCosts;
@ -33,7 +33,7 @@ public class VariableTransportCostCalculator implements SoftActivityConstraint{
} }
@Override @Override
public double getCosts(JobInsertionContext iFacts, TourActivity prevAct,TourActivity newAct, TourActivity nextAct, double depTimeAtPrevAct) { public double getCosts(JobInsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double depTimeAtPrevAct) {
double tp_costs_prevAct_newAct = routingCosts.getTransportCost(prevAct.getLocation(), newAct.getLocation(), depTimeAtPrevAct, iFacts.getNewDriver(), iFacts.getNewVehicle()); double tp_costs_prevAct_newAct = routingCosts.getTransportCost(prevAct.getLocation(), newAct.getLocation(), depTimeAtPrevAct, iFacts.getNewDriver(), iFacts.getNewVehicle());
double tp_time_prevAct_newAct = routingCosts.getTransportTime(prevAct.getLocation(), newAct.getLocation(), depTimeAtPrevAct, iFacts.getNewDriver(), iFacts.getNewVehicle()); double tp_time_prevAct_newAct = routingCosts.getTransportTime(prevAct.getLocation(), newAct.getLocation(), depTimeAtPrevAct, iFacts.getNewDriver(), iFacts.getNewVehicle());
@ -41,8 +41,8 @@ public class VariableTransportCostCalculator implements SoftActivityConstraint{
double newAct_endTime = CalculationUtils.getActivityEndTime(newAct_arrTime, newAct); double newAct_endTime = CalculationUtils.getActivityEndTime(newAct_arrTime, newAct);
//open routes //open routes
if(nextAct instanceof End){ if (nextAct instanceof End) {
if(!iFacts.getNewVehicle().isReturnToDepot()){ if (!iFacts.getNewVehicle().isReturnToDepot()) {
return tp_costs_prevAct_newAct; return tp_costs_prevAct_newAct;
} }
} }
@ -51,11 +51,10 @@ public class VariableTransportCostCalculator implements SoftActivityConstraint{
double totalCosts = tp_costs_prevAct_newAct + tp_costs_newAct_nextAct; double totalCosts = tp_costs_prevAct_newAct + tp_costs_newAct_nextAct;
double oldCosts; double oldCosts;
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

@ -22,11 +22,11 @@ import jsprit.core.problem.vehicle.Vehicle;
import jsprit.core.problem.vehicle.VehicleFleetManager; import jsprit.core.problem.vehicle.VehicleFleetManager;
public class VehicleSwitched implements VehicleSwitchedListener{ public class VehicleSwitched implements VehicleSwitchedListener {
private VehicleFleetManager fleetManager; private VehicleFleetManager fleetManager;
public VehicleSwitched(VehicleFleetManager fleetManager){ public VehicleSwitched(VehicleFleetManager fleetManager) {
this.fleetManager = fleetManager; this.fleetManager = fleetManager;
} }

View file

@ -33,7 +33,7 @@ import java.util.HashSet;
import java.util.Set; import java.util.Set;
final class VehicleTypeDependentJobInsertionCalculator implements JobInsertionCostsCalculator{ final class VehicleTypeDependentJobInsertionCalculator implements JobInsertionCostsCalculator {
private Logger logger = LogManager.getLogger(VehicleTypeDependentJobInsertionCalculator.class); private Logger logger = LogManager.getLogger(VehicleTypeDependentJobInsertionCalculator.class);
@ -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;
@ -65,7 +64,7 @@ final class VehicleTypeDependentJobInsertionCalculator implements JobInsertionCo
private void getInitialVehicleIds() { private void getInitialVehicleIds() {
Collection<VehicleRoute> initialVehicleRoutes = vrp.getInitialVehicleRoutes(); Collection<VehicleRoute> initialVehicleRoutes = vrp.getInitialVehicleRoutes();
for(VehicleRoute initialRoute : initialVehicleRoutes){ for (VehicleRoute initialRoute : initialVehicleRoutes) {
initialVehicleIds.add(initialRoute.getVehicle().getId()); initialVehicleIds.add(initialRoute.getVehicle().getId());
} }
} }
@ -99,24 +98,23 @@ final class VehicleTypeDependentJobInsertionCalculator implements JobInsertionCo
InsertionData bestIData = InsertionData.createEmptyInsertionData(); InsertionData bestIData = InsertionData.createEmptyInsertionData();
double bestKnownCost_ = bestKnownCost; double bestKnownCost_ = bestKnownCost;
Collection<Vehicle> relevantVehicles = new ArrayList<Vehicle>(); Collection<Vehicle> relevantVehicles = new ArrayList<Vehicle>();
if(!(selectedVehicle instanceof NoVehicle)) { if (!(selectedVehicle instanceof NoVehicle)) {
relevantVehicles.add(selectedVehicle); relevantVehicles.add(selectedVehicle);
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;
} }
if(iData.getInsertionCost() < bestKnownCost_){ if (iData.getInsertionCost() < bestKnownCost_) {
bestIData = iData; bestIData = iData;
bestKnownCost_ = iData.getInsertionCost(); bestKnownCost_ = iData.getInsertionCost();
} }

View file

@ -20,7 +20,7 @@ import jsprit.core.algorithm.recreate.InsertionData;
import jsprit.core.problem.job.Job; import jsprit.core.problem.job.Job;
import jsprit.core.problem.solution.route.VehicleRoute; import jsprit.core.problem.solution.route.VehicleRoute;
public interface BeforeJobInsertionListener extends InsertionListener{ public interface BeforeJobInsertionListener extends InsertionListener {
public void informBeforeJobInsertion(Job job, InsertionData data, VehicleRoute route); public void informBeforeJobInsertion(Job job, InsertionData data, VehicleRoute route);

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

@ -29,60 +29,60 @@ public class InsertionListeners {
private Collection<InsertionListener> listeners = new ArrayList<InsertionListener>(); private Collection<InsertionListener> listeners = new ArrayList<InsertionListener>();
public Collection<InsertionListener> getListeners(){ public Collection<InsertionListener> getListeners() {
return listeners; return listeners;
} }
public void informJobInserted(Job insertedJob, VehicleRoute inRoute, double additionalCosts, double additionalTime){ public void informJobInserted(Job insertedJob, VehicleRoute inRoute, double additionalCosts, double additionalTime) {
for(InsertionListener l : listeners){ for (InsertionListener l : listeners) {
if(l instanceof JobInsertedListener){ if (l instanceof JobInsertedListener) {
((JobInsertedListener)l).informJobInserted(insertedJob, inRoute, additionalCosts, additionalTime); ((JobInsertedListener) l).informJobInserted(insertedJob, inRoute, additionalCosts, additionalTime);
} }
} }
} }
public void informVehicleSwitched(VehicleRoute route, Vehicle oldVehicle, Vehicle newVehicle){ public void informVehicleSwitched(VehicleRoute route, Vehicle oldVehicle, Vehicle newVehicle) {
for(InsertionListener l : listeners){ for (InsertionListener l : listeners) {
if(l instanceof VehicleSwitchedListener){ if (l instanceof VehicleSwitchedListener) {
((VehicleSwitchedListener) l).vehicleSwitched(route, oldVehicle, newVehicle); ((VehicleSwitchedListener) l).vehicleSwitched(route, oldVehicle, newVehicle);
} }
} }
} }
public void informBeforeJobInsertion(Job job, InsertionData data, VehicleRoute route){ public void informBeforeJobInsertion(Job job, InsertionData data, VehicleRoute route) {
for(InsertionListener l : listeners){ for (InsertionListener l : listeners) {
if(l instanceof BeforeJobInsertionListener){ if (l instanceof BeforeJobInsertionListener) {
((BeforeJobInsertionListener)l).informBeforeJobInsertion(job, data, route); ((BeforeJobInsertionListener) l).informBeforeJobInsertion(job, data, route);
} }
} }
} }
public void informInsertionStarts(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs){ public void informInsertionStarts(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs) {
for(InsertionListener l : listeners){ for (InsertionListener l : listeners) {
if(l instanceof InsertionStartsListener){ if (l instanceof InsertionStartsListener) {
((InsertionStartsListener)l).informInsertionStarts(vehicleRoutes, unassignedJobs); ((InsertionStartsListener) l).informInsertionStarts(vehicleRoutes, unassignedJobs);
} }
} }
} }
public void informInsertionEndsListeners(Collection<VehicleRoute> vehicleRoutes) { public void informInsertionEndsListeners(Collection<VehicleRoute> vehicleRoutes) {
for(InsertionListener l : listeners){ for (InsertionListener l : listeners) {
if(l instanceof InsertionEndsListener){ if (l instanceof InsertionEndsListener) {
((InsertionEndsListener)l).informInsertionEnds(vehicleRoutes); ((InsertionEndsListener) l).informInsertionEnds(vehicleRoutes);
} }
} }
} }
public void addListener(InsertionListener insertionListener){ public void addListener(InsertionListener insertionListener) {
listeners.add(insertionListener); listeners.add(insertionListener);
} }
public void removeListener(InsertionListener insertionListener){ public void removeListener(InsertionListener insertionListener) {
listeners.remove(insertionListener); listeners.remove(insertionListener);
} }
public void addAllListeners(Collection<InsertionListener> listeners) { public void addAllListeners(Collection<InsertionListener> listeners) {
for(InsertionListener l : listeners) addListener(l); for (InsertionListener l : listeners) addListener(l);
} }
} }

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,11 +20,7 @@ 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

@ -19,7 +19,7 @@ package jsprit.core.algorithm.recreate.listener;
import jsprit.core.problem.solution.route.VehicleRoute; import jsprit.core.problem.solution.route.VehicleRoute;
import jsprit.core.problem.vehicle.Vehicle; import jsprit.core.problem.vehicle.Vehicle;
public interface VehicleSwitchedListener extends InsertionListener{ public interface VehicleSwitchedListener extends InsertionListener {
public void vehicleSwitched(VehicleRoute vehicleRoute, Vehicle oldVehicle, Vehicle newVehicle); public void vehicleSwitched(VehicleRoute vehicleRoute, Vehicle oldVehicle, Vehicle newVehicle);

View file

@ -30,7 +30,7 @@ import org.apache.logging.log4j.Logger;
import java.util.Collection; import java.util.Collection;
import java.util.Random; import java.util.Random;
public abstract class AbstractRuinStrategy implements RuinStrategy{ public abstract class AbstractRuinStrategy implements RuinStrategy {
private final static Logger logger = LogManager.getLogger(); private final static Logger logger = LogManager.getLogger();
@ -46,11 +46,11 @@ public abstract class AbstractRuinStrategy implements RuinStrategy{
protected RuinShareFactory ruinShareFactory; protected RuinShareFactory ruinShareFactory;
public void setRuinShareFactory(RuinShareFactory ruinShareFactory){ public void setRuinShareFactory(RuinShareFactory ruinShareFactory) {
this.ruinShareFactory = ruinShareFactory; this.ruinShareFactory = ruinShareFactory;
} }
public RuinShareFactory getRuinShareFactory(){ public RuinShareFactory getRuinShareFactory() {
return ruinShareFactory; return ruinShareFactory;
} }
@ -60,11 +60,11 @@ public abstract class AbstractRuinStrategy implements RuinStrategy{
} }
@Override @Override
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;
} }
@ -73,10 +73,10 @@ public abstract class AbstractRuinStrategy implements RuinStrategy{
@Override @Override
@Deprecated @Deprecated
public Collection<Job> ruin(Collection<VehicleRoute> vehicleRoutes, Job targetJob, int nOfJobs2BeRemoved){ public Collection<Job> ruin(Collection<VehicleRoute> vehicleRoutes, Job targetJob, int nOfJobs2BeRemoved) {
ruinListeners.ruinStarts(vehicleRoutes); ruinListeners.ruinStarts(vehicleRoutes);
Collection<Job> unassigned = ruinRoutes(vehicleRoutes, targetJob, nOfJobs2BeRemoved); Collection<Job> unassigned = ruinRoutes(vehicleRoutes, targetJob, nOfJobs2BeRemoved);
ruinListeners.ruinEnds(vehicleRoutes,unassigned); ruinListeners.ruinEnds(vehicleRoutes, unassigned);
return unassigned; return unassigned;
} }
@ -99,7 +99,7 @@ public abstract class AbstractRuinStrategy implements RuinStrategy{
} }
protected boolean removeJob(Job job, Collection<VehicleRoute> vehicleRoutes) { protected boolean removeJob(Job job, Collection<VehicleRoute> vehicleRoutes) {
if(jobIsInitial(job)) return false; if (jobIsInitial(job)) return false;
for (VehicleRoute route : vehicleRoutes) { for (VehicleRoute route : vehicleRoutes) {
if (removeJob(job, route)) { if (removeJob(job, route)) {
return true; return true;
@ -108,16 +108,16 @@ public abstract class AbstractRuinStrategy implements RuinStrategy{
return false; return false;
} }
private boolean jobIsInitial(Job job){ private boolean jobIsInitial(Job job) {
return !vrp.getJobs().containsKey(job.getId()); //for initial jobs (being not contained in problem return !vrp.getJobs().containsKey(job.getId()); //for initial jobs (being not contained in problem
} }
protected boolean removeJob(Job job, VehicleRoute route) { protected boolean removeJob(Job job, VehicleRoute route) {
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;
} }
return false; return false;

View file

@ -5,8 +5,8 @@ import jsprit.core.problem.job.Job;
import java.util.Iterator; import java.util.Iterator;
/** /**
* Created by schroeder on 07/01/15. * Created by schroeder on 07/01/15.
*/ */
public interface JobNeighborhoods { public interface JobNeighborhoods {
public Iterator<Job> getNearestNeighborsIterator(int nNeighbors, Job neighborTo); public Iterator<Job> getNearestNeighborsIterator(int nNeighbors, Job neighborTo);

View file

@ -8,12 +8,12 @@ import jsprit.core.problem.VehicleRoutingProblem;
*/ */
public class JobNeighborhoodsFactory { public class JobNeighborhoodsFactory {
public JobNeighborhoods createNeighborhoods(VehicleRoutingProblem vrp, JobDistance jobDistance){ public JobNeighborhoods createNeighborhoods(VehicleRoutingProblem vrp, JobDistance jobDistance) {
return new JobNeighborhoodsImpl(vrp,jobDistance); return new JobNeighborhoodsImpl(vrp, jobDistance);
} }
public JobNeighborhoods createNeighborhoods(VehicleRoutingProblem vrp, JobDistance jobDistance, int capacity){ public JobNeighborhoods createNeighborhoods(VehicleRoutingProblem vrp, JobDistance jobDistance, int capacity) {
return new JobNeighborhoodsImplWithCapRestriction(vrp,jobDistance,capacity); return new JobNeighborhoodsImplWithCapRestriction(vrp, jobDistance, capacity);
} }
} }

View file

@ -10,8 +10,8 @@ import org.apache.logging.log4j.Logger;
import java.util.*; import java.util.*;
/** /**
* Created by schroeder on 07/01/15. * Created by schroeder on 07/01/15.
*/ */
class JobNeighborhoodsImpl implements JobNeighborhoods { class JobNeighborhoodsImpl implements JobNeighborhoods {
private static Logger logger = LogManager.getLogger(JobNeighborhoodsImpl.class); private static Logger logger = LogManager.getLogger(JobNeighborhoodsImpl.class);
@ -26,13 +26,13 @@ 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
public Iterator<Job> getNearestNeighborsIterator(int nNeighbors, Job neighborTo){ public Iterator<Job> getNearestNeighborsIterator(int nNeighbors, Job neighborTo) {
TreeSet<ReferencedJob> tree = distanceNodeTree.get(neighborTo.getId()); TreeSet<ReferencedJob> tree = distanceNodeTree.get(neighborTo.getId());
if(tree == null) return new Iterator<Job>() { if (tree == null) return new Iterator<Job>() {
@Override @Override
public boolean hasNext() { public boolean hasNext() {
return false; return false;
@ -53,7 +53,7 @@ class JobNeighborhoodsImpl implements JobNeighborhoods {
} }
@Override @Override
public void initialise(){ public void initialise() {
logger.debug("calculates and memorizes distances from EACH job to EACH job --> n^2 calculations"); logger.debug("calculates and memorizes distances from EACH job to EACH job --> n^2 calculations");
calculateDistancesFromJob2Job(); calculateDistancesFromJob2Job();
} }
@ -77,7 +77,7 @@ class JobNeighborhoodsImpl implements JobNeighborhoods {
}); });
distanceNodeTree.put(i.getId(), treeSet); distanceNodeTree.put(i.getId(), treeSet);
for (Job j : vrp.getJobs().values()) { for (Job j : vrp.getJobs().values()) {
if(i==j) continue; if (i == j) continue;
double distance = jobDistance.getDistance(i, j); double distance = jobDistance.getDistance(i, j);
ReferencedJob refNode = new ReferencedJob(j, distance); ReferencedJob refNode = new ReferencedJob(j, distance);
treeSet.add(refNode); treeSet.add(refNode);
@ -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

@ -10,8 +10,8 @@ import org.apache.logging.log4j.Logger;
import java.util.*; import java.util.*;
/** /**
* Created by schroeder on 07/01/15. * Created by schroeder on 07/01/15.
*/ */
class JobNeighborhoodsImplWithCapRestriction implements JobNeighborhoods { class JobNeighborhoodsImplWithCapRestriction implements JobNeighborhoods {
private static Logger logger = LogManager.getLogger(JobNeighborhoodsImpl.class); private static Logger logger = LogManager.getLogger(JobNeighborhoodsImpl.class);
@ -29,13 +29,13 @@ 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
public Iterator<Job> getNearestNeighborsIterator(int nNeighbors, Job neighborTo){ public Iterator<Job> getNearestNeighborsIterator(int nNeighbors, Job neighborTo) {
TreeSet<ReferencedJob> tree = distanceNodeTree.get(neighborTo.getId()); TreeSet<ReferencedJob> tree = distanceNodeTree.get(neighborTo.getId());
if(tree == null) return new Iterator<Job>() { if (tree == null) return new Iterator<Job>() {
@Override @Override
public boolean hasNext() { public boolean hasNext() {
@ -58,9 +58,9 @@ 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();
} }
@ -83,15 +83,14 @@ class JobNeighborhoodsImplWithCapRestriction implements JobNeighborhoods {
}); });
distanceNodeTree.put(i.getId(), treeSet); distanceNodeTree.put(i.getId(), treeSet);
for (Job j : vrp.getJobs().values()) { for (Job j : vrp.getJobs().values()) {
if(i==j) continue; if (i == j) continue;
double distance = jobDistance.getDistance(i, j); double distance = jobDistance.getDistance(i, j);
ReferencedJob refNode = new ReferencedJob(j, distance); ReferencedJob refNode = new ReferencedJob(j, distance);
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,13 +100,13 @@ 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
public String toString() { public String toString() {
return "[name=neighborhoodWithCapRestriction][capacity="+capacity+"]"; return "[name=neighborhoodWithCapRestriction][capacity=" + capacity + "]";
} }
} }

View file

@ -7,8 +7,8 @@ import org.apache.logging.log4j.Logger;
import java.util.Iterator; import java.util.Iterator;
/** /**
* Created by schroeder on 07/01/15. * Created by schroeder on 07/01/15.
*/ */
class NearestNeighborhoodIterator implements Iterator<Job> { class NearestNeighborhoodIterator implements Iterator<Job> {
private static Logger log = LogManager.getLogger(NearestNeighborhoodIterator.class); private static Logger log = LogManager.getLogger(NearestNeighborhoodIterator.class);
@ -27,9 +27,10 @@ class NearestNeighborhoodIterator implements Iterator<Job> {
@Override @Override
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

@ -21,7 +21,7 @@ package jsprit.core.algorithm.ruin;
import jsprit.core.algorithm.ruin.distance.JobDistance; import jsprit.core.algorithm.ruin.distance.JobDistance;
import jsprit.core.problem.VehicleRoutingProblem; import jsprit.core.problem.VehicleRoutingProblem;
public class RadialRuinStrategyFactory implements RuinStrategyFactory{ public class RadialRuinStrategyFactory implements RuinStrategyFactory {
private double fraction; private double fraction;
@ -35,7 +35,7 @@ public class RadialRuinStrategyFactory implements RuinStrategyFactory{
@Override @Override
public RuinStrategy createStrategy(VehicleRoutingProblem vrp) { public RuinStrategy createStrategy(VehicleRoutingProblem vrp) {
return new RuinRadial(vrp,fraction,jobDistance); return new RuinRadial(vrp, fraction, jobDistance);
} }
} }

View file

@ -20,7 +20,7 @@ package jsprit.core.algorithm.ruin;
import jsprit.core.problem.VehicleRoutingProblem; import jsprit.core.problem.VehicleRoutingProblem;
public class RandomRuinStrategyFactory implements RuinStrategyFactory{ public class RandomRuinStrategyFactory implements RuinStrategyFactory {
private double fraction; private double fraction;

View file

@ -3,8 +3,8 @@ package jsprit.core.algorithm.ruin;
import jsprit.core.problem.job.Job; import jsprit.core.problem.job.Job;
/** /**
* Created by schroeder on 07/01/15. * Created by schroeder on 07/01/15.
*/ */
class ReferencedJob { class ReferencedJob {
private Job job; private Job job;
private double distance; private double distance;

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 {
@ -56,10 +55,10 @@ public final class RuinClusters extends AbstractRuinStrategy implements Iteratio
@Override @Override
public double[] getPoint() { public double[] getPoint() {
return new double[]{ jobActivity.getLocation().getCoordinate().getX(), jobActivity.getLocation().getCoordinate().getY() }; return new double[]{jobActivity.getLocation().getCoordinate().getX(), jobActivity.getLocation().getCoordinate().getY()};
} }
public TourActivity.JobActivity getActivity(){ public TourActivity.JobActivity getActivity() {
return jobActivity; return jobActivity;
} }
} }
@ -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,35 +115,35 @@ 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) {
Map<Job,VehicleRoute> mappedRoutes = map(vehicleRoutes); if (vrp.getJobs().values().size() == 0) return;
Map<Job, VehicleRoute> mappedRoutes = map(vehicleRoutes);
int toRemove = nOfJobs2BeRemoved; int toRemove = nOfJobs2BeRemoved;
Collection<Job> lastRemoved = new ArrayList<Job>(); Collection<Job> lastRemoved = new ArrayList<Job>();
Set<VehicleRoute> ruined = new HashSet<VehicleRoute>(); Set<VehicleRoute> ruined = new HashSet<VehicleRoute>();
Set<Job> removed = new HashSet<Job>(); Set<Job> removed = new HashSet<Job>();
Set<VehicleRoute> cycleCandidates = new HashSet<VehicleRoute>(); Set<VehicleRoute> cycleCandidates = new HashSet<VehicleRoute>();
while(toRemove > 0) { while (toRemove > 0) {
Job target; Job target;
VehicleRoute targetRoute = null; VehicleRoute targetRoute = null;
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()) {
Job j = neighborIterator.next(); Job j = neighborIterator.next();
if(!removed.contains(j) && !ruined.contains(mappedRoutes.get(j))){ if (!removed.contains(j) && !ruined.contains(mappedRoutes.get(j))) {
targetRoute = mappedRoutes.get(j); targetRoute = mappedRoutes.get(j);
break; break;
} }
} }
lastRemoved.clear(); lastRemoved.clear();
} }
if(targetRoute == null) break; if (targetRoute == null) break;
if(cycleCandidates.contains(targetRoute)) break; if (cycleCandidates.contains(targetRoute)) break;
if(ruined.contains(targetRoute)) { if (ruined.contains(targetRoute)) {
cycleCandidates.add(targetRoute); cycleCandidates.add(targetRoute);
break; break;
} }
@ -153,9 +152,9 @@ public final class RuinClusters extends AbstractRuinStrategy implements Iteratio
dbscan.setMinPts(minPts); dbscan.setMinPts(minPts);
dbscan.setEpsFactor(epsFactor); dbscan.setEpsFactor(epsFactor);
List<Job> cluster = dbscan.getRandomCluster(targetRoute); List<Job> cluster = dbscan.getRandomCluster(targetRoute);
for(Job j : cluster){ for (Job j : cluster) {
if(toRemove == 0) break; if (toRemove == 0) break;
if(removeJob(j, vehicleRoutes)) { if (removeJob(j, vehicleRoutes)) {
lastRemoved.add(j); lastRemoved.add(j);
unassignedJobs.add(j); unassignedJobs.add(j);
} }
@ -167,17 +166,17 @@ public final class RuinClusters extends AbstractRuinStrategy implements Iteratio
private List<JobActivityWrapper> wrap(List<TourActivity> activities) { private List<JobActivityWrapper> wrap(List<TourActivity> activities) {
List<JobActivityWrapper> wl = new ArrayList<JobActivityWrapper>(); List<JobActivityWrapper> wl = new ArrayList<JobActivityWrapper>();
for(TourActivity act : activities){ for (TourActivity act : activities) {
wl.add(new JobActivityWrapper((TourActivity.JobActivity) act)); wl.add(new JobActivityWrapper((TourActivity.JobActivity) act));
} }
return wl; return wl;
} }
private Map<Job, VehicleRoute> map(Collection<VehicleRoute> vehicleRoutes) { private Map<Job, VehicleRoute> map(Collection<VehicleRoute> vehicleRoutes) {
Map<Job,VehicleRoute> map = new HashMap<Job, VehicleRoute>(vrp.getJobs().size()); Map<Job, VehicleRoute> map = new HashMap<Job, VehicleRoute>(vrp.getJobs().size());
for(VehicleRoute r : vehicleRoutes){ for (VehicleRoute r : vehicleRoutes) {
for(Job j : r.getTourActivities().getJobs()){ for (Job j : r.getTourActivities().getJobs()) {
map.put(j,r); map.put(j, r);
} }
} }
return map; return map;

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