I'd like to take a directed graph, e.g.
input = {
13 -> 7, 7 -> 0, 0 -> 16, 16 -> 2, 2 -> 15,
10 -> 5, 5 -> 12, 12 -> 18, 18 -> 15,
17 -> 18,
15 -> 6, 6 -> 8, 8 -> 4,
9 -> 8,
4 -> 19, 19 -> 11, 11 -> 1, 1 -> 20, 20 -> 3, 3 -> 4,
14 -> 19};
GraphPlot[input, VertexLabeling -> True]
...and reduce it to only the "junctions," e.g.
output = {
13 -> 15,
10 -> 18,
18 -> 15,
17 -> 18,
15 -> 8,
8 -> 4,
9 -> 8,
4 -> 19,
19 -> 4,
14 -> 19};
GraphPlot[output, VertexLabeling -> True]
In the end, I'd also like to label the edges with the number of nodes that were "omitted" during the reduction, e.g. 4, between 13 and 15. It should be mentioned that the input is guaranteed to be a sinkless finite digraph.
I've been writing a (naive) algorithim that simply traverses nodes until reaching a visited node, to generate "paths," segmenting these paths when another path joins to it in the middle. This generates a list of all the segments, e.g.
segments = {
{13, 7, 0, 16, 2, 15},
{10, 5, 12, 18},
{18, 15},
{17, 18},
{15, 6, 8},
{9, 8},
{8, 4},
{4, 19},
{14, 19},
{19, 11, 1, 20, 3, 4}
}
Then, it's easy to construct the graph I desire by reducing each list to First@#->Last@#
, while storing Length@#-2
as an edge weight.
My function is nearing completion, but I'm beginning to wonder if there isn't an easier, built-in way to do this in $Mathematica$. I've browsed through Graphs And Networks, in particular "Computation on Graphs," but I don't see anything that fits what I'm trying to do. I could be missing terminology, however.
Does someone know of a more elegant way to achieve my aim, than my algorithm?
Graph
instead ofGraphPlot
to display the direction of the edges. SoGraph[output, VertexLabels ->"Name"]
$\endgroup$DirectedEdges -> True
withGraphPlot
. $\endgroup$