From 16f069c810d6c2f373b266f19aeae7f6c52ae277 Mon Sep 17 00:00:00 2001 From: Michael Hammann Date: Sat, 9 Oct 2021 06:57:01 +0200 Subject: [PATCH] feat: add graphutils to detect cyclical process dependencies --- supervisor/graphutils.py | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 supervisor/graphutils.py diff --git a/supervisor/graphutils.py b/supervisor/graphutils.py new file mode 100644 index 000000000..867f3aa06 --- /dev/null +++ b/supervisor/graphutils.py @@ -0,0 +1,36 @@ +from collections import defaultdict + +class Graph(): + def __init__(self,vertices): + self.graph = defaultdict(list) + self.V = vertices + + def addEdge(self,u,v): + self.graph[u].append(v) + + def cyclic(self): + """Return True if the directed graph has a cycle. + The graph must be represented as a dictionary mapping vertices to + iterables of neighbouring vertices. For example: + + >>> cyclic({1: (2,), 2: (3,), 3: (1,)}) + True + >>> cyclic({1: (2,), 2: (3,), 3: (4,)}) + False + + """ + path = set() + visited = set() + + def visit(vertex): + if vertex in visited: + return False + visited.add(vertex) + path.add(vertex) + for neighbour in self.graph.get(vertex, ()): + if neighbour in path or visit(neighbour): + return True + path.remove(vertex) + return False + + return any(visit(v) for v in self.graph)