2

I am using QuickGraph to create a directed acyclic graph. I need to find all vertices whose indegree is zero. I don't see this support on a graph's Vertices collection, or a way to filter using LINQ.

Here is a sample data structure I'm composing:

var componentGraph = new AdjacencyGraph<Component, Edge<Component>>();

var serverOnMachineA = new TalismaServerComponent("CLTDEPAPI10");
var serverOnMachineB = new TalismaServerComponent("CLTDEPAPI11");
var appServerOnMachineB = new TalismaAppServerComponent("CLTDEPAPI11");
var webComponentsOnMachineC = new TalismaWebComponentsComponent("CLTDEPFE1");

componentGraph.AddVertex(serverOnMachineA);
componentGraph.AddVertex(serverOnMachineB);
componentGraph.AddVertex(appServerOnMachineB);
componentGraph.AddVertex(webComponentsOnMachineC);

componentGraph.AddEdge(new Edge<Component>(appServerOnMachineB, serverOnMachineA));
componentGraph.AddEdge(new Edge<Component>(webComponentsOnMachineC, appServerOnMachineB));
componentGraph.AddEdge(new Edge<Component>(webComponentsOnMachineC, serverOnMachineB));

I simply need a list of the vertices in this graph that have no "in" edges (indegree=0).

Mark Richman
  • 28,948
  • 25
  • 99
  • 159
  • Who voted for closing? What is unclear about this question? I vote for leaving open. – chiccodoro Aug 29 '14 at 13:59
  • @chiccodoro Thank you! I don't understand why this is unclear either. – Mark Richman Aug 29 '14 at 14:13
  • Does `Vertex` have anything like a `IncomingEdges` property or at least something like an `AdjacentEdges` property? Then of course you could filter by using `componentGraph.Vertices.Where(v => !v.IncomingEdges.Any()` or similar. However I reckon you need an implementation of a certain algorithm to make this more performant... – chiccodoro Sep 01 '14 at 06:42
  • It has `OutEdges` but not `InEdges`. That's the first thing I looked for. – Mark Richman Sep 01 '14 at 11:38
  • I think I found the solution. The guy (or lady) who voted for closing helped you find attention :-) – chiccodoro Sep 01 '14 at 14:47

1 Answers1

3

You might need a different graph type. Diving a bit into the forums and source of QuickGraph I found the BidirectionalGraph class which is

A mutable directed graph data structure efficient for sparse graph representation where out-edge and in-edges need to be enumerated. Requires twice as much memory as the adjacency graph.

The method to retrieve the in-degree seems to be found on the IBidirectionalIncidenceGraph as this discussion implies.

The data structure you use does not do book keeping on incoming edges, thus you would have to retrieve the in-degree of a vertex by iterating through all edges and looking at their target, which could be an expensive operation for big graphs.

The BidirectionalGraph is quicker for that but takes twice as much memory space for the book-keeping. Using it you could do something like:

var orphans = graph.Vertices.Where(v => graph.InDegree(v) == 0)
Karl Wenzel
  • 2,412
  • 25
  • 24
chiccodoro
  • 14,407
  • 19
  • 87
  • 130
  • I think this will work for me! I will only have a handful (<50) vertices, so efficiency is not much of a concern. I will give this a try and mark this as the answer when I have it working. Thanks! – Mark Richman Sep 02 '14 at 00:14
  • @Mark, more than glad I could offer help for a question I only found through review :-) – chiccodoro Sep 02 '14 at 15:20
  • was that a nice way of telling me to RTFM? – Mark Richman Sep 02 '14 at 15:21
  • @Mark it was not the least intended too. I guess I was just lucky to find what you were looking for. I did not know the library but I know the concepts of graphs, indegrees etc.; when I saw that your question still wasn't answered and still was in the review queue I thought I'd rather hasten to help you (and prove that the question was clear enough) – chiccodoro Sep 02 '14 at 15:25