问题
Is there any way to create a graph with clusters using jgrapht? Example graph with two clusters "process #1" and "process #2":
Expected dot file content :
digraph G {
subgraph cluster_0 {
style=filled;
color=lightgrey;
node [style=filled,color=white];
a0 -> a1 -> a2 -> a3;
label = "process #1";
}
subgraph cluster_1 {
node [style=filled];
b0 -> b1 -> b2 -> b3;
label = "process #2";
color=blue
}
start -> a0;
start -> b0;
a1 -> b3;
b2 -> a3;
a3 -> a0;
a3 -> end;
b3 -> end;
start [shape=Mdiamond];
end [shape=Msquare];
}
回答1:
Your graph design is a bit peculiar. When I visually look at your graph, I see a base graph, and 2 clustered groups of nodes. When I look at your DOT file, I see 2 subgraphs, and an 'outer' graph that refers to specific nodes in your subgraph. Note that a subgraph is not a cluster.
Your question seems to have 2 parts: (1) can you create a graph with clusters using jgrapht and (2) can you create the DOT file in your example. The answers are: (1) yes, (2) no, at least not out of the box, since DOTExporter
does not support 'subgraphs'.
There are a few different ways you can create clustered graphs.
- Create a regular graph with edges and vertices, and maintain a separate
List<Set<V>>
to store your clusters. You could visualize the subgraph induced by a particular cluster using theAsSubgraph
class. - JGraphT support vertices of any type. So a vertex can be a graph as well! You could create a graph where each vertex is a graph by itself; edges between these vertices represent relations between these special vertices. We did something like this in the
BlockCutpointGraph
implementation.
If you want to export your graph in a similar fashion as your example DOT file, you'll have to do some work. You could implement your own custom DOTExporter, or modify the existing one. Perhaps an easy alternative (not the cleanest) is to do something along the following lines:
- Create a regular graph with vertices and edges (in your case all nodes and arcs in your graph).
- Create your induced subgraph clusters (in your case, a subgraph for process1 and another one for process 2. For this you can use the
AsSubgraph
class - Create a graph which does not contain any of the arcs internally present in your clusters. For this you could use the
MaskSubgraph
class. - Export the graphs you created in steps (2) and (3) using the
DOTExporter
class. - As a final step, you must merge the exported graphs into a single file. I would use the graph from step (3) as the 'base' graph, and insert the other graphs using the
subgraph
keywork.
Using your example:
- Base graph from step (3):
digraph G {
start -> a0;
start -> b0;
a1 -> b3;
b2 -> a3;
a3 -> a0;
a3 -> end;
b3 -> end;
start [shape=Mdiamond];
end [shape=Msquare];
}
- One of the induced subgraphs from step (2):
digraph cluster_0 {
style=filled;
color=lightgrey;
node [style=filled,color=white];
a0 -> a1 -> a2 -> a3;
label = "process #1";
}
Here you have to substitute digraph
by subgraph
and insert this graph into the base graph to obtain:
digraph G {
subgraph cluster_0 {
style=filled;
color=lightgrey;
node [style=filled,color=white];
a0 -> a1 -> a2 -> a3;
label = "process #1";
}
start -> a0;
start -> b0;
a1 -> b3;
b2 -> a3;
a3 -> a0;
a3 -> end;
b3 -> end;
start [shape=Mdiamond];
end [shape=Msquare];
}
Obviously you must repeat this for the remaining clusters.
来源:https://stackoverflow.com/questions/57820898/creating-graph-with-clusters-using-jgrapht