-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathValidate_DAG.py
40 lines (36 loc) · 2.17 KB
/
Validate_DAG.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
def hasCycle(edges, numEdges):
#Initialize a graph that stores the neighbor of each node
graph = {i:[] for i in list(range(numEdges))}
#Populate the graph so that the 'children' of each node are stored with the parent as the key
for x, y in edges: graph[x] += [y]
#Create three sets, one to store all unvisited nodes, one to store nodes curently visiting, one to store completely visited ones
unvisited = list(range(numEdges))
visiting = set()
completelyVisited = set()
#While we still have nodes that are unvisited
while unvisited:
#We graph a random node from the unvisited collection to run a DFS on
currentNode = unvisited[0]
#If a call to the depth first seach returns true then we know this graph has a cycle and can return true
if depthFirstSearch(currentNode, unvisited, visiting, completelyVisited, graph): return True
#If no call to the depth first search returns true then we can return False that there is no cycle in this graph
return False
#Define our helper depth first search for a cycle
def depthFirstSearch(currentNode, unvisited, visiting, completelyVisited, graph):
#Firstly, we need to move the current node we're at from unvisited and to visiting
unvisited.remove(currentNode)
visiting.add(currentNode)
#Now for each of this nodes adjacent neighbors we need to run this DFS again
for neighbor in graph[currentNode]:
#If that neighbor has already been completely visited, we can skip tis particular neighbor
if neighbor in completelyVisited: continue
#If this neighbor is already a node we're visiting then return true that this has a cycle! Because we've circled back to a parent node
if neighbor in visiting: return True
#If any its neighbors have a cycle return true as well
if depthFirstSearch(neighbor, unvisited, visiting, completelyVisited, graph): return True
#Finally remove this current node from visiting and add it to completely visited
visiting.remove(currentNode)
completelyVisited.add(currentNode)
def main():
print(hasCycle([[1, 0], [0, 2]], 3))
main()