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

add editorconfig - #174

This commit is contained in:
oblonski 2015-09-11 12:45:48 +02:00
commit 2a95edf129
495 changed files with 73196 additions and 73383 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,4 +1,5 @@
<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>
@ -28,7 +29,7 @@
</goals> </goals>
</pluginExecutionFilter> </pluginExecutionFilter>
<action> <action>
<ignore /> <ignore/>
</action> </action>
</pluginExecution> </pluginExecution>
</pluginExecutions> </pluginExecutions>

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,7 +15,8 @@
~ 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>
@ -26,7 +26,7 @@
<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>

View file

@ -36,8 +36,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 +56,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,24 +68,24 @@ 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();
@ -94,14 +94,14 @@ public class PrettyAlgorithmBuilder {
UpdateVehicleDependentPracticalTimeWindows tw_updater = new UpdateVehicleDependentPracticalTimeWindows(stateManager, vrp.getTransportCosts()); UpdateVehicleDependentPracticalTimeWindows tw_updater = new UpdateVehicleDependentPracticalTimeWindows(stateManager, vrp.getTransportCosts());
tw_updater.setVehiclesToUpdate(new UpdateVehicleDependentPracticalTimeWindows.VehiclesToUpdate() { tw_updater.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);
} }
} }
} }
@ -116,7 +116,7 @@ public class PrettyAlgorithmBuilder {
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));
} }
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 +124,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))
@ -150,10 +150,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,7 +85,7 @@ 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;
@ -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={}][#modules={}]", module, 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

@ -35,7 +35,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 {
@ -43,14 +42,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;
} }
} }
@ -72,14 +71,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;
} }
} }
@ -120,19 +119,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" +
@ -141,9 +140,9 @@ public class VehicleRoutingAlgorithm {
} }
} }
} }
if(nuJobs != problem.getJobs().values().size()){ if (nuJobs != problem.getJobs().values().size()) {
logger.warn("number of jobs in initial solution ({}) is not equal nuJobs in vehicle routing problem ({})" + logger.warn("number of jobs in initial solution ({}) is not equal nuJobs in vehicle routing problem ({})" +
"\n this might yield unintended effects, e.g. initial solution cannot be improved anymore.", nuJobs, problem.getJobs().values().size() ); "\n this might yield unintended effects, e.g. initial solution cannot be improved anymore.", nuJobs, problem.getJobs().values().size());
} }
} }
@ -153,7 +152,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);
} }
@ -164,7 +163,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);
} }
@ -179,7 +178,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.
@ -187,51 +186,52 @@ 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);
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);
logger.trace("discovered solution: {}", discoveredSolution); logger.trace("discovered solution: {}", 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 {} iterations", noIterationsThisAlgoIsRunning); logger.info("iterations end at {} iterations", noIterationsThisAlgoIsRunning);
addBestEver(solutions); addBestEver(solutions);
algorithmEnds(problem, solutions); algorithmEnds(problem, solutions);
logger.info("took {} seconds", ((System.currentTimeMillis()-now)/1000.0)); logger.info("took {} seconds", ((System.currentTimeMillis() - now) / 1000.0));
return solutions; return solutions;
} }
private void addBestEver(Collection<VehicleRoutingProblemSolution> solutions) { private void addBestEver(Collection<VehicleRoutingProblemSolution> solutions) {
if(bestEver != null) solutions.add(bestEver); 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) {
@ -242,14 +242,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) {

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());
@ -61,7 +61,6 @@ public class ExperimentalSchrimpfAcceptance implements SolutionAcceptor, Iterati
} }
@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,7 +89,7 @@ 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) {
@ -127,7 +125,7 @@ public class ExperimentalSchrimpfAcceptance implements SolutionAcceptor, Iterati
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,7 +136,7 @@ public class ExperimentalSchrimpfAcceptance implements SolutionAcceptor, Iterati
initialThreshold = standardDeviation / 2; initialThreshold = standardDeviation / 2;
logger.info("warmup done"); logger.info("warmup done");
logger.info("total time: {}s", ((System.currentTimeMillis()-now)/1000.0)); 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,7 +78,7 @@ 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);
@ -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();
@ -68,7 +68,7 @@ public class SchrimpfInitialThresholdGenerator implements AlgorithmStartsListene
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,7 +80,7 @@ public class SchrimpfInitialThresholdGenerator implements AlgorithmStartsListene
schrimpfAcceptance.setInitialThreshold(initialThreshold); schrimpfAcceptance.setInitialThreshold(initialThreshold);
logger.info("took {} seconds", ((System.currentTimeMillis()-now)/1000.0) ); 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,20 +540,20 @@ 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());
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

@ -70,7 +70,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 +115,7 @@ public class VehicleRoutingAlgorithms {
} }
static class SelectorKey implements AbstractKey<SolutionSelector>{ static class SelectorKey implements AbstractKey<SolutionSelector> {
private ModKey modKey; private ModKey modKey;
@ -151,7 +151,6 @@ public class VehicleRoutingAlgorithms {
} }
@Override @Override
public Class<SolutionSelector> getType() { public Class<SolutionSelector> getType() {
return SolutionSelector.class; return SolutionSelector.class;
@ -159,7 +158,7 @@ public class VehicleRoutingAlgorithms {
} }
static class StrategyModuleKey implements AbstractKey<SearchStrategyModule>{ static class StrategyModuleKey implements AbstractKey<SearchStrategyModule> {
private ModKey modKey; private ModKey modKey;
@ -195,7 +194,6 @@ public class VehicleRoutingAlgorithms {
} }
@Override @Override
public Class<SearchStrategyModule> getType() { public Class<SearchStrategyModule> getType() {
return SearchStrategyModule.class; return SearchStrategyModule.class;
@ -203,7 +201,7 @@ public class VehicleRoutingAlgorithms {
} }
static class RuinStrategyKey implements AbstractKey<RuinStrategy>{ static class RuinStrategyKey implements AbstractKey<RuinStrategy> {
private ModKey modKey; private ModKey modKey;
@ -239,7 +237,6 @@ public class VehicleRoutingAlgorithms {
} }
@Override @Override
public Class<RuinStrategy> getType() { public Class<RuinStrategy> getType() {
return RuinStrategy.class; return RuinStrategy.class;
@ -247,7 +244,7 @@ public class VehicleRoutingAlgorithms {
} }
static class InsertionStrategyKey implements AbstractKey<InsertionStrategy>{ static class InsertionStrategyKey implements AbstractKey<InsertionStrategy> {
private ModKey modKey; private ModKey modKey;
@ -283,7 +280,6 @@ public class VehicleRoutingAlgorithms {
} }
@Override @Override
public Class<InsertionStrategy> getType() { public Class<InsertionStrategy> getType() {
return InsertionStrategy.class; return InsertionStrategy.class;
@ -294,7 +290,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 +298,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 +321,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 +348,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 +358,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 +373,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 +394,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 +438,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 +454,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,7 +474,7 @@ 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();
@ -485,7 +484,7 @@ public class VehicleRoutingAlgorithms {
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 +501,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 +520,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 +536,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 +561,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 +619,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 +629,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 +641,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 +678,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 +713,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 +722,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 +767,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 +814,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 +829,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 +886,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 +896,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);
@ -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>();
@ -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("Exception", e); 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

@ -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

@ -15,8 +15,8 @@ class EventListeners {
listeners.add(new SwitchVehicleListener()); listeners.add(new SwitchVehicleListener());
} }
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);
@ -51,12 +51,12 @@ final class JobInsertionConsideringFixCostsCalculator implements JobInsertionCos
@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

@ -32,8 +32,6 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
public class JobInsertionCostsCalculatorBuilder { public class JobInsertionCostsCalculatorBuilder {
private static class CalculatorPlusListeners { private static class CalculatorPlusListeners {
@ -97,7 +95,7 @@ public class JobInsertionCostsCalculatorBuilder {
/** /**
* Constructs the builder. * Constructs the builder.
* * <p/>
* <p>Some calculators require information from the overall algorithm or the higher-level insertion procedure. Thus listeners inform them. * <p>Some calculators require information from the overall algorithm or the higher-level insertion procedure. Thus listeners inform them.
* These listeners are cached in the according list and can thus be added when its time to add them. * These listeners are cached in the according list and can thus be added when its time to add them.
* *
@ -112,11 +110,11 @@ public class JobInsertionCostsCalculatorBuilder {
/** /**
* Sets activityStates. MUST be set. * Sets activityStates. MUST be set.
* @param stateManager
* *
* @param stateManager
* @return * @return
*/ */
public JobInsertionCostsCalculatorBuilder setStateManager(RouteAndActivityStateGetter stateManager){ public JobInsertionCostsCalculatorBuilder setStateManager(RouteAndActivityStateGetter stateManager) {
this.states = stateManager; this.states = stateManager;
return this; return this;
} }
@ -127,7 +125,7 @@ public class JobInsertionCostsCalculatorBuilder {
* @param vehicleRoutingProblem * @param vehicleRoutingProblem
* @return * @return
*/ */
public JobInsertionCostsCalculatorBuilder setVehicleRoutingProblem(VehicleRoutingProblem vehicleRoutingProblem){ public JobInsertionCostsCalculatorBuilder setVehicleRoutingProblem(VehicleRoutingProblem vehicleRoutingProblem) {
this.vrp = vehicleRoutingProblem; this.vrp = vehicleRoutingProblem;
return this; return this;
} }
@ -138,24 +136,25 @@ public class JobInsertionCostsCalculatorBuilder {
* @param fleetManager * @param fleetManager
* @return * @return
*/ */
public JobInsertionCostsCalculatorBuilder setVehicleFleetManager(VehicleFleetManager fleetManager){ public JobInsertionCostsCalculatorBuilder setVehicleFleetManager(VehicleFleetManager fleetManager) {
this.fleetManager = fleetManager; this.fleetManager = fleetManager;
return this; return this;
} }
/** /**
* Sets a flag to build a calculator based on local calculations. * Sets a flag to build a calculator based on local calculations.
* * <p/>
* <p>Insertion of a job and job-activity is evaluated based on the previous and next activity. * <p>Insertion of a job and job-activity is evaluated based on the previous and next activity.
*
* @param addDefaultCostCalc * @param addDefaultCostCalc
*/ */
public JobInsertionCostsCalculatorBuilder setLocalLevel(boolean addDefaultCostCalc){ public JobInsertionCostsCalculatorBuilder setLocalLevel(boolean addDefaultCostCalc) {
local = true; local = true;
this.addDefaultCostCalc = addDefaultCostCalc; this.addDefaultCostCalc = addDefaultCostCalc;
return this; return this;
} }
public JobInsertionCostsCalculatorBuilder setActivityInsertionCostsCalculator(ActivityInsertionCostsCalculator activityInsertionCostsCalculator){ public JobInsertionCostsCalculatorBuilder setActivityInsertionCostsCalculator(ActivityInsertionCostsCalculator activityInsertionCostsCalculator) {
this.activityInsertionCostCalculator = activityInsertionCostsCalculator; this.activityInsertionCostCalculator = activityInsertionCostsCalculator;
return this; return this;
} }
@ -167,7 +166,7 @@ public class JobInsertionCostsCalculatorBuilder {
* @param memory * @param memory
* @param addDefaultMarginalCostCalc * @param addDefaultMarginalCostCalc
*/ */
public JobInsertionCostsCalculatorBuilder setRouteLevel(int forwardLooking, int memory, boolean addDefaultMarginalCostCalc){ public JobInsertionCostsCalculatorBuilder setRouteLevel(int forwardLooking, int memory, boolean addDefaultMarginalCostCalc) {
local = false; local = false;
this.forwardLooking = forwardLooking; this.forwardLooking = forwardLooking;
this.memory = memory; this.memory = memory;
@ -180,13 +179,13 @@ public class JobInsertionCostsCalculatorBuilder {
* *
* @param weightOfFixedCosts * @param weightOfFixedCosts
*/ */
public JobInsertionCostsCalculatorBuilder considerFixedCosts(double weightOfFixedCosts){ public JobInsertionCostsCalculatorBuilder considerFixedCosts(double weightOfFixedCosts) {
considerFixedCost = true; considerFixedCost = true;
this.weightOfFixedCost = weightOfFixedCosts; this.weightOfFixedCost = weightOfFixedCosts;
return this; return this;
} }
public JobInsertionCostsCalculatorBuilder experimentalTimeScheduler(double timeSlice, int neighbors){ public JobInsertionCostsCalculatorBuilder experimentalTimeScheduler(double timeSlice, int neighbors) {
timeScheduling = true; timeScheduling = true;
this.timeSlice = timeSlice; this.timeSlice = timeSlice;
this.neighbors = neighbors; this.neighbors = neighbors;
@ -199,31 +198,33 @@ public class JobInsertionCostsCalculatorBuilder {
* @return jobInsertionCalculator. * @return jobInsertionCalculator.
* @throws IllegalStateException if vrp == null or activityStates == null or fleetManager == null. * @throws IllegalStateException if vrp == null or activityStates == null or fleetManager == null.
*/ */
public JobInsertionCostsCalculator build(){ public JobInsertionCostsCalculator build() {
if(vrp == null) throw new IllegalStateException("vehicle-routing-problem is null, but it must be set (this.setVehicleRoutingProblem(vrp))"); if (vrp == null)
if(states == null) throw new IllegalStateException("states is null, but is must be set (this.setStateManager(states))"); throw new IllegalStateException("vehicle-routing-problem is null, but it must be set (this.setVehicleRoutingProblem(vrp))");
if(fleetManager == null) throw new IllegalStateException("fleetManager is null, but it must be set (this.setVehicleFleetManager(fleetManager))"); if (states == null)
throw new IllegalStateException("states is null, but is must be set (this.setStateManager(states))");
if (fleetManager == null)
throw new IllegalStateException("fleetManager is null, but it must be set (this.setVehicleFleetManager(fleetManager))");
JobInsertionCostsCalculator baseCalculator = null; JobInsertionCostsCalculator baseCalculator = null;
CalculatorPlusListeners standardLocal = null; CalculatorPlusListeners standardLocal = null;
if(local){ if (local) {
standardLocal = createStandardLocal(vrp, states); standardLocal = createStandardLocal(vrp, states);
} } else {
else{
checkServicesOnly(); checkServicesOnly();
standardLocal = createStandardRoute(vrp, states,forwardLooking,memory); standardLocal = createStandardRoute(vrp, states, forwardLooking, memory);
} }
baseCalculator = standardLocal.getCalculator(); baseCalculator = standardLocal.getCalculator();
addAlgorithmListeners(standardLocal.getAlgorithmListener()); addAlgorithmListeners(standardLocal.getAlgorithmListener());
addInsertionListeners(standardLocal.getInsertionListener()); addInsertionListeners(standardLocal.getInsertionListener());
if(considerFixedCost){ if (considerFixedCost) {
CalculatorPlusListeners withFixed = createCalculatorConsideringFixedCosts(vrp, baseCalculator, states, weightOfFixedCost); CalculatorPlusListeners withFixed = createCalculatorConsideringFixedCosts(vrp, baseCalculator, states, weightOfFixedCost);
baseCalculator = withFixed.getCalculator(); baseCalculator = withFixed.getCalculator();
addAlgorithmListeners(withFixed.getAlgorithmListener()); addAlgorithmListeners(withFixed.getAlgorithmListener());
addInsertionListeners(withFixed.getInsertionListener()); addInsertionListeners(withFixed.getInsertionListener());
} }
if(timeScheduling){ if (timeScheduling) {
// baseCalculator = new CalculatesServiceInsertionWithTimeSchedulingInSlices(baseCalculator,timeSlice,neighbors); // baseCalculator = new CalculatesServiceInsertionWithTimeSchedulingInSlices(baseCalculator,timeSlice,neighbors);
CalculatesServiceInsertionWithTimeScheduling wts = new CalculatesServiceInsertionWithTimeScheduling(baseCalculator,timeSlice,neighbors); CalculatesServiceInsertionWithTimeScheduling wts = new CalculatesServiceInsertionWithTimeScheduling(baseCalculator, timeSlice, neighbors);
CalculatorPlusListeners calcPlusListeners = new CalculatorPlusListeners(wts); CalculatorPlusListeners calcPlusListeners = new CalculatorPlusListeners(wts);
calcPlusListeners.getInsertionListener().add(new CalculatesServiceInsertionWithTimeScheduling.KnowledgeInjection(wts)); calcPlusListeners.getInsertionListener().add(new CalculatesServiceInsertionWithTimeScheduling.KnowledgeInjection(wts));
addInsertionListeners(calcPlusListeners.getInsertionListener()); addInsertionListeners(calcPlusListeners.getInsertionListener());
@ -233,8 +234,8 @@ public class JobInsertionCostsCalculatorBuilder {
} }
private void checkServicesOnly() { private void checkServicesOnly() {
for(Job j : vrp.getJobs().values()){ for (Job j : vrp.getJobs().values()) {
if(j instanceof Shipment){ if (j instanceof Shipment) {
throw new UnsupportedOperationException("currently the 'insert-on-route-level' option is only available for services (i.e. service, pickup, delivery), \n" + throw new UnsupportedOperationException("currently the 'insert-on-route-level' option is only available for services (i.e. service, pickup, delivery), \n" +
"if you want to deal with shipments switch to option 'local-level' by either setting bestInsertionBuilder.setLocalLevel() or \n" "if you want to deal with shipments switch to option 'local-level' by either setting bestInsertionBuilder.setLocalLevel() or \n"
+ "by omitting the xml-tag '<level forwardLooking=2 memory=1>route</level>' when defining your insertionStrategy in algo-config.xml file"); + "by omitting the xml-tag '<level forwardLooking=2 memory=1>route</level>' when defining your insertionStrategy in algo-config.xml file");
@ -244,26 +245,25 @@ public class JobInsertionCostsCalculatorBuilder {
} }
private void addInsertionListeners(List<InsertionListener> list) { private void addInsertionListeners(List<InsertionListener> list) {
for(InsertionListener iL : list){ for (InsertionListener iL : list) {
insertionListeners.add(iL); insertionListeners.add(iL);
} }
} }
private void addAlgorithmListeners(List<PrioritizedVRAListener> list) { private void addAlgorithmListeners(List<PrioritizedVRAListener> list) {
for(PrioritizedVRAListener aL : list){ for (PrioritizedVRAListener aL : list) {
algorithmListeners.add(aL); algorithmListeners.add(aL);
} }
} }
private CalculatorPlusListeners createStandardLocal(final VehicleRoutingProblem vrp, RouteAndActivityStateGetter statesManager){ private CalculatorPlusListeners createStandardLocal(final VehicleRoutingProblem vrp, RouteAndActivityStateGetter statesManager) {
if(constraintManager == null) throw new IllegalStateException("constraint-manager is null"); if (constraintManager == null) throw new IllegalStateException("constraint-manager is null");
ActivityInsertionCostsCalculator actInsertionCalc; ActivityInsertionCostsCalculator actInsertionCalc;
if(activityInsertionCostCalculator == null && addDefaultCostCalc){ if (activityInsertionCostCalculator == null && addDefaultCostCalc) {
actInsertionCalc = new LocalActivityInsertionCostsCalculator(vrp.getTransportCosts(), vrp.getActivityCosts()); actInsertionCalc = new LocalActivityInsertionCostsCalculator(vrp.getTransportCosts(), vrp.getActivityCosts());
} } else if (activityInsertionCostCalculator == null && !addDefaultCostCalc) {
else if(activityInsertionCostCalculator == null && !addDefaultCostCalc){ actInsertionCalc = new ActivityInsertionCostsCalculator() {
actInsertionCalc = new ActivityInsertionCostsCalculator(){
@Override @Override
public double getCosts(JobInsertionContext iContext, TourActivity prevAct, TourActivity nextAct, TourActivity newAct, public double getCosts(JobInsertionContext iContext, TourActivity prevAct, TourActivity nextAct, TourActivity newAct,
@ -272,8 +272,7 @@ public class JobInsertionCostsCalculatorBuilder {
} }
}; };
} } else {
else{
actInsertionCalc = activityInsertionCostCalculator; actInsertionCalc = activityInsertionCostCalculator;
} }
@ -299,7 +298,7 @@ public class JobInsertionCostsCalculatorBuilder {
return new CalculatorPlusListeners(switcher); return new CalculatorPlusListeners(switcher);
} }
private CalculatorPlusListeners createCalculatorConsideringFixedCosts(VehicleRoutingProblem vrp, JobInsertionCostsCalculator baseCalculator, RouteAndActivityStateGetter activityStates2, double weightOfFixedCosts){ private CalculatorPlusListeners createCalculatorConsideringFixedCosts(VehicleRoutingProblem vrp, JobInsertionCostsCalculator baseCalculator, RouteAndActivityStateGetter activityStates2, double weightOfFixedCosts) {
final JobInsertionConsideringFixCostsCalculator withFixCost = new JobInsertionConsideringFixCostsCalculator(baseCalculator, activityStates2); final JobInsertionConsideringFixCostsCalculator withFixCost = new JobInsertionConsideringFixCostsCalculator(baseCalculator, activityStates2);
withFixCost.setWeightOfFixCost(weightOfFixedCosts); withFixCost.setWeightOfFixCost(weightOfFixedCosts);
CalculatorPlusListeners calcPlusListeners = new CalculatorPlusListeners(withFixCost); CalculatorPlusListeners calcPlusListeners = new CalculatorPlusListeners(withFixCost);
@ -307,17 +306,16 @@ public class JobInsertionCostsCalculatorBuilder {
return calcPlusListeners; return calcPlusListeners;
} }
private CalculatorPlusListeners createStandardRoute(final VehicleRoutingProblem vrp, RouteAndActivityStateGetter activityStates2, int forwardLooking, int solutionMemory){ private CalculatorPlusListeners createStandardRoute(final VehicleRoutingProblem vrp, RouteAndActivityStateGetter activityStates2, int forwardLooking, int solutionMemory) {
ActivityInsertionCostsCalculator routeLevelCostEstimator; ActivityInsertionCostsCalculator routeLevelCostEstimator;
if(activityInsertionCostCalculator == null && addDefaultCostCalc){ if (activityInsertionCostCalculator == null && addDefaultCostCalc) {
RouteLevelActivityInsertionCostsEstimator routeLevelActivityInsertionCostsEstimator = new RouteLevelActivityInsertionCostsEstimator(vrp.getTransportCosts(), vrp.getActivityCosts(), activityStates2); RouteLevelActivityInsertionCostsEstimator routeLevelActivityInsertionCostsEstimator = new RouteLevelActivityInsertionCostsEstimator(vrp.getTransportCosts(), vrp.getActivityCosts(), activityStates2);
routeLevelActivityInsertionCostsEstimator.setForwardLooking(forwardLooking); routeLevelActivityInsertionCostsEstimator.setForwardLooking(forwardLooking);
routeLevelCostEstimator = routeLevelActivityInsertionCostsEstimator; routeLevelCostEstimator = routeLevelActivityInsertionCostsEstimator;
} } else if (activityInsertionCostCalculator == null && !addDefaultCostCalc) {
else if(activityInsertionCostCalculator == null && !addDefaultCostCalc){ routeLevelCostEstimator = new ActivityInsertionCostsCalculator() {
routeLevelCostEstimator = new ActivityInsertionCostsCalculator(){
final ActivityInsertionCosts noInsertionCosts = new ActivityInsertionCosts(0.,0.); final ActivityInsertionCosts noInsertionCosts = new ActivityInsertionCosts(0., 0.);
@Override @Override
public double getCosts(JobInsertionContext iContext, TourActivity prevAct, TourActivity nextAct, TourActivity newAct, public double getCosts(JobInsertionContext iContext, TourActivity prevAct, TourActivity nextAct, TourActivity newAct,
@ -326,8 +324,7 @@ public class JobInsertionCostsCalculatorBuilder {
} }
}; };
} } else {
else{
routeLevelCostEstimator = activityInsertionCostCalculator; routeLevelCostEstimator = activityInsertionCostCalculator;
} }
ServiceInsertionOnRouteLevelCalculator jobInsertionCalculator = new ServiceInsertionOnRouteLevelCalculator(vrp.getTransportCosts(), vrp.getActivityCosts(), routeLevelCostEstimator, constraintManager, constraintManager); ServiceInsertionOnRouteLevelCalculator jobInsertionCalculator = new ServiceInsertionOnRouteLevelCalculator(vrp.getTransportCosts(), vrp.getActivityCosts(), routeLevelCostEstimator, constraintManager, constraintManager);
@ -343,7 +340,7 @@ public class JobInsertionCostsCalculatorBuilder {
return new CalculatorPlusListeners(jobInsertionCalculator); return new CalculatorPlusListeners(jobInsertionCalculator);
} }
private JobInsertionCostsCalculator createFinalInsertion(VehicleFleetManager fleetManager, JobInsertionCostsCalculator baseCalc, RouteAndActivityStateGetter activityStates2){ private JobInsertionCostsCalculator createFinalInsertion(VehicleFleetManager fleetManager, JobInsertionCostsCalculator baseCalc, RouteAndActivityStateGetter activityStates2) {
VehicleTypeDependentJobInsertionCalculator vehicleTypeDependentJobInsertionCalculator = new VehicleTypeDependentJobInsertionCalculator(vrp, fleetManager, baseCalc); VehicleTypeDependentJobInsertionCalculator vehicleTypeDependentJobInsertionCalculator = new VehicleTypeDependentJobInsertionCalculator(vrp, fleetManager, baseCalc);
vehicleTypeDependentJobInsertionCalculator.setVehicleSwitchAllowed(allowVehicleSwitch); vehicleTypeDependentJobInsertionCalculator.setVehicleSwitchAllowed(allowVehicleSwitch);
return vehicleTypeDependentJobInsertionCalculator; return vehicleTypeDependentJobInsertionCalculator;

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

@ -1,4 +1,3 @@
/******************************************************************************* /*******************************************************************************
* Copyright (C) 2014 Stefan Schroeder * Copyright (C) 2014 Stefan Schroeder
* *
@ -29,13 +28,12 @@ import jsprit.core.util.CalculationUtils;
* Calculates activity insertion costs locally, i.e. by comparing the additional costs of insertion the new activity k between * Calculates activity insertion costs locally, i.e. by comparing the additional costs of insertion the new activity k between
* activity i (prevAct) and j (nextAct). * activity i (prevAct) and j (nextAct).
* Additional costs are then basically calculated as delta c = c_ik + c_kj - c_ij. * Additional costs are then basically calculated as delta c = c_ik + c_kj - c_ij.
* * <p/>
* <p>Note once time has an effect on costs this class requires activity endTimes. * <p>Note once time has an effect on costs this class requires activity endTimes.
* *
* @author stefan * @author stefan
*
*/ */
class LocalActivityInsertionCostsCalculator implements ActivityInsertionCostsCalculator{ class LocalActivityInsertionCostsCalculator implements ActivityInsertionCostsCalculator {
private VehicleRoutingTransportCosts routingCosts; private VehicleRoutingTransportCosts routingCosts;
@ -58,8 +56,8 @@ class LocalActivityInsertionCostsCalculator implements ActivityInsertionCostsCal
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());
//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;
} }
} }
@ -71,13 +69,12 @@ class LocalActivityInsertionCostsCalculator implements ActivityInsertionCostsCal
double totalCosts = tp_costs_prevAct_newAct + tp_costs_newAct_nextAct + act_costs_newAct + act_costs_nextAct; double totalCosts = tp_costs_prevAct_newAct + tp_costs_newAct_nextAct + act_costs_newAct + act_costs_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());
double arrTime_nextAct = routingCosts.getTransportTime(prevAct.getLocation(), nextAct.getLocation(), depTimeAtPrevAct, iFacts.getNewDriver(), iFacts.getNewVehicle()); double arrTime_nextAct = routingCosts.getTransportTime(prevAct.getLocation(), nextAct.getLocation(), depTimeAtPrevAct, iFacts.getNewDriver(), iFacts.getNewVehicle());
double actCost_nextAct = activityCosts.getActivityCost(nextAct, arrTime_nextAct, iFacts.getNewDriver(), iFacts.getNewVehicle()); double actCost_nextAct = activityCosts.getActivityCost(nextAct, arrTime_nextAct, iFacts.getNewDriver(), iFacts.getNewVehicle());
oldCosts = tp_costs_prevAct_nextAct + actCost_nextAct; oldCosts = tp_costs_prevAct_nextAct + actCost_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());
double arrTime_nextAct = routingCosts.getTransportTime(prevAct.getLocation(), nextAct.getLocation(), prevAct.getEndTime(), iFacts.getRoute().getDriver(), iFacts.getRoute().getVehicle()); double arrTime_nextAct = routingCosts.getTransportTime(prevAct.getLocation(), nextAct.getLocation(), prevAct.getEndTime(), iFacts.getRoute().getDriver(), iFacts.getRoute().getVehicle());
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());

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

@ -31,16 +31,15 @@ import java.util.Collection;
import java.util.List; import java.util.List;
/** /**
* 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 RegretInsertion extends AbstractInsertionStrategy { public class RegretInsertion extends AbstractInsertionStrategy {
static class ScoredJob { static class ScoredJob {
@ -96,7 +95,6 @@ public class RegretInsertion extends AbstractInsertionStrategy {
* Scorer to include other impacts on score such as time-window length or distance to depot. * Scorer to include other impacts on score such as time-window length or distance to depot.
* *
* @author schroeder * @author schroeder
*
*/ */
static interface ScoringFunction { static interface ScoringFunction {
@ -106,57 +104,58 @@ public class RegretInsertion extends AbstractInsertionStrategy {
/** /**
* Scorer that includes the length of the time-window when scoring a job. The wider the time-window, the lower the score. * Scorer that includes the length of the time-window when scoring a job. The wider the time-window, the lower the score.
* * <p/>
* <p>This is the default scorer, i.e.: score = (secondBest - firstBest) + this.TimeWindowScorer.score(job) * <p>This is the default scorer, i.e.: score = (secondBest - firstBest) + this.TimeWindowScorer.score(job)
* *
* @author schroeder * @author schroeder
*
*/ */
public static class DefaultScorer implements ScoringFunction { public static class DefaultScorer implements ScoringFunction {
private VehicleRoutingProblem vrp; private VehicleRoutingProblem vrp;
private double tw_param = - 0.5; private double tw_param = -0.5;
private double depotDistance_param = + 0.1; private double depotDistance_param = +0.1;
private double minTimeWindowScore = - 100000; private double minTimeWindowScore = -100000;
public DefaultScorer(VehicleRoutingProblem vrp) { public DefaultScorer(VehicleRoutingProblem vrp) {
this.vrp = vrp; this.vrp = vrp;
} }
public void setTimeWindowParam(double tw_param){ this.tw_param = tw_param; } public void setTimeWindowParam(double tw_param) {
this.tw_param = tw_param;
}
public void setDepotDistanceParam(double depotDistance_param){ this.depotDistance_param = depotDistance_param; } public void setDepotDistanceParam(double depotDistance_param) {
this.depotDistance_param = depotDistance_param;
}
@Override @Override
public double score(InsertionData best, Job job) { public double score(InsertionData best, Job job) {
double score; double score;
if(job instanceof Service){ if (job instanceof Service) {
score = scoreService(best, job); score = scoreService(best, job);
} } else if (job instanceof Shipment) {
else if(job instanceof Shipment){ score = scoreShipment(best, job);
score = scoreShipment(best,job); } else throw new IllegalStateException("not supported");
}
else throw new IllegalStateException("not supported");
return score; return score;
} }
private double scoreShipment(InsertionData best, Job job) { private double scoreShipment(InsertionData best, Job job) {
Shipment shipment = (Shipment)job; Shipment shipment = (Shipment) job;
double maxDepotDistance_1 = Math.max( double maxDepotDistance_1 = Math.max(
getDistance(best.getSelectedVehicle().getStartLocation(),shipment.getPickupLocation()), getDistance(best.getSelectedVehicle().getStartLocation(), shipment.getPickupLocation()),
getDistance(best.getSelectedVehicle().getStartLocation(),shipment.getDeliveryLocation()) getDistance(best.getSelectedVehicle().getStartLocation(), shipment.getDeliveryLocation())
); );
double maxDepotDistance_2 = Math.max( double maxDepotDistance_2 = Math.max(
getDistance(best.getSelectedVehicle().getEndLocation(),shipment.getPickupLocation()), getDistance(best.getSelectedVehicle().getEndLocation(), shipment.getPickupLocation()),
getDistance(best.getSelectedVehicle().getEndLocation(),shipment.getDeliveryLocation()) getDistance(best.getSelectedVehicle().getEndLocation(), shipment.getDeliveryLocation())
); );
double maxDepotDistance = Math.max(maxDepotDistance_1,maxDepotDistance_2); double maxDepotDistance = Math.max(maxDepotDistance_1, maxDepotDistance_2);
double minTimeToOperate = Math.min(shipment.getPickupTimeWindow().getEnd()-shipment.getPickupTimeWindow().getStart(), double minTimeToOperate = Math.min(shipment.getPickupTimeWindow().getEnd() - shipment.getPickupTimeWindow().getStart(),
shipment.getDeliveryTimeWindow().getEnd()-shipment.getDeliveryTimeWindow().getStart()); shipment.getDeliveryTimeWindow().getEnd() - shipment.getDeliveryTimeWindow().getStart());
return Math.max(tw_param * minTimeToOperate,minTimeWindowScore) + depotDistance_param * maxDepotDistance; return Math.max(tw_param * minTimeToOperate, minTimeWindowScore) + depotDistance_param * maxDepotDistance;
} }
private double scoreService(InsertionData best, Job job) { private double scoreService(InsertionData best, Job job) {
@ -164,18 +163,18 @@ public class RegretInsertion extends AbstractInsertionStrategy {
getDistance(best.getSelectedVehicle().getStartLocation(), ((Service) job).getLocation()), getDistance(best.getSelectedVehicle().getStartLocation(), ((Service) job).getLocation()),
getDistance(best.getSelectedVehicle().getEndLocation(), ((Service) job).getLocation()) getDistance(best.getSelectedVehicle().getEndLocation(), ((Service) job).getLocation())
); );
return Math.max(tw_param * (((Service)job).getTimeWindow().getEnd() - ((Service)job).getTimeWindow().getStart()),minTimeWindowScore) + return Math.max(tw_param * (((Service) job).getTimeWindow().getEnd() - ((Service) job).getTimeWindow().getStart()), minTimeWindowScore) +
depotDistance_param * maxDepotDistance; depotDistance_param * maxDepotDistance;
} }
private double getDistance(Location loc1, Location loc2) { private double getDistance(Location loc1, Location loc2) {
return vrp.getTransportCosts().getTransportCost(loc1,loc2,0.,null,null); return vrp.getTransportCosts().getTransportCost(loc1, loc2, 0., null, null);
} }
@Override @Override
public String toString() { public String toString() {
return "[name=defaultScorer][twParam="+tw_param+"][depotDistanceParam=" + depotDistance_param + "]"; return "[name=defaultScorer][twParam=" + tw_param + "][depotDistanceParam=" + depotDistance_param + "]";
} }
} }
@ -189,7 +188,7 @@ public class RegretInsertion 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
@ -208,15 +207,14 @@ public class RegretInsertion 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.
*
*/ */
@Override @Override
public Collection<Job> insertUnassignedJobs(Collection<VehicleRoute> routes, Collection<Job> unassignedJobs) { public Collection<Job> insertUnassignedJobs(Collection<VehicleRoute> routes, Collection<Job> unassignedJobs) {
@ -227,14 +225,14 @@ public class RegretInsertion 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 bad : badJobList) { for (Job bad : badJobList) {
jobs.remove(bad); jobs.remove(bad);
badJobs.add(bad); badJobs.add(bad);
} }
@ -245,14 +243,14 @@ public class RegretInsertion extends AbstractInsertionStrategy {
private ScoredJob nextJob(Collection<VehicleRoute> routes, List<Job> unassignedJobList, List<Job> badJobs) { private ScoredJob nextJob(Collection<VehicleRoute> routes, List<Job> unassignedJobList, List<Job> badJobs) {
ScoredJob bestScoredJob = null; ScoredJob bestScoredJob = null;
for (Job unassignedJob : unassignedJobList) { for (Job unassignedJob : unassignedJobList) {
ScoredJob scoredJob = getScoredJob(routes,unassignedJob,insertionCostsCalculator,scoringFunction); ScoredJob scoredJob = getScoredJob(routes, unassignedJob, insertionCostsCalculator, scoringFunction);
if(scoredJob instanceof BadJob){ if (scoredJob instanceof BadJob) {
badJobs.add(unassignedJob); badJobs.add(unassignedJob);
continue; continue;
} }
if(bestScoredJob == null) bestScoredJob = scoredJob; if (bestScoredJob == null) bestScoredJob = scoredJob;
else{ else {
if(scoredJob.getScore() > bestScoredJob.getScore()){ if (scoredJob.getScore() > bestScoredJob.getScore()) {
bestScoredJob = scoredJob; bestScoredJob = scoredJob;
} }
} }
@ -298,31 +296,29 @@ public class RegretInsertion extends AbstractInsertionStrategy {
secondBest = iData; secondBest = iData;
} }
} }
if(best == null){ if (best == null) {
return new RegretInsertion.BadJob(unassignedJob); return new RegretInsertion.BadJob(unassignedJob);
} }
double score = score(unassignedJob, best, secondBest, scoringFunction); double score = score(unassignedJob, best, secondBest, scoringFunction);
ScoredJob scoredJob; ScoredJob scoredJob;
if(bestRoute == emptyRoute){ if (bestRoute == emptyRoute) {
scoredJob = new ScoredJob(unassignedJob, score, best, bestRoute, true); scoredJob = new ScoredJob(unassignedJob, score, best, bestRoute, true);
} } else scoredJob = new ScoredJob(unassignedJob, score, best, bestRoute, false);
else scoredJob = new ScoredJob(unassignedJob, score, best, bestRoute, false);
return scoredJob; return scoredJob;
} }
static double score(Job unassignedJob, InsertionData best, InsertionData secondBest, ScoringFunction scoringFunction) { static double score(Job unassignedJob, InsertionData best, InsertionData secondBest, ScoringFunction scoringFunction) {
if(best == null){ if (best == null) {
throw new IllegalStateException("cannot insert job " + unassignedJob.getId()); throw new IllegalStateException("cannot insert job " + unassignedJob.getId());
} }
double score; double score;
if(secondBest == null){ //either there is only one vehicle or there are more vehicles, but they cannot load unassignedJob if (secondBest == null) { //either there is only one vehicle or there are more vehicles, but they cannot load unassignedJob
//if only one vehicle, I want the job to be inserted with min iCosts //if only one vehicle, I want the job to be inserted with min iCosts
//if there are more vehicles, I want this job to be prioritized since there are no alternatives //if there are more vehicles, I want this job to be prioritized since there are no alternatives
score = Integer.MAX_VALUE - best.getInsertionCost() + scoringFunction.score(best, unassignedJob); score = Integer.MAX_VALUE - best.getInsertionCost() + scoringFunction.score(best, unassignedJob);
} } else {
else{ score = (secondBest.getInsertionCost() - best.getInsertionCost()) + scoringFunction.score(best, unassignedJob);
score = (secondBest.getInsertionCost()-best.getInsertionCost()) + scoringFunction.score(best, unassignedJob);
} }
return score; return score;
} }

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);
@ -73,7 +72,7 @@ final class ServiceInsertionCalculator implements JobInsertionCostsCalculator{
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,15 +66,15 @@ 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) {
@ -96,7 +94,7 @@ final class ServiceInsertionOnRouteLevelCalculator implements JobInsertionCostsC
} }
public void setStates(RouteAndActivityStateGetter stateManager){ public void setStates(RouteAndActivityStateGetter stateManager) {
this.stateManager = stateManager; this.stateManager = stateManager;
} }
@ -107,7 +105,7 @@ final class ServiceInsertionOnRouteLevelCalculator implements JobInsertionCostsC
@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);
@ -71,7 +69,7 @@ final class ShipmentInsertionCalculator implements JobInsertionCostsCalculator{
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: {}, act-size: {}", i, 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

@ -3,13 +3,13 @@ package jsprit.core.algorithm.recreate;
/** /**
* Created by schroeder on 19/05/15. * Created by schroeder on 19/05/15.
*/ */
class SwitchVehicleListener implements EventListener{ class SwitchVehicleListener implements EventListener {
@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;
switchVehicle.getRoute().setVehicleAndDepartureTime(switchVehicle.getVehicle(),((SwitchVehicle) event).getDepartureTime()); switchVehicle.getRoute().setVehicleAndDepartureTime(switchVehicle.getVehicle(), ((SwitchVehicle) event).getDepartureTime());
} }
} }
} }

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; 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

@ -16,8 +16,8 @@ import org.apache.commons.math3.ml.distance.DistanceMeasure;
import java.util.*; import java.util.*;
/** /**
* Created by schroeder on 04/02/15. * Created by schroeder on 04/02/15.
*/ */
public class DBSCANClusterer { public class DBSCANClusterer {
private static class LocationWrapper implements Clusterable { private static class LocationWrapper implements Clusterable {
@ -37,12 +37,11 @@ public class DBSCANClusterer {
this.id = objCounter; this.id = objCounter;
} }
private List<Location> getLocations(Job job){ private List<Location> getLocations(Job job) {
List<Location> locs = new ArrayList<Location>(); List<Location> locs = new ArrayList<Location>();
if(job instanceof Service) { if (job instanceof Service) {
locs.add(((Service) job).getLocation()); locs.add(((Service) job).getLocation());
} } else if (job instanceof Shipment) {
else if(job instanceof Shipment){
locs.add(((Shipment) job).getPickupLocation()); locs.add(((Shipment) job).getPickupLocation());
locs.add(((Shipment) job).getDeliveryLocation()); locs.add(((Shipment) job).getDeliveryLocation());
} }
@ -55,7 +54,7 @@ public class DBSCANClusterer {
@Override @Override
public double[] getPoint() { public double[] getPoint() {
return new double[]{ id }; return new double[]{id};
} }
public Job getJob() { public Job getJob() {
@ -65,31 +64,31 @@ public class DBSCANClusterer {
private static class MyDistance implements DistanceMeasure { private static class MyDistance implements DistanceMeasure {
private Map<Integer,LocationWrapper> locations; private Map<Integer, LocationWrapper> locations;
private VehicleRoutingTransportCosts costs; private VehicleRoutingTransportCosts costs;
public MyDistance(List<LocationWrapper> locations, VehicleRoutingTransportCosts costs) { public MyDistance(List<LocationWrapper> locations, VehicleRoutingTransportCosts costs) {
this.locations = new HashMap<Integer, LocationWrapper>(); this.locations = new HashMap<Integer, LocationWrapper>();
for(LocationWrapper lw : locations){ for (LocationWrapper lw : locations) {
this.locations.put((int)lw.getPoint()[0],lw); this.locations.put((int) lw.getPoint()[0], lw);
} }
this.costs = costs; this.costs = costs;
} }
@Override @Override
public double compute(double[] doubles, double[] doubles1) { public double compute(double[] doubles, double[] doubles1) {
LocationWrapper l1 = locations.get((int)doubles[0]); LocationWrapper l1 = locations.get((int) doubles[0]);
LocationWrapper l2 = locations.get((int)doubles1[0]); LocationWrapper l2 = locations.get((int) doubles1[0]);
int count = 0; int count = 0;
double sum = 0; double sum = 0;
for(Location loc_1 : l1.getLocations()){ for (Location loc_1 : l1.getLocations()) {
for(Location loc_2 : l2.getLocations()){ for (Location loc_2 : l2.getLocations()) {
sum += costs.getTransportCost(loc_1,loc_2,0,null,null); sum += costs.getTransportCost(loc_1, loc_2, 0, null, null);
count++; count++;
} }
} }
return sum / (double)count; return sum / (double) count;
} }
} }
@ -113,21 +112,21 @@ public class DBSCANClusterer {
this.costs = costs; this.costs = costs;
} }
public void setMinPts(int pts){ public void setMinPts(int pts) {
this.minNoOfJobsInCluster = pts; this.minNoOfJobsInCluster = pts;
} }
public void setEpsFactor(double epsFactor){ public void setEpsFactor(double epsFactor) {
this.epsFactor = epsFactor; this.epsFactor = epsFactor;
} }
public void setEpsDistance(double epsDistance){ public void setEpsDistance(double epsDistance) {
this.epsDistance = epsDistance; this.epsDistance = epsDistance;
} }
public List<List<Job>> getClusters(VehicleRoute route){ public List<List<Job>> getClusters(VehicleRoute route) {
List<LocationWrapper> locations = new ArrayList<LocationWrapper>(route.getTourActivities().getJobs().size()); List<LocationWrapper> locations = new ArrayList<LocationWrapper>(route.getTourActivities().getJobs().size());
for(Job j : route.getTourActivities().getJobs()){ for (Job j : route.getTourActivities().getJobs()) {
locations.add(new LocationWrapper(j)); locations.add(new LocationWrapper(j));
} }
List<Cluster<LocationWrapper>> clusterResults = getClusters(route, locations); List<Cluster<LocationWrapper>> clusterResults = getClusters(route, locations);
@ -136,15 +135,15 @@ public class DBSCANClusterer {
private List<Cluster<LocationWrapper>> getClusters(VehicleRoute route, List<LocationWrapper> locations) { private List<Cluster<LocationWrapper>> getClusters(VehicleRoute route, List<LocationWrapper> locations) {
double sampledDistance; double sampledDistance;
if(epsDistance != null) sampledDistance = epsDistance; if (epsDistance != null) sampledDistance = epsDistance;
else sampledDistance = Math.max(0, sample(costs, route)); else sampledDistance = Math.max(0, sample(costs, route));
org.apache.commons.math3.ml.clustering.DBSCANClusterer<LocationWrapper> clusterer = new org.apache.commons.math3.ml.clustering.DBSCANClusterer<LocationWrapper>(sampledDistance, minNoOfJobsInCluster, new MyDistance(locations,costs)); org.apache.commons.math3.ml.clustering.DBSCANClusterer<LocationWrapper> clusterer = new org.apache.commons.math3.ml.clustering.DBSCANClusterer<LocationWrapper>(sampledDistance, minNoOfJobsInCluster, new MyDistance(locations, costs));
return clusterer.cluster(locations); return clusterer.cluster(locations);
} }
private List<List<Job>> makeList(List<Cluster<LocationWrapper>> clusterResults) { private List<List<Job>> makeList(List<Cluster<LocationWrapper>> clusterResults) {
List<List<Job>> l = new ArrayList<List<Job>>(); List<List<Job>> l = new ArrayList<List<Job>>();
for(Cluster<LocationWrapper> c : clusterResults){ for (Cluster<LocationWrapper> c : clusterResults) {
List<Job> l_ = getJobList(c); List<Job> l_ = getJobList(c);
l.add(l_); l.add(l_);
} }
@ -153,21 +152,21 @@ public class DBSCANClusterer {
private List<Job> getJobList(Cluster<LocationWrapper> c) { private List<Job> getJobList(Cluster<LocationWrapper> c) {
List<Job> l_ = new ArrayList<Job>(); List<Job> l_ = new ArrayList<Job>();
if(c == null) return l_; if (c == null) return l_;
for(LocationWrapper lw : c.getPoints()){ for (LocationWrapper lw : c.getPoints()) {
l_.add(lw.getJob()); l_.add(lw.getJob());
} }
return l_; return l_;
} }
public List<Job> getRandomCluster(VehicleRoute route){ public List<Job> getRandomCluster(VehicleRoute route) {
if(route.isEmpty()) return Collections.emptyList(); if (route.isEmpty()) return Collections.emptyList();
List<LocationWrapper> locations = new ArrayList<LocationWrapper>(route.getTourActivities().getJobs().size()); List<LocationWrapper> locations = new ArrayList<LocationWrapper>(route.getTourActivities().getJobs().size());
for(Job j : route.getTourActivities().getJobs()){ for (Job j : route.getTourActivities().getJobs()) {
locations.add(new LocationWrapper(j)); locations.add(new LocationWrapper(j));
} }
List<Cluster<LocationWrapper>> clusterResults = getClusters(route,locations); List<Cluster<LocationWrapper>> clusterResults = getClusters(route, locations);
if(clusterResults.isEmpty()) return Collections.emptyList(); if (clusterResults.isEmpty()) return Collections.emptyList();
Cluster<LocationWrapper> randomCluster = RandomUtils.nextItem(clusterResults, random); Cluster<LocationWrapper> randomCluster = RandomUtils.nextItem(clusterResults, random);
return getJobList(randomCluster); return getJobList(randomCluster);
} }
@ -175,15 +174,15 @@ public class DBSCANClusterer {
private double sample(VehicleRoutingTransportCosts costs, VehicleRoute r) { private double sample(VehicleRoutingTransportCosts costs, VehicleRoute r) {
double min = Double.MAX_VALUE; double min = Double.MAX_VALUE;
double sum = 0; double sum = 0;
for(int i=0;i<noDistanceSamples;i++){ for (int i = 0; i < noDistanceSamples; i++) {
TourActivity act1 = RandomUtils.nextItem(r.getActivities(), random); TourActivity act1 = RandomUtils.nextItem(r.getActivities(), random);
TourActivity act2 = RandomUtils.nextItem(r.getActivities(), random); TourActivity act2 = RandomUtils.nextItem(r.getActivities(), random);
double dist = costs.getTransportCost(act1.getLocation(), act2.getLocation(), double dist = costs.getTransportCost(act1.getLocation(), act2.getLocation(),
0., null, r.getVehicle()); 0., null, r.getVehicle());
if(dist < min) min = dist; if (dist < min) min = dist;
sum += dist; sum += dist;
} }
double avg = sum / ((double)noDistanceSamples); double avg = sum / ((double) noDistanceSamples);
return (avg - min) * epsFactor; return (avg - min) * epsFactor;
} }

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);
@ -30,9 +30,9 @@ class JobNeighborhoodsImpl implements JobNeighborhoods {
} }
@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);
@ -87,7 +87,7 @@ class JobNeighborhoodsImpl implements JobNeighborhoods {
} }
stopWatch.stop(); stopWatch.stop();
logger.debug("preprocessing comp-time: {}; nuOfDistances stored: {}; estimated memory: {}" + logger.debug("preprocessing comp-time: {}; nuOfDistances stored: {}; estimated memory: {}" +
" bytes", stopWatch, nuOfDistancesStored, (distanceNodeTree.keySet().size()*64+nuOfDistancesStored*92) ); " 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);
@ -33,9 +33,9 @@ class JobNeighborhoodsImplWithCapRestriction implements JobNeighborhoods {
} }
@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={} calculations, but 'only' {} are cached.", Math.pow(vrp.getJobs().values().size(), 2), (vrp.getJobs().values().size()*capacity)); 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);
} }
@ -102,12 +101,12 @@ class JobNeighborhoodsImplWithCapRestriction implements JobNeighborhoods {
} }
stopWatch.stop(); stopWatch.stop();
logger.debug("preprocessing comp-time: {}; nuOfDistances stored: {}; estimated memory: {}" + logger.debug("preprocessing comp-time: {}; nuOfDistances stored: {}; estimated memory: {}" +
" bytes", stopWatch, nuOfDistancesStored, (distanceNodeTree.keySet().size()*64+nuOfDistancesStored*92)); " 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

@ -28,13 +28,11 @@ import java.util.*;
/** /**
*
* RuinStrategy that ruins the neighborhood of a randomly selected job. The size and the structure of the neighborhood is defined by * RuinStrategy that ruins the neighborhood of a randomly selected job. The size and the structure of the neighborhood is defined by
* the share of jobs to be removed and the distance between jobs (where distance not necessarily mean Euclidean distance but an arbitrary * the share of jobs to be removed and the distance between jobs (where distance not necessarily mean Euclidean distance but an arbitrary
* measure). * measure).
* *
* @author stefan * @author stefan
*
*/ */
public final class RuinRadial extends AbstractRuinStrategy { public final class RuinRadial extends AbstractRuinStrategy {
@ -56,7 +54,7 @@ public final class RuinRadial extends AbstractRuinStrategy {
public RuinRadial(VehicleRoutingProblem vrp, double fraction2beRemoved, JobDistance jobDistance) { public RuinRadial(VehicleRoutingProblem vrp, double fraction2beRemoved, JobDistance jobDistance) {
super(vrp); super(vrp);
this.vrp = vrp; this.vrp = vrp;
noJobsToMemorize = (int) Math.ceil(vrp.getJobs().values().size()*fraction2beRemoved); noJobsToMemorize = (int) Math.ceil(vrp.getJobs().values().size() * fraction2beRemoved);
ruinShareFactory = new RuinShareFactory() { ruinShareFactory = new RuinShareFactory() {
@Override @Override
@ -108,7 +106,7 @@ public final class RuinRadial extends AbstractRuinStrategy {
@Override @Override
public String toString() { public String toString() {
return "[name=radialRuin][noJobsToBeRemoved="+noJobsToMemorize+"]"; return "[name=radialRuin][noJobsToBeRemoved=" + noJobsToMemorize + "]";
} }
/** /**
@ -117,31 +115,32 @@ public final class RuinRadial extends AbstractRuinStrategy {
*/ */
@Override @Override
public Collection<Job> ruinRoutes(Collection<VehicleRoute> vehicleRoutes) { public Collection<Job> ruinRoutes(Collection<VehicleRoute> vehicleRoutes) {
if(vehicleRoutes.isEmpty()){ if (vehicleRoutes.isEmpty()) {
return Collections.emptyList(); return Collections.emptyList();
} }
int nOfJobs2BeRemoved = Math.min(ruinShareFactory.createNumberToBeRemoved(), noJobsToMemorize); int nOfJobs2BeRemoved = Math.min(ruinShareFactory.createNumberToBeRemoved(), noJobsToMemorize);
if (nOfJobs2BeRemoved == 0) { if (nOfJobs2BeRemoved == 0) {
return Collections.emptyList(); return Collections.emptyList();
} }
Job randomJob = RandomUtils.nextJob(vrp.getJobs().values(),random); Job randomJob = RandomUtils.nextJob(vrp.getJobs().values(), random);
return ruinRoutes(vehicleRoutes, randomJob, nOfJobs2BeRemoved); return ruinRoutes(vehicleRoutes, randomJob, nOfJobs2BeRemoved);
} }
/** /**
* Removes targetJob and its neighborhood and returns the removed jobs. * Removes targetJob and its neighborhood and returns the removed jobs.
*
* @deprecated will be private * @deprecated will be private
*/ */
@Deprecated @Deprecated
public Collection<Job> ruinRoutes(Collection<VehicleRoute> vehicleRoutes, Job targetJob, int nOfJobs2BeRemoved){ public Collection<Job> ruinRoutes(Collection<VehicleRoute> vehicleRoutes, Job targetJob, int nOfJobs2BeRemoved) {
List<Job> unassignedJobs = new ArrayList<Job>(); List<Job> unassignedJobs = new ArrayList<Job>();
int nNeighbors = nOfJobs2BeRemoved - 1; int nNeighbors = nOfJobs2BeRemoved - 1;
removeJob(targetJob,vehicleRoutes); removeJob(targetJob, vehicleRoutes);
unassignedJobs.add(targetJob); unassignedJobs.add(targetJob);
Iterator<Job> neighborhoodIterator = jobNeighborhoods.getNearestNeighborsIterator(nNeighbors, targetJob); Iterator<Job> neighborhoodIterator = jobNeighborhoods.getNearestNeighborsIterator(nNeighbors, targetJob);
while(neighborhoodIterator.hasNext()){ while (neighborhoodIterator.hasNext()) {
Job job = neighborhoodIterator.next(); Job job = neighborhoodIterator.next();
if(removeJob(job,vehicleRoutes)){ if (removeJob(job, vehicleRoutes)) {
unassignedJobs.add(job); unassignedJobs.add(job);
} }
} }

View file

@ -27,13 +27,11 @@ import java.util.*;
/** /**
*
* RuinStrategy that ruins the neighborhood of a randomly selected job. The size and the structure of the neighborhood is defined by * RuinStrategy that ruins the neighborhood of a randomly selected job. The size and the structure of the neighborhood is defined by
* the share of jobs to be removed and the distance between jobs (where distance not necessarily mean Euclidean distance but an arbitrary * the share of jobs to be removed and the distance between jobs (where distance not necessarily mean Euclidean distance but an arbitrary
* measure). * measure).
* *
* @author stefan * @author stefan
*
*/ */
public final class RuinRadialMultipleCenters extends AbstractRuinStrategy { public final class RuinRadialMultipleCenters extends AbstractRuinStrategy {
@ -65,13 +63,13 @@ public final class RuinRadialMultipleCenters extends AbstractRuinStrategy {
logger.debug("initialise {}", this); logger.debug("initialise {}", this);
} }
public void setNumberOfRuinCenters(int noCenters){ public void setNumberOfRuinCenters(int noCenters) {
this.noCenters = noCenters; this.noCenters = noCenters;
} }
@Override @Override
public String toString() { public String toString() {
return "[name=radialRuin][noJobsToBeRemoved="+noJobsToMemorize+"]"; return "[name=radialRuin][noJobsToBeRemoved=" + noJobsToMemorize + "]";
} }
/** /**
@ -80,18 +78,18 @@ public final class RuinRadialMultipleCenters extends AbstractRuinStrategy {
*/ */
@Override @Override
public Collection<Job> ruinRoutes(Collection<VehicleRoute> vehicleRoutes) { public Collection<Job> ruinRoutes(Collection<VehicleRoute> vehicleRoutes) {
if(vehicleRoutes.isEmpty()){ if (vehicleRoutes.isEmpty()) {
return Collections.emptyList(); return Collections.emptyList();
} }
Set<Job> available = new HashSet<Job>(vrp.getJobs().values()); Set<Job> available = new HashSet<Job>(vrp.getJobs().values());
Collection<Job> ruined = new ArrayList<Job>(); Collection<Job> ruined = new ArrayList<Job>();
for(int center=0;center<noCenters;center++) { for (int center = 0; center < noCenters; center++) {
int nOfJobs2BeRemoved = ruinShareFactory.createNumberToBeRemoved(); int nOfJobs2BeRemoved = ruinShareFactory.createNumberToBeRemoved();
if (nOfJobs2BeRemoved == 0) { if (nOfJobs2BeRemoved == 0) {
return Collections.emptyList(); return Collections.emptyList();
} }
Job randomJob = pickRandomJob(available); Job randomJob = pickRandomJob(available);
if(randomJob != null) { if (randomJob != null) {
ruined.addAll(ruinRoutes_(vehicleRoutes, randomJob, nOfJobs2BeRemoved, available)); ruined.addAll(ruinRoutes_(vehicleRoutes, randomJob, nOfJobs2BeRemoved, available));
} }
} }
@ -100,23 +98,24 @@ public final class RuinRadialMultipleCenters extends AbstractRuinStrategy {
/** /**
* Removes targetJob and its neighborhood and returns the removed jobs. * Removes targetJob and its neighborhood and returns the removed jobs.
*
* @deprecated will be private * @deprecated will be private
*/ */
@Deprecated @Deprecated
public Collection<Job> ruinRoutes(Collection<VehicleRoute> vehicleRoutes, Job targetJob, int nOfJobs2BeRemoved){ public Collection<Job> ruinRoutes(Collection<VehicleRoute> vehicleRoutes, Job targetJob, int nOfJobs2BeRemoved) {
return ruinRoutes_(vehicleRoutes,targetJob,nOfJobs2BeRemoved,null); return ruinRoutes_(vehicleRoutes, targetJob, nOfJobs2BeRemoved, null);
} }
private Collection<Job> ruinRoutes_(Collection<VehicleRoute> vehicleRoutes, Job targetJob, int nOfJobs2BeRemoved, Set<Job> available){ private Collection<Job> ruinRoutes_(Collection<VehicleRoute> vehicleRoutes, Job targetJob, int nOfJobs2BeRemoved, Set<Job> available) {
List<Job> unassignedJobs = new ArrayList<Job>(); List<Job> unassignedJobs = new ArrayList<Job>();
int nNeighbors = nOfJobs2BeRemoved - 1; int nNeighbors = nOfJobs2BeRemoved - 1;
removeJob(targetJob,vehicleRoutes); removeJob(targetJob, vehicleRoutes);
unassignedJobs.add(targetJob); unassignedJobs.add(targetJob);
Iterator<Job> neighborhoodIterator = jobNeighborhoods.getNearestNeighborsIterator(nNeighbors, targetJob); Iterator<Job> neighborhoodIterator = jobNeighborhoods.getNearestNeighborsIterator(nNeighbors, targetJob);
while(neighborhoodIterator.hasNext()){ while (neighborhoodIterator.hasNext()) {
Job job = neighborhoodIterator.next(); Job job = neighborhoodIterator.next();
if(available!=null) available.remove(job); if (available != null) available.remove(job);
if(removeJob(job,vehicleRoutes)) { if (removeJob(job, vehicleRoutes)) {
unassignedJobs.add(job); unassignedJobs.add(job);
} }
} }
@ -125,12 +124,11 @@ public final class RuinRadialMultipleCenters extends AbstractRuinStrategy {
private Job pickRandomJob(Set<Job> available) { private Job pickRandomJob(Set<Job> available) {
int randomIndex = random.nextInt(available.size()); int randomIndex = random.nextInt(available.size());
int i=0; int i = 0;
for(Job j : available){ for (Job j : available) {
if(i>=randomIndex) { if (i >= randomIndex) {
return j; return j;
} } else i++;
else i++;
} }
return null; return null;
} }

View file

@ -33,7 +33,6 @@ import java.util.List;
* customer are removed randomly from current solution. * customer are removed randomly from current solution.
* *
* @author stefan schroeder * @author stefan schroeder
*
*/ */
public final class RuinRandom extends AbstractRuinStrategy { public final class RuinRandom extends AbstractRuinStrategy {
@ -65,7 +64,7 @@ public final class RuinRandom extends AbstractRuinStrategy {
/** /**
* 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
@ -86,11 +85,11 @@ public final class RuinRandom extends AbstractRuinStrategy {
private void ruin(Collection<VehicleRoute> vehicleRoutes, int nOfJobs2BeRemoved, List<Job> unassignedJobs) { private void ruin(Collection<VehicleRoute> vehicleRoutes, int nOfJobs2BeRemoved, List<Job> unassignedJobs) {
ArrayList<Job> availableJobs = new ArrayList<Job>(vrp.getJobs().values()); ArrayList<Job> availableJobs = new ArrayList<Job>(vrp.getJobs().values());
Collections.shuffle(availableJobs,random); Collections.shuffle(availableJobs, random);
int removed = 0; int removed = 0;
for (Job job : availableJobs) { for (Job job : availableJobs) {
if(removed == nOfJobs2BeRemoved) break; if (removed == nOfJobs2BeRemoved) break;
if(removeJob(job,vehicleRoutes)) { if (removeJob(job, vehicleRoutes)) {
unassignedJobs.add(job); unassignedJobs.add(job);
} }
removed++; removed++;
@ -99,7 +98,7 @@ public final class RuinRandom extends AbstractRuinStrategy {
@Override @Override
public String toString() { public String toString() {
return "[name=randomRuin][noJobsToBeRemoved="+selectNuOfJobs2BeRemoved()+"]"; return "[name=randomRuin][noJobsToBeRemoved=" + selectNuOfJobs2BeRemoved() + "]";
} }
private int selectNuOfJobs2BeRemoved() { private int selectNuOfJobs2BeRemoved() {

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