mirror of
https://github.com/graphhopper/jsprit.git
synced 2020-01-24 07:45:05 +01:00
vis
This commit is contained in:
parent
9c857962d6
commit
b702c8015b
2 changed files with 394 additions and 57 deletions
|
|
@ -24,14 +24,15 @@ import jsprit.core.algorithm.recreate.listener.BeforeJobInsertionListener;
|
|||
import jsprit.core.algorithm.recreate.listener.InsertionEndsListener;
|
||||
import jsprit.core.algorithm.recreate.listener.InsertionStartsListener;
|
||||
import jsprit.core.algorithm.ruin.listener.RuinListener;
|
||||
import jsprit.core.problem.AbstractActivity;
|
||||
import jsprit.core.problem.VehicleRoutingProblem;
|
||||
import jsprit.core.problem.job.Job;
|
||||
import jsprit.core.problem.job.Service;
|
||||
import jsprit.core.problem.job.*;
|
||||
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 jsprit.core.util.Coordinate;
|
||||
import jsprit.core.util.Solutions;
|
||||
import org.graphstream.graph.Edge;
|
||||
import org.graphstream.graph.Graph;
|
||||
|
|
@ -43,11 +44,19 @@ import java.io.File;
|
|||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class AlgorithmEventRecorder implements RuinListener, IterationStartsListener, InsertionStartsListener, BeforeJobInsertionListener, InsertionEndsListener, AlgorithmEndsListener {
|
||||
|
||||
private boolean renderShipments = false;
|
||||
|
||||
public static void writeSolution(VehicleRoutingProblem vrp, VehicleRoutingProblemSolution solution, File outfile){
|
||||
AlgorithmEventRecorder rec = new AlgorithmEventRecorder(vrp,outfile);
|
||||
rec.initialiseGraph(vrp);
|
||||
rec.addRoutes(solution.getRoutes());
|
||||
rec.finish();
|
||||
}
|
||||
|
||||
public static enum RecordPolicy {
|
||||
RECORD_AND_WRITE
|
||||
|
|
@ -75,7 +84,10 @@ public class AlgorithmEventRecorder implements RuinListener, IterationStartsList
|
|||
|
||||
private int currentIteration = 0;
|
||||
|
||||
private VehicleRoutingProblem vrp;
|
||||
|
||||
public AlgorithmEventRecorder(VehicleRoutingProblem vrp, File outfile) {
|
||||
this.vrp = vrp;
|
||||
graph = new MultiGraph("g");
|
||||
try {
|
||||
writer = new FileWriter(outfile);
|
||||
|
|
@ -88,6 +100,11 @@ public class AlgorithmEventRecorder implements RuinListener, IterationStartsList
|
|||
initialiseGraph(vrp);
|
||||
}
|
||||
|
||||
public AlgorithmEventRecorder(VehicleRoutingProblem vrp, File outfile, boolean renderShipments) {
|
||||
this.renderShipments = renderShipments;
|
||||
new AlgorithmEventRecorder(vrp,outfile);
|
||||
}
|
||||
|
||||
public void setRecordingRange(int startIteration, int endIteration){
|
||||
this.start_recording_at = startIteration;
|
||||
this.end_recording_at = endIteration;
|
||||
|
|
@ -114,23 +131,41 @@ public class AlgorithmEventRecorder implements RuinListener, IterationStartsList
|
|||
public void ruinStarts(Collection<VehicleRoute> routes) {
|
||||
if(!record()) return;
|
||||
fileSink.stepBegins(graph.getId(),0,BEFORE_RUIN_RENDER_SOLUTION);
|
||||
recordRoutes(routes);
|
||||
addRoutes(routes);
|
||||
fileSink.stepBegins(graph.getId(),0,RUIN);
|
||||
}
|
||||
|
||||
private void recordRoutes(Collection<VehicleRoute> routes) {
|
||||
private void addRoutes(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 actNodeId = getNodeId(act);
|
||||
addEdge(prevNode+"_"+actNodeId,prevNode,actNodeId);
|
||||
prevNode = actNodeId;
|
||||
}
|
||||
String lastNode = makeEndId(route.getVehicle());
|
||||
addEdge(prevNode+"_"+lastNode,prevNode,lastNode);
|
||||
if(route.getVehicle().isReturnToDepot()) {
|
||||
String lastNode = makeEndId(route.getVehicle());
|
||||
addEdge(prevNode+"_"+lastNode,prevNode,lastNode);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private String getNodeId(TourActivity act) {
|
||||
String nodeId = null;
|
||||
if(act instanceof TourActivity.JobActivity){
|
||||
Job job = ((TourActivity.JobActivity) act).getJob();
|
||||
if(job instanceof Service){
|
||||
nodeId = job.getId();
|
||||
}
|
||||
else if(job instanceof Shipment){
|
||||
if(act.getName().equals("pickupShipment")) nodeId = getFromNodeId((Shipment) job);
|
||||
else nodeId = getToNodeId((Shipment) job);
|
||||
}
|
||||
}
|
||||
return nodeId;
|
||||
}
|
||||
|
||||
private boolean record() {
|
||||
return currentIteration >= start_recording_at && currentIteration <= end_recording_at;
|
||||
}
|
||||
|
|
@ -143,19 +178,99 @@ public class AlgorithmEventRecorder implements RuinListener, IterationStartsList
|
|||
@Override
|
||||
public void removed(Job job, VehicleRoute fromRoute) {
|
||||
if(!record()) return;
|
||||
if(job instanceof Service) removeService(job, fromRoute);
|
||||
else if(job instanceof Shipment) removeShipment(job,fromRoute);
|
||||
}
|
||||
|
||||
private void removeShipment(Job job, VehicleRoute fromRoute) {
|
||||
Shipment shipment = (Shipment)job;
|
||||
String fromNodeId = getFromNodeId(shipment);
|
||||
String toNodeId = getToNodeId(shipment);
|
||||
// removeNodeAndBelongingEdges(fromNodeId,fromRoute);
|
||||
// removeNodeAndBelongingEdges(toNodeId,fromRoute);
|
||||
|
||||
Edge enteringToNode = getEnteringEdge(toNodeId);
|
||||
if(enteringToNode.getNode0().getId().equals(fromNodeId)){
|
||||
markRemoved(graph.getNode(fromNodeId));
|
||||
markRemoved(graph.getNode(toNodeId));
|
||||
// i -> from -> to -> j: rem(i,from), rem(from,to), rem(to,j), add(i,j)
|
||||
Edge enteringFromNode = getEnteringEdge(fromNodeId);
|
||||
removeEdge(enteringFromNode.getId());
|
||||
removeEdge(enteringToNode.getId());
|
||||
if(graph.getNode(toNodeId).getLeavingEdgeSet().isEmpty()){
|
||||
if(fromRoute.getVehicle().isReturnToDepot()) throw new IllegalStateException("leaving edge is missing");
|
||||
return;
|
||||
}
|
||||
|
||||
Edge leavingToNode = getLeavingEdge(toNodeId);
|
||||
removeEdge(leavingToNode.getId());
|
||||
Node from = enteringFromNode.getNode0();
|
||||
Node to = leavingToNode.getNode1();
|
||||
if(!fromRoute.getActivities().isEmpty()){
|
||||
addEdge(makeEdgeId(from,to),from.getId(),to.getId());
|
||||
}
|
||||
}
|
||||
else{
|
||||
removeNodeAndBelongingEdges(fromNodeId,fromRoute);
|
||||
removeNodeAndBelongingEdges(toNodeId,fromRoute);
|
||||
}
|
||||
}
|
||||
|
||||
private Edge getLeavingEdge(String toNodeId) {
|
||||
Collection<Edge> edges = graph.getNode(toNodeId).getLeavingEdgeSet();
|
||||
if(edges.size()==1) return edges.iterator().next();
|
||||
else{
|
||||
for(Edge e : edges){
|
||||
if(e.getId().startsWith("shipment")){ continue; }
|
||||
return e;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Edge getEnteringEdge(String toNodeId) {
|
||||
Collection<Edge> enteringEdges = graph.getNode(toNodeId).getEnteringEdgeSet();
|
||||
if(enteringEdges.size()==1) return enteringEdges.iterator().next();
|
||||
else{
|
||||
for(Edge e : enteringEdges){
|
||||
if(e.getId().startsWith("shipment")){ continue; }
|
||||
return e;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String getToNodeId(Shipment shipment) {
|
||||
return shipment.getId() + "_delivery";
|
||||
}
|
||||
|
||||
private String getFromNodeId(Shipment shipment) {
|
||||
return shipment.getId() + "_pickup";
|
||||
}
|
||||
|
||||
private void removeService(Job job, VehicleRoute fromRoute) {
|
||||
String nodeId = job.getId();
|
||||
removeNodeAndBelongingEdges(nodeId, fromRoute);
|
||||
}
|
||||
|
||||
private void removeNodeAndBelongingEdges(String nodeId, VehicleRoute fromRoute) {
|
||||
Node node = graph.getNode(nodeId);
|
||||
markRemoved(node);
|
||||
Edge entering = node.getEnteringEdge(0);
|
||||
Edge entering = getEnteringEdge(nodeId);
|
||||
removeEdge(entering.getId());
|
||||
Edge leaving = node.getLeavingEdge(0);
|
||||
|
||||
if(node.getLeavingEdgeSet().isEmpty()){
|
||||
if(fromRoute.getVehicle().isReturnToDepot()) throw new IllegalStateException("leaving edge is missing");
|
||||
return;
|
||||
}
|
||||
|
||||
Edge leaving = getLeavingEdge(nodeId);
|
||||
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) {
|
||||
|
|
@ -170,7 +285,11 @@ public class AlgorithmEventRecorder implements RuinListener, IterationStartsList
|
|||
public void informAlgorithmEnds(VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions) {
|
||||
VehicleRoutingProblemSolution solution = Solutions.bestOf(solutions);
|
||||
fileSink.stepBegins(graph.getId(),0,BEFORE_RUIN_RENDER_SOLUTION);
|
||||
recordRoutes(solution.getRoutes());
|
||||
addRoutes(solution.getRoutes());
|
||||
finish();
|
||||
}
|
||||
|
||||
private void finish() {
|
||||
try {
|
||||
fileSink.end();
|
||||
writer.close();
|
||||
|
|
@ -189,10 +308,50 @@ public class AlgorithmEventRecorder implements RuinListener, IterationStartsList
|
|||
addVehicle(vehicle);
|
||||
}
|
||||
for(Job job : problem.getJobs().values()){
|
||||
Service service = (Service)job;
|
||||
addService(service);
|
||||
addJob(job);
|
||||
}
|
||||
}
|
||||
|
||||
private void addJob(Job job) {
|
||||
if(job instanceof Service){
|
||||
Service service = (Service)job;
|
||||
addNode(service.getId(), service.getCoord());
|
||||
markService(service);
|
||||
}
|
||||
else if(job instanceof Shipment){
|
||||
Shipment shipment = (Shipment)job;
|
||||
String fromNodeId = getFromNodeId(shipment);
|
||||
addNode(fromNodeId, shipment.getPickupCoord());
|
||||
String toNodeId = getToNodeId(shipment);
|
||||
addNode(toNodeId,shipment.getDeliveryCoord());
|
||||
markShipment(shipment);
|
||||
if(renderShipments) {
|
||||
Edge e = graph.addEdge("shipment_" + fromNodeId + "_" + toNodeId, fromNodeId, toNodeId, true);
|
||||
e.addAttribute("ui.class", "shipment");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void markShipment(Shipment shipment) {
|
||||
markPickup(getFromNodeId(shipment));
|
||||
markDelivery(getToNodeId(shipment));
|
||||
}
|
||||
|
||||
private void markService(Service service) {
|
||||
if(service instanceof Pickup){
|
||||
markPickup(service.getId());
|
||||
}
|
||||
else if(service instanceof Delivery){
|
||||
markDelivery(service.getId());
|
||||
}
|
||||
}
|
||||
|
||||
private void markPickup(String id) {
|
||||
graph.getNode(id).addAttribute("ui.class","pickup");
|
||||
}
|
||||
|
||||
private void markDelivery(String id) {
|
||||
graph.getNode(id).addAttribute("ui.class","delivery");
|
||||
}
|
||||
|
||||
private void addVehicle(Vehicle vehicle) {
|
||||
|
|
@ -220,25 +379,31 @@ public class AlgorithmEventRecorder implements RuinListener, IterationStartsList
|
|||
return vehicle.getId() + "_end";
|
||||
}
|
||||
|
||||
private void addService(Service service) {
|
||||
Node serviceNode = graph.addNode(service.getId());
|
||||
serviceNode.addAttribute("x", service.getCoord().getX());
|
||||
serviceNode.addAttribute("y", service.getCoord().getY());
|
||||
private void addNode(String nodeId, Coordinate nodeCoord) {
|
||||
Node node = graph.addNode(nodeId);
|
||||
node.addAttribute("x", nodeCoord.getX());
|
||||
node.addAttribute("y", nodeCoord.getY());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void informInsertionEnds(Collection<VehicleRoute> vehicleRoutes) {
|
||||
if(!record()) return;
|
||||
fileSink.stepBegins(graph.getId(),0,CLEAR_SOLUTION);
|
||||
removeRoutes(vehicleRoutes);
|
||||
}
|
||||
|
||||
private void removeRoutes(Collection<VehicleRoute> vehicleRoutes) {
|
||||
for(VehicleRoute route : vehicleRoutes){
|
||||
String prevNode = makeStartId(route.getVehicle());
|
||||
for(TourActivity act : route.getActivities()){
|
||||
String actNode = ((TourActivity.JobActivity)act).getJob().getId();
|
||||
String actNode = getNodeId(act);
|
||||
removeEdge(prevNode + "_" + actNode);
|
||||
prevNode = actNode;
|
||||
}
|
||||
String lastNode = makeEndId(route.getVehicle());
|
||||
removeEdge(prevNode + "_" + lastNode);
|
||||
if(route.getVehicle().isReturnToDepot()) {
|
||||
String lastNode = makeEndId(route.getVehicle());
|
||||
removeEdge(prevNode + "_" + lastNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -246,6 +411,66 @@ public class AlgorithmEventRecorder implements RuinListener, IterationStartsList
|
|||
public void informBeforeJobInsertion(Job job, InsertionData data, VehicleRoute route) {
|
||||
if(!record()) return;
|
||||
markInserted(job);
|
||||
handleVehicleSwitch(data, route);
|
||||
insertJob(job, data, route);
|
||||
}
|
||||
|
||||
private void insertJob(Job job, InsertionData data, VehicleRoute route) {
|
||||
if(job instanceof Service) insertService(job,data,route);
|
||||
else if(job instanceof Shipment) insertShipment(job,data,route);
|
||||
}
|
||||
|
||||
private void insertShipment(Job job, InsertionData data, VehicleRoute route) {
|
||||
String fromNodeId = getFromNodeId((Shipment) job);
|
||||
String toNodeId = getToNodeId((Shipment) job);
|
||||
insertNode(toNodeId,data.getDeliveryInsertionIndex(),data,route);
|
||||
|
||||
List<AbstractActivity> del = vrp.getActivities(job);
|
||||
VehicleRoute copied = VehicleRoute.copyOf(route);
|
||||
copied.getTourActivities().addActivity(data.getDeliveryInsertionIndex(),del.get(1));
|
||||
|
||||
insertNode(fromNodeId, data.getPickupInsertionIndex(), data, copied);
|
||||
}
|
||||
|
||||
private void insertService(Job job, InsertionData data, VehicleRoute route) {
|
||||
insertNode(job.getId(), data.getDeliveryInsertionIndex(), data, route);
|
||||
}
|
||||
|
||||
private void insertNode(String nodeId, int insertionIndex, InsertionData data, VehicleRoute route) {
|
||||
// VehicleRoute copied = VehicleRoute.copyOf(route);
|
||||
|
||||
String node_i;
|
||||
|
||||
if(isFirst(insertionIndex,route)) {
|
||||
node_i = makeStartId(data.getSelectedVehicle());
|
||||
}
|
||||
else {
|
||||
TourActivity.JobActivity jobActivity = (TourActivity.JobActivity) route.getActivities().get(insertionIndex - 1);
|
||||
node_i = getNodeId(jobActivity);
|
||||
}
|
||||
String node_k = nodeId;
|
||||
String edgeId_1 = node_i + "_" + node_k;
|
||||
String node_j;
|
||||
if(isLast(insertionIndex,route)) {
|
||||
node_j = makeEndId(data.getSelectedVehicle());
|
||||
}
|
||||
else {
|
||||
TourActivity.JobActivity jobActivity = (TourActivity.JobActivity) route.getActivities().get(insertionIndex);
|
||||
node_j = getNodeId(jobActivity);
|
||||
}
|
||||
String edgeId_2 = node_k + "_" + node_j;
|
||||
|
||||
addEdge(edgeId_1, node_i, node_k);
|
||||
|
||||
if(!(isLast(insertionIndex,route) && !data.getSelectedVehicle().isReturnToDepot())) {
|
||||
addEdge(edgeId_2, node_k, node_j);
|
||||
if (!route.getActivities().isEmpty()) {
|
||||
removeEdge(node_i + "_" + node_j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleVehicleSwitch(InsertionData data, VehicleRoute route) {
|
||||
boolean vehicleSwitch = false;
|
||||
if(!(route.getVehicle() instanceof VehicleImpl.NoVehicle)) {
|
||||
if (!route.getVehicle().getId().equals(data.getSelectedVehicle().getId())) {
|
||||
|
|
@ -258,56 +483,55 @@ public class AlgorithmEventRecorder implements RuinListener, IterationStartsList
|
|||
String oldEnd = makeEndId(route.getVehicle());
|
||||
String lastAct = ((TourActivity.JobActivity)route.getActivities().get(route.getActivities().size()-1)).getJob().getId();
|
||||
removeEdge(oldStart + "_" + firstAct);
|
||||
removeEdge(lastAct + "_" + oldEnd);
|
||||
|
||||
if(route.getVehicle().isReturnToDepot()) {
|
||||
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);
|
||||
if(data.getSelectedVehicle().isReturnToDepot()) {
|
||||
addEdge(lastAct + "_" + newEnd, lastAct, newEnd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void markInserted(Job job) {
|
||||
graph.getNode(job.getId()).removeAttribute("ui.class");
|
||||
if(job instanceof Service){
|
||||
markService((Service) job);
|
||||
}
|
||||
else{
|
||||
markShipment((Shipment)job);
|
||||
}
|
||||
}
|
||||
|
||||
private void removeEdge(String edgeId) {
|
||||
markEdgeRemoved(edgeId);
|
||||
graph.removeEdge(edgeId);
|
||||
}
|
||||
|
||||
private boolean isFirst(InsertionData data, VehicleRoute route) {
|
||||
return data.getDeliveryInsertionIndex() == 0;
|
||||
private void markEdgeRemoved(String edgeId) {
|
||||
graph.getEdge(edgeId).addAttribute("ui.class","removed");
|
||||
}
|
||||
|
||||
private boolean isLast(InsertionData data, VehicleRoute route) {
|
||||
return data.getDeliveryInsertionIndex() == route.getActivities().size();
|
||||
private boolean isFirst(int index, VehicleRoute route) {
|
||||
return index == 0;
|
||||
}
|
||||
|
||||
private boolean isLast(int index, VehicleRoute route) {
|
||||
return index == route.getActivities().size();
|
||||
}
|
||||
|
||||
private void addEdge(String edgeId, String fromNode, String toNode) {
|
||||
graph.addEdge(edgeId,fromNode,toNode,true);
|
||||
markEdgeInserted(edgeId);
|
||||
}
|
||||
|
||||
private void markEdgeInserted(String edgeId) {
|
||||
graph.getEdge(edgeId).addAttribute("ui.class","inserted");
|
||||
graph.getEdge(edgeId).removeAttribute("ui.class");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -33,16 +33,95 @@ import org.graphstream.graph.Edge;
|
|||
import org.graphstream.graph.Graph;
|
||||
import org.graphstream.graph.Node;
|
||||
import org.graphstream.graph.implementations.MultiGraph;
|
||||
import org.graphstream.stream.Sink;
|
||||
import org.graphstream.stream.file.FileSinkImages;
|
||||
import org.graphstream.ui.swingViewer.View;
|
||||
import org.graphstream.ui.swingViewer.Viewer;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
|
||||
public class GraphStreamViewer {
|
||||
|
||||
private static class EmptySink implements Sink {
|
||||
|
||||
@Override
|
||||
public void graphAttributeAdded(String sourceId, long timeId, String attribute, Object value) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void graphAttributeChanged(String sourceId, long timeId, String attribute, Object oldValue, Object newValue) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void graphAttributeRemoved(String sourceId, long timeId, String attribute) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nodeAttributeAdded(String sourceId, long timeId, String nodeId, String attribute, Object value) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nodeAttributeChanged(String sourceId, long timeId, String nodeId, String attribute, Object oldValue, Object newValue) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nodeAttributeRemoved(String sourceId, long timeId, String nodeId, String attribute) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void edgeAttributeAdded(String sourceId, long timeId, String edgeId, String attribute, Object value) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void edgeAttributeChanged(String sourceId, long timeId, String edgeId, String attribute, Object oldValue, Object newValue) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void edgeAttributeRemoved(String sourceId, long timeId, String edgeId, String attribute) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nodeAdded(String sourceId, long timeId, String nodeId) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nodeRemoved(String sourceId, long timeId, String nodeId) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void edgeAdded(String sourceId, long timeId, String edgeId, String fromNodeId, String toNodeId, boolean directed) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void edgeRemoved(String sourceId, long timeId, String edgeId) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void graphCleared(String sourceId, long timeId) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stepBegins(String sourceId, long timeId, double step) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static Graph createMultiGraph(String name, String style){
|
||||
Graph g = new MultiGraph(name);
|
||||
|
|
@ -143,6 +222,12 @@ public class GraphStreamViewer {
|
|||
|
||||
private double scaling = 1.0;
|
||||
|
||||
private boolean createImageByEvent = false;
|
||||
|
||||
private File imageDirectory;
|
||||
|
||||
Sink fsi = new EmptySink();
|
||||
|
||||
public GraphStreamViewer(VehicleRoutingProblem vrp) {
|
||||
super();
|
||||
this.vrp = vrp;
|
||||
|
|
@ -159,6 +244,12 @@ public class GraphStreamViewer {
|
|||
return this;
|
||||
}
|
||||
|
||||
public GraphStreamViewer createImagesByEvent(boolean createImanges, File outDirectory){
|
||||
createImageByEvent = true;
|
||||
imageDirectory = outDirectory;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GraphStreamViewer setRenderDelay(long ms){
|
||||
this.renderDelay_in_ms=ms;
|
||||
return this;
|
||||
|
|
@ -204,7 +295,21 @@ public class GraphStreamViewer {
|
|||
|
||||
JFrame jframe = createJFrame(view,scaling);
|
||||
|
||||
render(g,view);
|
||||
Sink fsi;
|
||||
if(createImageByEvent){
|
||||
FileSinkImages.OutputPolicy outputPolicy = FileSinkImages.OutputPolicy.BY_ELEMENT_EVENT;
|
||||
String prefix = "screenshot_";
|
||||
FileSinkImages.OutputType type = FileSinkImages.OutputType.PNG;
|
||||
FileSinkImages.Resolution resolution = FileSinkImages.Resolutions.HD720;
|
||||
fsi = new FileSinkImages( type, resolution );
|
||||
((FileSinkImages)fsi).setStyleSheet(STYLESHEET);
|
||||
((FileSinkImages)fsi).setOutputPolicy(outputPolicy);
|
||||
((FileSinkImages)fsi).setLayoutPolicy(FileSinkImages.LayoutPolicy.NO_LAYOUT);
|
||||
((FileSinkImages)fsi).setQuality(FileSinkImages.Quality.HIGH);
|
||||
((FileSinkImages)fsi).setRenderer(FileSinkImages.RendererType.SCALA);
|
||||
}
|
||||
|
||||
render(g, view);
|
||||
}
|
||||
|
||||
private JFrame createJFrame(View view, double scaling) {
|
||||
|
|
@ -254,8 +359,7 @@ public class GraphStreamViewer {
|
|||
private void render(Graph g, View view) {
|
||||
if(center != null){
|
||||
view.resizeFrame(view.getWidth(), view.getHeight());
|
||||
view.getCamera().setViewCenter(center.x, center.y, 0);
|
||||
view.getCamera().setViewPercent(zoomFactor);
|
||||
alignCamera(view);
|
||||
}
|
||||
|
||||
for(Vehicle vehicle : vrp.getVehicles()){
|
||||
|
|
@ -284,7 +388,16 @@ public class GraphStreamViewer {
|
|||
|
||||
}
|
||||
|
||||
private JLabel createEmptyLabel() {
|
||||
private void alignCamera(View view) {
|
||||
view.getCamera().setViewCenter(center.x, center.y, 0);
|
||||
view.getCamera().setViewPercent(zoomFactor);
|
||||
if(fsi instanceof FileSinkImages){
|
||||
((FileSinkImages) fsi).setViewCenter(center.x, center.y);
|
||||
((FileSinkImages) fsi).setViewPercent(zoomFactor);
|
||||
}
|
||||
}
|
||||
|
||||
private JLabel createEmptyLabel() {
|
||||
JLabel emptyLabel1 = new JLabel();
|
||||
emptyLabel1.setPreferredSize(new Dimension((int)(40*scaling),(int)(25*scaling)));
|
||||
return emptyLabel1;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue