2

I have a large directed graph with cycles (a control-flow-graph from a large program). I want to group the nodes such that each group would contain nodes independent to each other. Two nodes A and B are independent to each other if there is no path from node A to node B or node B to node A. That is, once A has been executed, it guarantees that B will not be. Similarly, once B has been executed, A can not be executed. Is there an efficient algorithm to do this?

The trivial algorithm here is to start by picking a node A, remove all nodes reachable from it, then transpose the graph, and remove all nodes that are again reachable from A, pick one from the remaining. Remove nodes reachable from it, transpose, and remove everything reachable from it. Continue until all nodes are exhausted. Start over again with remaining nodes (with suitable caching of reachability).

If this question is off-topic here, I would also be glad to be pointed to the right SO community.

I found this question related, but in my case, existence of a path from A to B does not mean a B to A path exists. Hence, they need not be strongly connected. This question is also similar, but talks about having nodes without edge connection rather than path connection.

Example abs_value()

abs_value

The groups here are (1),(2), (3,5), (6), (7)

Example factorial()

factorial

The groups here are: (1), (2), (3,5), (3,6,8), (3,6,9,11), (3,6,9,12),(3,6,9,13), (3,6,9,14), (3,6,9,16), (17)

Rahul Gopinath
  • 808
  • 10
  • 24
  • I find your question interesting but very confusing. Can you give some visual examples? What has me confused is that you describe graph [components](https://en.wikipedia.org/wiki/Component_(graph_theory)) but then in a comment for an answer say that they are related some how, `Essentially, if a node in a group is executed, I need to guarantee that no other nodes in that group will be executed.` It is like you have two different set of rules, one for reachability and one for activation. Continued. – Guy Coder Jan 10 '22 at 08:56
  • I have learned from experience to avoid questions like this when I am confused. Don't take this the wrong way but I often note that if the [duck](https://en.wikipedia.org/wiki/Rubber_duck_debugging) doesn't know it we don't know it. – Guy Coder Jan 10 '22 at 08:58
  • In some sense your question has me thinking of [DNF](https://en.wikipedia.org/wiki/Disjunctive_normal_form) (Disjunctive normal form) but your input is a graph with cycles, no?, and DNF does not work with cycles. – Guy Coder Jan 10 '22 at 09:01
  • @GuyCoder I have updated the question. I don't think these are components; neither weakly connected nor strongly connected components seem to describe what I want. – Rahul Gopinath Jan 10 '22 at 12:18
  • The visuals are so much better at conveying the idea of the question. After setting the visuals I know nothing pops into my mind for an answer but then again if I think about this more it might. Don't expect an answer from me but your visuals should definitely help you get more people thinking about an answer. The problem is that most people only look at a question once and if they don't know an answer they move on. You have now lost a large group of such users. The only way to get them to take a second look is to use a bounty. – Guy Coder Jan 10 '22 at 15:55
  • I have NOT tired to implement your method in code but tried to reason out the groups in my head. If I base the idea on number of steps from the root then it kind of makes sense, 1 - (1), 2 - (2), 3 - (3,5) but when I get to 4 it seems the result would be 4 - (17,6,8) but you need (3,6,8). So now I am confused again. Maybe I would need to implement your method in code and then I would get your desired results but I don't plan to do that. – Guy Coder Jan 10 '22 at 16:17
  • Assuming the graph is a directed acyclic graph G. Identify the "left-most branch" of the graph. For every node `u` on the left-most branch: { Remove all descendants and ancestors of `u`, calling H the resulting graph. Make a recursive call to get all the groups of H. Add `u` to each of the groups of H, and output all the groups. } – Stef Jan 10 '22 at 16:58
  • The method in my previous comment probably works on a non-acyclic graph as well, but you have to be more careful when removing the "descendants and ancestors". – Stef Jan 10 '22 at 16:59

1 Answers1

0

You may end to the up with a great many "groups", with each node present in multiple groups.

Example, a graph with three nodes A, B and C.

Links: B -> C and C -> B

The "groups" are ( A,B ) and ( A, C )

Is this really what you want? It is hard to imagine what purpose this might serve.

In the case of a larger graph that happens to be bipartite, you will need a group for every distinct pair where one node is in one part and the other in the other part.

Since this is a control flow graph, every node is independent of every node higher in the call hierarchy, and every node in a different calling tree.

ravenspoint
  • 19,093
  • 6
  • 57
  • 103
  • Please see my clarification in the question; Yes, I need ( A,B ) and ( A, C ) here. Essentially, if a node in a group is executed, I need to guarantee that no other nodes in that group will be executed. – Rahul Gopinath Jan 10 '22 at 02:37