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

graph vis

This commit is contained in:
Stefan Schroeder 2014-11-14 16:38:56 +01:00
parent 6a1631fc9a
commit 006aa561cf
4 changed files with 425 additions and 54 deletions

View file

@ -0,0 +1,27 @@
package jsprit.analysis.toolbox;
import jsprit.core.algorithm.VehicleRoutingAlgorithm;
import jsprit.core.algorithm.box.GreedySchrimpfFactory;
import jsprit.core.problem.VehicleRoutingProblem;
import jsprit.core.problem.io.VrpXMLReader;
import java.io.File;
/**
* Created by stefan on 14.11.14.
*/
public class AnotherGraphTest {
public static void main(String[] args) {
VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
new VrpXMLReader(vrpBuilder).read("/Users/stefan/Documents/git-repositories/jsprit/jsprit-examples/input/cordeau01.xml");
VehicleRoutingProblem vrp = vrpBuilder.build();
// GraphStreamEventWriter eventWriter = new GraphStreamEventWriter(new File("output/events.txt"));
VehicleRoutingAlgorithm vra = new GreedySchrimpfFactory().createAlgorithm(vrp);
// vra.addListener(eventWriter);
vra.searchSolutions();
}
}

View file

@ -0,0 +1,321 @@
package jsprit.analysis.toolbox;
import jsprit.core.algorithm.listener.AlgorithmEndsListener;
import jsprit.core.algorithm.recreate.InsertionData;
import jsprit.core.algorithm.recreate.listener.BeforeJobInsertionListener;
import jsprit.core.algorithm.recreate.listener.InsertionEndsListener;
import jsprit.core.algorithm.ruin.listener.RuinListener;
import jsprit.core.problem.VehicleRoutingProblem;
import jsprit.core.problem.job.Job;
import jsprit.core.problem.job.Service;
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.vehicle.Vehicle;
import jsprit.core.problem.vehicle.VehicleImpl;
import org.graphstream.graph.Edge;
import org.graphstream.graph.Graph;
import org.graphstream.graph.Node;
import org.graphstream.graph.implementations.MultiGraph;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
* Created by stefan on 14.11.14.
*/
public class GraphStreamEventWriter implements RuinListener, BeforeJobInsertionListener, InsertionEndsListener, AlgorithmEndsListener {
static class Edges {
String inEdgeId;
String outEdgeId;
Edges(String inEdgeId, String outEdgeId) {
this.inEdgeId = inEdgeId;
this.outEdgeId = outEdgeId;
}
}
private File outfile;
private FileWriter writer;
private Map<String,Edges> in_out_edges = new HashMap<String,Edges>();
private Graph graph;
private VehicleRoutingProblem vrp;
private boolean notInitialized = true;
public GraphStreamEventWriter(VehicleRoutingProblem vrp, File outfile) {
this.outfile = outfile;
this.vrp = vrp;
graph = new MultiGraph("g");
try {
writer = new FileWriter(outfile);
writeHead();
} catch (IOException e) {
e.printStackTrace();
}
initialiseGraph(vrp);
}
public GraphStreamEventWriter(VehicleRoutingProblem vrp, VehicleRoutingProblemSolution initialSolution, File outfile) {
this.outfile = outfile;
this.vrp = vrp;
graph = new MultiGraph("g");
try {
writer = new FileWriter(outfile);
writeHead();
} catch (IOException e) {
e.printStackTrace();
}
initialiseGraph(vrp,initialSolution);
}
private void initialiseGraph(VehicleRoutingProblem vrp, VehicleRoutingProblemSolution initialSolution) {
}
@Override
public void ruinStarts(Collection<VehicleRoute> routes) {
for(VehicleRoute route : routes){
String prevNode = makeStartId(route.getVehicle());
for(TourActivity act : route.getActivities()){
String actNode = ((TourActivity.JobActivity)act).getJob().getId();
addEdge(prevNode+"_"+actNode,prevNode,actNode);
prevNode = actNode;
}
String lastNode = makeEndId(route.getVehicle());
addEdge(prevNode+"_"+lastNode,prevNode,lastNode);
}
}
private void removeNode(Node node) {
graph.removeNode(node);
String eventString = "dn " + node.getId() + "\n";
System.out.print(eventString);
try {
writer.write(eventString);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void ruinEnds(Collection<VehicleRoute> routes, Collection<Job> unassignedJobs) {
}
@Override
public void removed(Job job, VehicleRoute fromRoute) {
System.out.println("remove job " + job.getId());
String nodeId = job.getId();
Node node = graph.getNode(nodeId);
markRemoved(node);
Edge entering = node.getEnteringEdge(0);
removeEdge(entering.getId());
Edge leaving = node.getLeavingEdge(0);
removeEdge((leaving.getId()));
Node from = entering.getNode0();
Node to = leaving.getNode1();
if(!fromRoute.getActivities().isEmpty()){
addEdge(makeEdgeId(from,to),from.getId(),to.getId());
}
}
private void markRemoved(Node node) {
node.setAttribute("ui.class","removed");
try {
writer.write("cn " + node.getId() + " ui.class:removed\n");
} catch (IOException e) {
e.printStackTrace();
}
}
private String makeEdgeId(Node from, Node to) {
return from.getId() + "_" + to.getId();
}
@Override
public void informAlgorithmEnds(VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions) {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private void writeHead() throws IOException {
writer.write("DGS004\n");
writer.write("null 0 0\n");
}
private void initialiseGraph(VehicleRoutingProblem problem) {
for(Vehicle vehicle : problem.getVehicles()){
addVehicle(vehicle);
}
for(Job job : problem.getJobs().values()){
Service service = (Service)job;
addService(service);
}
}
private void addVehicle(Vehicle vehicle) {
try {
String startId = makeStartId(vehicle);
String startNodeEventString = "an " + startId + " x:" + vehicle.getStartLocationCoordinate().getX() + " y:"
+ vehicle.getStartLocationCoordinate().getY() + " ui.class:depot\n";
System.out.print(startNodeEventString);
writer.write(startNodeEventString);
graph.addNode(startId);
String endId = makeEndId(vehicle);
if(!startId.equals(endId)){
String endNodeEventString = "an " + endId + " x:" + vehicle.getEndLocationCoordinate().getX() + " y:"
+ vehicle.getEndLocationCoordinate().getY() + " ui.class:depot\n";
System.out.print(endNodeEventString);
writer.write( endNodeEventString);
graph.addNode(endId);
}
} catch (IOException e) {
e.printStackTrace();
}
}
private String makeStartId(Vehicle vehicle) {
return vehicle.getId() + "_start";
}
private String makeEndId(Vehicle vehicle) {
if(vehicle.getStartLocationId().equals(vehicle.getEndLocationId())) return makeStartId(vehicle);
return vehicle.getId() + "_end";
}
private void addService(Service service) {
try {
String eventString = "an " + service.getId() + " x:" + service.getCoord().getX() + " y:" + service.getCoord().getY() + "\n";
System.out.print(eventString);
writer.write(eventString);
graph.addNode(service.getId());
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void informInsertionEnds(Collection<VehicleRoute> vehicleRoutes) {
for(VehicleRoute route : vehicleRoutes){
String prevNode = makeStartId(route.getVehicle());
for(TourActivity act : route.getActivities()){
String actNode = ((TourActivity.JobActivity)act).getJob().getId();
removeEdge(prevNode + "_" + actNode);
prevNode = actNode;
}
String lastNode = makeEndId(route.getVehicle());
removeEdge(prevNode + "_" + lastNode);
}
}
@Override
public void informBeforeJobInsertion(Job job, InsertionData data, VehicleRoute route) {
System.out.println("insert job " + job.getId());
markInserted(job);
boolean vehicleSwitch = false;
if(!(route.getVehicle() instanceof VehicleImpl.NoVehicle)) {
if (!route.getVehicle().getId().equals(data.getSelectedVehicle().getId())) {
vehicleSwitch = true;
}
}
if(vehicleSwitch && !route.getActivities().isEmpty()){
System.out.println("switch vehicle " + route.getVehicle().getId() + " --> " + data.getSelectedVehicle().getId());
String oldStart = makeStartId(route.getVehicle());
String firstAct = ((TourActivity.JobActivity)route.getActivities().get(0)).getJob().getId();
String oldEnd = makeEndId(route.getVehicle());
String lastAct = ((TourActivity.JobActivity)route.getActivities().get(route.getActivities().size()-1)).getJob().getId();
removeEdge(oldStart + "_" + firstAct);
removeEdge(lastAct + "_" + oldEnd);
String newStart = makeStartId(data.getSelectedVehicle());
String newEnd = makeEndId(data.getSelectedVehicle());
addEdge(newStart + "_" + firstAct,newStart,firstAct);
addEdge(lastAct + "_" + newEnd, lastAct,newEnd);
}
String node_i;
if(isFirst(data,route)) {
node_i = makeStartId(data.getSelectedVehicle());
}
else {
node_i = ((TourActivity.JobActivity)route.getActivities().get(data.getDeliveryInsertionIndex()-1)).getJob().getId();
}
String node_k = job.getId();
String edgeId_1 = node_i + "_" + node_k;
String node_j;
if(isLast(data,route)) {
node_j = makeEndId(data.getSelectedVehicle());
}
else {
node_j = ((TourActivity.JobActivity)route.getActivities().get(data.getDeliveryInsertionIndex())).getJob().getId();
}
String edgeId_2 = node_k + "_" + node_j;
addEdge(edgeId_1, node_i, node_k);
addEdge(edgeId_2, node_k, node_j);
if(!route.getActivities().isEmpty()){
removeEdge(node_i + "_" + node_j);
}
}
private void markInserted(Job job) {
graph.getNode(job.getId()).removeAttribute("ui.class");
try {
writer.write("cn " + job.getId() + " -ui.class\n");
} catch (IOException e) {
e.printStackTrace();
}
}
private void removeEdge(String edgeId) {
try {
String eventString = "de " + edgeId + "\n";
System.out.print(eventString);
writer.write(eventString);
graph.removeEdge(edgeId);
} catch (IOException e) {
e.printStackTrace();
}
}
private boolean isFirst(InsertionData data, VehicleRoute route) {
return data.getDeliveryInsertionIndex() == 0;
}
private boolean isLast(InsertionData data, VehicleRoute route) {
return data.getDeliveryInsertionIndex() == route.getActivities().size();
}
private void addEdge(String edgeId, String fromNode, String toNode) {
try {
String eventString = "ae " + edgeId + " " + fromNode + " > " + toNode + "\n";
System.out.print(eventString);
writer.write(eventString);
graph.addEdge(edgeId,fromNode,toNode,true);
} catch (IOException e) {
e.printStackTrace();
}
}
}

View file

@ -27,7 +27,6 @@ import jsprit.core.problem.solution.route.activity.DeliveryActivity;
import jsprit.core.problem.solution.route.activity.PickupActivity;
import jsprit.core.problem.solution.route.activity.TourActivity;
import jsprit.core.problem.solution.route.activity.TourActivity.JobActivity;
import jsprit.core.problem.vehicle.PenaltyVehicleType;
import jsprit.core.problem.vehicle.Vehicle;
import jsprit.core.util.Time;
import org.graphstream.graph.Edge;
@ -44,7 +43,7 @@ import java.awt.*;
public class GraphStreamViewer {
protected static String styleSheet =
public static String STYLESHEET =
"node {" +
" size: 10px, 10px;" +
" fill-color: #6CC644;" +
@ -79,6 +78,13 @@ public class GraphStreamViewer {
" size: 10px, 10px;" +
" shape: box;" +
"}" +
"node.removed {" +
" fill-color: #BD2C00;" +
" size: 10px, 10px;" +
" stroke-mode: plain;" +
" stroke-color: #333;" +
" stroke-width: 2.0;" +
"}" +
"edge {" +
" fill-color: #333;" +
@ -176,56 +182,71 @@ public class GraphStreamViewer {
public void display(){
System.setProperty("org.graphstream.ui.renderer", "org.graphstream.ui.j2dviewer.J2DGraphRenderer");
JFrame jframe = new JFrame();
Graph g = createMultiGraph("g");
JPanel basicPanel = new JPanel();
basicPanel.setLayout(new BoxLayout(basicPanel, BoxLayout.Y_AXIS));
View view = createEmbeddedView(g);
//result-panel
JPanel resultPanel = createResultPanel();
//graphstream-panel
Graph g = new MultiGraph("g");
g.addAttribute("ui.quality");
g.addAttribute("ui.antialias");
g.addAttribute("ui.stylesheet", styleSheet);
JFrame jframe = createJFrame(view);
JPanel graphStreamPanel = new JPanel();
graphStreamPanel.setPreferredSize(new Dimension((int)(800*scaling),(int)(460*scaling)));
graphStreamPanel.setBackground(Color.WHITE);
JPanel graphStreamBackPanel = new JPanel();
graphStreamBackPanel.setPreferredSize(new Dimension((int)(700*scaling),(int)(450*scaling)));
graphStreamBackPanel.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY, 1));
graphStreamBackPanel.setBackground(Color.WHITE);
Viewer viewer = new Viewer(g,Viewer.ThreadingModel.GRAPH_IN_ANOTHER_THREAD);
View view = viewer.addDefaultView(false);
view.setPreferredSize(new Dimension((int)(698*scaling),(int)(440*scaling)));
graphStreamBackPanel.add(view);
graphStreamPanel.add(graphStreamBackPanel);
//setup basicPanel
basicPanel.add(resultPanel);
basicPanel.add(graphStreamPanel);
// basicPanel.add(legendPanel);
//put it together
jframe.add(basicPanel);
//conf jframe
jframe.setSize((int)(800*scaling),(int)(580*scaling));
jframe.setLocationRelativeTo(null);
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jframe.setVisible(true);
jframe.pack();
jframe.setTitle("jsprit - GraphStream");
//start rendering graph
render(g,view);
render(g,view);
}
private void render(Graph g, View view) {
public JFrame createJFrame(View view) {
JFrame jframe = new JFrame();
JPanel basicPanel = new JPanel();
basicPanel.setLayout(new BoxLayout(basicPanel, BoxLayout.Y_AXIS));
//result-panel
JPanel resultPanel = createResultPanel();
//graphstream-panel
JPanel graphStreamPanel = new JPanel();
graphStreamPanel.setPreferredSize(new Dimension((int)(800*scaling),(int)(460*scaling)));
graphStreamPanel.setBackground(Color.WHITE);
JPanel graphStreamBackPanel = new JPanel();
graphStreamBackPanel.setPreferredSize(new Dimension((int)(700*scaling),(int)(450*scaling)));
graphStreamBackPanel.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY, 1));
graphStreamBackPanel.setBackground(Color.WHITE);
graphStreamBackPanel.add(view);
graphStreamPanel.add(graphStreamBackPanel);
//setup basicPanel
basicPanel.add(resultPanel);
basicPanel.add(graphStreamPanel);
// basicPanel.add(legendPanel);
//put it together
jframe.add(basicPanel);
//conf jframe
jframe.setSize((int)(800*scaling),(int)(580*scaling));
jframe.setLocationRelativeTo(null);
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jframe.setVisible(true);
jframe.pack();
jframe.setTitle("jsprit - GraphStream");
return jframe;
}
public View createEmbeddedView(Graph g) {
Viewer viewer = new Viewer(g,Viewer.ThreadingModel.GRAPH_IN_ANOTHER_THREAD);
View view = viewer.addDefaultView(false);
view.setPreferredSize(new Dimension((int)(698*scaling),(int)(440*scaling)));
return view;
}
public Graph createMultiGraph(String name) {
Graph g = new MultiGraph(name);
g.addAttribute("ui.quality");
g.addAttribute("ui.antialias");
g.addAttribute("ui.stylesheet", STYLESHEET);
return g;
}
private void render(Graph g, View view) {
if(center != null){
view.resizeFrame(view.getWidth(), view.getHeight());
view.getCamera().setViewCenter(center.x, center.y, 0);
@ -284,7 +305,10 @@ public class GraphStreamViewer {
jobs.setFont(font);
jobs.setPreferredSize(new Dimension((int)(40*scaling),(int)(25*scaling)));
JFormattedTextField nJobs = new JFormattedTextField(this.vrp.getJobs().values().size());
int noJobs = 0;
if(this.vrp != null) noJobs = this.vrp.getJobs().values().size();
JFormattedTextField nJobs = new JFormattedTextField(noJobs);
nJobs.setFont(font);
nJobs.setEditable(false);
nJobs.setBorder(BorderFactory.createEmptyBorder());
@ -393,8 +417,7 @@ public class GraphStreamViewer {
private void renderVehicle(Graph g, Vehicle vehicle, Label label) {
String nodeId = makeId(vehicle.getId(),vehicle.getStartLocationId());
if(vehicle.getType() instanceof PenaltyVehicleType) nodeId = makeId("pen_"+vehicle.getId(),vehicle.getStartLocationId());
Node vehicleStart = g.addNode(nodeId);
Node vehicleStart = g.addNode(nodeId);
if(label.equals(Label.ID)) vehicleStart.addAttribute("ui.label", "depot");
// if(label.equals(Label.ACTIVITY)) n.addAttribute("ui.label", "start");
vehicleStart.addAttribute("x", vehicle.getStartLocationCoordinate().getX());

View file

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