From 0717f5dd667b7828ce4a3e8fed735bb6b5d3b091 Mon Sep 17 00:00:00 2001 From: Stefan Schroeder <4sschroeder@gmail.com> Date: Tue, 10 Dec 2013 16:02:23 +0100 Subject: [PATCH] some visualization features --- jsprit-analysis/pom.xml | 15 ++ .../jsprit/analysis/toolbox/GraphStream.java | 199 ++++++++++++++++++ .../toolbox/NoLocationFoundException.java | 10 + .../java/jsprit/analysis/toolbox/Plotter.java | 18 +- .../java/jsprit/examples/SolomonExample.java | 7 +- .../jsprit/examples/SolomonOpenExample.java | 3 + .../examples/VRPWithBackhaulsExample.java | 10 +- 7 files changed, 247 insertions(+), 15 deletions(-) create mode 100644 jsprit-analysis/src/main/java/jsprit/analysis/toolbox/GraphStream.java create mode 100644 jsprit-analysis/src/main/java/jsprit/analysis/toolbox/NoLocationFoundException.java diff --git a/jsprit-analysis/pom.xml b/jsprit-analysis/pom.xml index 0f733379..5850a5e8 100644 --- a/jsprit-analysis/pom.xml +++ b/jsprit-analysis/pom.xml @@ -43,6 +43,21 @@ jar provided + + + gs-core + org.graphstream + 1.2 + false + + + + gs-ui + org.graphstream + 1.2 + false + + diff --git a/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/GraphStream.java b/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/GraphStream.java new file mode 100644 index 00000000..a0517ab0 --- /dev/null +++ b/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/GraphStream.java @@ -0,0 +1,199 @@ +package jsprit.analysis.toolbox; + +import java.util.HashMap; +import java.util.Map; + +import jsprit.core.problem.VehicleRoutingProblem; +import jsprit.core.problem.job.Job; +import jsprit.core.problem.job.Service; +import jsprit.core.problem.job.Shipment; +import jsprit.core.problem.solution.VehicleRoutingProblemSolution; +import jsprit.core.problem.solution.route.VehicleRoute; +import jsprit.core.problem.solution.route.activity.TourActivity; +import jsprit.core.problem.solution.route.activity.TourActivity.JobActivity; +import jsprit.core.problem.vehicle.Vehicle; +import jsprit.core.util.Coordinate; +import jsprit.core.util.Locations; + +import org.graphstream.graph.Graph; +import org.graphstream.graph.Node; +import org.graphstream.graph.implementations.DefaultGraph; +import org.graphstream.ui.swingViewer.Viewer; + +public class GraphStream { + + protected static String styleSheet = + "node {" + + " size: 10px, 10px;" + + " fill-color: orange;" + + " text-alignment: at-right;" + + " stroke-mode: plain;" + + " stroke-color: black;" + + + "}" + + "node.depot {" + + " fill-color: red;" + + " size: 10px, 10px;" + + " shape: box;" + + "}" + + "edge {" + + " fill-color: black;" + + "}" ; + + public static void display(VehicleRoutingProblem vrp, int renderDelay_in_ms) { + System.setProperty("org.graphstream.ui.renderer", "org.graphstream.ui.j2dviewer.J2DGraphRenderer"); + Graph g = new DefaultGraph("g"); + g.addAttribute("ui.quality"); + g.addAttribute("ui.antialias"); + g.addAttribute("ui.stylesheet", styleSheet); + + Viewer viewer = g.display(); + viewer.disableAutoLayout(); + + for(Vehicle vehicle : vrp.getVehicles()){ + renderVehicle(g, vehicle); + sleep(renderDelay_in_ms); + } + + for(Job j : vrp.getJobs().values()){ + sleep(renderDelay_in_ms); + if(j instanceof Service){ + renderService(g, j); + } + } + } + + private static void sleep(int renderDelay_in_ms) { + try { + Thread.sleep(renderDelay_in_ms); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + }; + + } + + private static void renderService(Graph g, Job j) { + Node n = g.addNode(j.getId()); + n.addAttribute("ui.label", j.getId()); + n.addAttribute("x", ((Service) j).getCoord().getX()); + n.addAttribute("y", ((Service) j).getCoord().getY()); + } + + private static void renderVehicle(Graph g, Vehicle vehicle) { + Node n = g.addNode(vehicle.getId()); + n.addAttribute("ui.label", "depot"); + n.addAttribute("x", vehicle.getCoord().getX()); + n.addAttribute("y", vehicle.getCoord().getY()); + n.setAttribute("ui.class", "depot"); + } + + public static void display(VehicleRoutingProblem vrp) { + display(vrp,0); + } + + public static void display(VehicleRoutingProblem vrp, VehicleRoutingProblemSolution solution, int renderDelay_in_ms, boolean enableAutoLayout) { + System.setProperty("org.graphstream.ui.renderer", "org.graphstream.ui.j2dviewer.J2DGraphRenderer"); + Graph g = new DefaultGraph("g"); + g.addAttribute("ui.quality"); + g.addAttribute("ui.antialias"); + g.addAttribute("ui.stylesheet", styleSheet); + + Viewer viewer = g.display(); + if(!enableAutoLayout) viewer.disableAutoLayout(); + + for(Vehicle vehicle : vrp.getVehicles()){ + renderVehicle(g,vehicle); + sleep(renderDelay_in_ms); + } + + for(Job j : vrp.getJobs().values()){ + if(j instanceof Service){ + renderService(g,(Service)j); + } + sleep(renderDelay_in_ms); + } + + int routeId = 1; + for(VehicleRoute route : solution.getRoutes()){ + renderRoute(g,route,routeId,renderDelay_in_ms); + sleep(renderDelay_in_ms); + routeId++; + } + + } + + public static void display(VehicleRoutingProblem vrp, VehicleRoutingProblemSolution solution, int renderDelay_in_ms) { + display(vrp,solution,renderDelay_in_ms,false); + } + + public static void display(VehicleRoutingProblem vrp, VehicleRoutingProblemSolution solution) { + display(vrp,solution,0,false); + } + + private static Locations retrieveLocations(VehicleRoutingProblem vrp) throws NoLocationFoundException { + final Map locs = new HashMap(); + for(Vehicle v : vrp.getVehicles()){ + String locationId = v.getLocationId(); + if(locationId == null) throw new NoLocationFoundException(); + Coordinate coord = v.getCoord(); + if(coord == null) throw new NoLocationFoundException(); + locs.put(locationId, coord); + } + for(Job j : vrp.getJobs().values()){ + if(j instanceof Service){ + String locationId = ((Service) j).getLocationId(); + if(locationId == null) throw new NoLocationFoundException(); + Coordinate coord = ((Service) j).getCoord(); + if(coord == null) throw new NoLocationFoundException(); + locs.put(locationId, coord); + } + else if(j instanceof Shipment){ + { + String locationId = ((Shipment) j).getPickupLocation(); + if(locationId == null) throw new NoLocationFoundException(); + Coordinate coord = ((Shipment) j).getPickupCoord(); + if(coord == null) throw new NoLocationFoundException(); + locs.put(locationId, coord); + } + { + String locationId = ((Shipment) j).getDeliveryLocation(); + if(locationId == null) throw new NoLocationFoundException(); + Coordinate coord = ((Shipment) j).getDeliveryCoord(); + if(coord == null) throw new NoLocationFoundException(); + locs.put(locationId, coord); + } + } + else{ + throw new IllegalStateException("job is neither a service nor a shipment. this is not supported yet."); + } + } + return new Locations() { + + @Override + public Coordinate getCoord(String id) { + return locs.get(id); + } + }; + } + + private static void renderRoute(Graph g, VehicleRoute route, int routeId, int renderDelay_in_ms) { + int vehicle_edgeId = 1; + String prevIdentifier = route.getVehicle().getId(); + for(TourActivity act : route.getActivities()){ + String currIdentifier = ((JobActivity)act).getJob().getId(); + g.addEdge(makeEdgeId(routeId,vehicle_edgeId), prevIdentifier, currIdentifier, true); + prevIdentifier = currIdentifier; + vehicle_edgeId++; + sleep(renderDelay_in_ms); + } + if(route.getVehicle().isReturnToDepot()){ + g.addEdge(makeEdgeId(routeId,vehicle_edgeId), prevIdentifier, route.getVehicle().getId(), true); + } + } + + private static String makeEdgeId(int routeId, int vehicle_edgeId) { + return Integer.valueOf(routeId).toString() + "." + Integer.valueOf(vehicle_edgeId).toString(); + } + +} diff --git a/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/NoLocationFoundException.java b/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/NoLocationFoundException.java new file mode 100644 index 00000000..4f0ee30d --- /dev/null +++ b/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/NoLocationFoundException.java @@ -0,0 +1,10 @@ +package jsprit.analysis.toolbox; + +class NoLocationFoundException extends Exception{ + + /** + * + */ + private static final long serialVersionUID = 1L; + +} diff --git a/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/Plotter.java b/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/Plotter.java index 5416755f..38e8fbcf 100644 --- a/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/Plotter.java +++ b/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/Plotter.java @@ -75,14 +75,14 @@ public class Plotter { } - private static class NoLocationFoundException extends Exception{ - - /** - * - */ - private static final long serialVersionUID = 1L; - - } +// private static class NoLocationFoundException extends Exception{ +// +// /** +// * +// */ +// private static final long serialVersionUID = 1L; +// +// } private static Logger log = Logger.getLogger(SolutionPlotter.class); @@ -504,7 +504,7 @@ public class Plotter { } } else{ - throw new IllegalStateException("job is not a service. this is not supported yet."); + throw new IllegalStateException("job is neither a service nor a shipment. this is not supported yet."); } } return new Locations() { diff --git a/jsprit-examples/src/main/java/jsprit/examples/SolomonExample.java b/jsprit-examples/src/main/java/jsprit/examples/SolomonExample.java index dbd7dad3..e2ff3702 100644 --- a/jsprit-examples/src/main/java/jsprit/examples/SolomonExample.java +++ b/jsprit-examples/src/main/java/jsprit/examples/SolomonExample.java @@ -19,6 +19,7 @@ package jsprit.examples; import java.io.File; import java.util.Collection; +import jsprit.analysis.toolbox.GraphStream; import jsprit.analysis.toolbox.Plotter; import jsprit.analysis.toolbox.SolutionPlotter; import jsprit.analysis.toolbox.SolutionPrinter; @@ -71,7 +72,7 @@ public class SolomonExample { */ // VehicleRoutingAlgorithm vra = new SchrimpfFactory().createAlgorithm(vrp); VehicleRoutingAlgorithm vra = VehicleRoutingAlgorithms.readAndCreateAlgorithm(vrp, "input/algorithmConfig_solomon.xml"); -// vra.setPrematureBreak(100); + vra.setPrematureBreak(10); // vra.getAlgorithmListeners().addListener(new AlgorithmSearchProgressChartListener("output/sol_progress.png")); /* * Solve the problem. @@ -98,7 +99,9 @@ public class SolomonExample { plotter.plot("output/solomon_C101_solution.png", "C101"); // SolutionPlotter.plotSolutionAsPNG(vrp, solution, "output/solomon_C101_solution.png","C101"); - +// GraphStream.display(vrp,100); + + GraphStream.display(vrp,solution); } diff --git a/jsprit-examples/src/main/java/jsprit/examples/SolomonOpenExample.java b/jsprit-examples/src/main/java/jsprit/examples/SolomonOpenExample.java index ae2be7ca..30fc1f49 100644 --- a/jsprit-examples/src/main/java/jsprit/examples/SolomonOpenExample.java +++ b/jsprit-examples/src/main/java/jsprit/examples/SolomonOpenExample.java @@ -19,6 +19,7 @@ package jsprit.examples; import java.io.File; import java.util.Collection; +import jsprit.analysis.toolbox.GraphStream; import jsprit.analysis.toolbox.SolutionPlotter; import jsprit.analysis.toolbox.SolutionPrinter; import jsprit.core.algorithm.VehicleRoutingAlgorithm; @@ -93,6 +94,8 @@ public class SolomonOpenExample { */ SolutionPlotter.plotSolutionAsPNG(vrp, solution, "output/solomon_C101_open_solution.png","C101"); + + GraphStream.display(vrp, solution, 50, false); } diff --git a/jsprit-examples/src/main/java/jsprit/examples/VRPWithBackhaulsExample.java b/jsprit-examples/src/main/java/jsprit/examples/VRPWithBackhaulsExample.java index 56d4e4a7..b162ab72 100644 --- a/jsprit-examples/src/main/java/jsprit/examples/VRPWithBackhaulsExample.java +++ b/jsprit-examples/src/main/java/jsprit/examples/VRPWithBackhaulsExample.java @@ -20,6 +20,7 @@ import java.io.File; import java.util.Collection; import jsprit.analysis.toolbox.AlgorithmSearchProgressChartListener; +import jsprit.analysis.toolbox.GraphStream; import jsprit.analysis.toolbox.Plotter; import jsprit.analysis.toolbox.Plotter.Label; import jsprit.analysis.toolbox.SolutionPrinter.Print; @@ -99,11 +100,12 @@ public class VRPWithBackhaulsExample { /* * Plot solution. */ - Plotter plotter = new Plotter(vrp, solution); - plotter.setLabel(Label.SIZE); - plotter.setShowFirstActivity(true); - plotter.plot("output/vrpwbh_solomon_r101_solution.png","vrpwbh_r101"); +// Plotter plotter = new Plotter(vrp, solution); +// plotter.setLabel(Label.SIZE); +// plotter.setShowFirstActivity(true); +// plotter.plot("output/vrpwbh_solomon_r101_solution.png","vrpwbh_r101"); + GraphStream.display(vrp, solution, 100, true); }