Skip to content

Commit b3a1517

Browse files
author
A Safari
authored
Added more functionality
Added topological sort, cycle detection and a function to report the nodes participating in cycles in graph(for a use case I myself needed ).
1 parent 889f8fb commit b3a1517

File tree

1 file changed

+222
-0
lines changed

1 file changed

+222
-0
lines changed

graphs/Directed and Undirected (Weighted) Graph

+222
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,133 @@ class DirectedGraph:
106106
def out_degree(self, u):
107107
return len(self.graph[u])
108108

109+
def topological_sort(self, s = -2):
110+
stack = []
111+
visited = []
112+
if s == -2:
113+
s = list(self.graph.keys())[0]
114+
stack.append(s)
115+
visited.append(s)
116+
ss = s
117+
sorted_nodes = []
118+
119+
while True:
120+
# check if there is any non isolated nodes
121+
if len(self.graph[s]) != 0:
122+
ss = s
123+
for __ in self.graph[s]:
124+
if visited.count(__[1]) < 1:
125+
stack.append(__[1])
126+
visited.append(__[1])
127+
ss =__[1]
128+
break
129+
130+
# check if all the children are visited
131+
if s == ss :
132+
sorted_nodes.append(stack.pop())
133+
if len(stack) != 0:
134+
s = stack[len(stack) - 1]
135+
else:
136+
s = ss
137+
138+
# check if se have reached the starting point
139+
if len(stack) == 0:
140+
return sorted_nodes
141+
142+
def cycle_nodes(self):
143+
stack = []
144+
visited = []
145+
s = list(self.graph.keys())[0]
146+
stack.append(s)
147+
visited.append(s)
148+
parent = -2
149+
indirect_parents = []
150+
ss = s
151+
anticipating_nodes = set()
152+
153+
while True:
154+
# check if there is any non isolated nodes
155+
if len(self.graph[s]) != 0:
156+
ss = s
157+
for __ in self.graph[s]:
158+
if visited.count(__[1]) > 0 and __[1] != parent and indirect_parents.count(__[1]) > 0 and not on_the_way_back:
159+
l = len(stack) - 1
160+
while True and l >= 0:
161+
if stack[l] == __[1]:
162+
anticipating_nodes.add(__[1])
163+
break
164+
else:
165+
anticipating_nodes.add(stack[l])
166+
l -= 1
167+
if visited.count(__[1]) < 1:
168+
stack.append(__[1])
169+
visited.append(__[1])
170+
ss =__[1]
171+
break
172+
173+
# check if all the children are visited
174+
if s == ss :
175+
stack.pop()
176+
on_the_way_back = True
177+
if len(stack) != 0:
178+
s = stack[len(stack) - 1]
179+
else:
180+
on_the_way_back = False
181+
indirect_parents.append(parent)
182+
parent = s
183+
s = ss
184+
185+
# check if se have reached the starting point
186+
if len(stack) == 0:
187+
return list(anticipating_nodes)
188+
189+
def has_cycle(self):
190+
stack = []
191+
visited = []
192+
s = list(self.graph.keys())[0]
193+
stack.append(s)
194+
visited.append(s)
195+
parent = -2
196+
indirect_parents = []
197+
ss = s
198+
anticipating_nodes = set()
199+
200+
while True:
201+
# check if there is any non isolated nodes
202+
if len(self.graph[s]) != 0:
203+
ss = s
204+
for __ in self.graph[s]:
205+
if visited.count(__[1]) > 0 and __[1] != parent and indirect_parents.count(__[1]) > 0 and not on_the_way_back:
206+
l = len(stack) - 1
207+
while True and l >= 0:
208+
if stack[l] == __[1]:
209+
anticipating_nodes.add(__[1])
210+
break
211+
else:
212+
return True
213+
anticipating_nodes.add(stack[l])
214+
l -= 1
215+
if visited.count(__[1]) < 1:
216+
stack.append(__[1])
217+
visited.append(__[1])
218+
ss =__[1]
219+
break
220+
221+
# check if all the children are visited
222+
if s == ss :
223+
stack.pop()
224+
on_the_way_back = True
225+
if len(stack) != 0:
226+
s = stack[len(stack) - 1]
227+
else:
228+
on_the_way_back = False
229+
indirect_parents.append(parent)
230+
parent = s
231+
s = ss
232+
233+
# check if se have reached the starting point
234+
if len(stack) == 0:
235+
return False
109236

110237
class Graph:
111238
def __init__(self):
@@ -214,3 +341,98 @@ class Graph:
214341
return visited
215342
def degree(self, u):
216343
return len(self.graph[u])
344+
345+
def cycle_nodes(self):
346+
stack = []
347+
visited = []
348+
s = list(self.graph.keys())[0]
349+
stack.append(s)
350+
visited.append(s)
351+
parent = -2
352+
indirect_parents = []
353+
ss = s
354+
anticipating_nodes = set()
355+
356+
while True:
357+
# check if there is any non isolated nodes
358+
if len(self.graph[s]) != 0:
359+
ss = s
360+
for __ in self.graph[s]:
361+
if visited.count(__[1]) > 0 and __[1] != parent and indirect_parents.count(__[1]) > 0 and not on_the_way_back:
362+
l = len(stack) - 1
363+
while True and l >= 0:
364+
if stack[l] == __[1]:
365+
anticipating_nodes.add(__[1])
366+
break
367+
else:
368+
anticipating_nodes.add(stack[l])
369+
l -= 1
370+
if visited.count(__[1]) < 1:
371+
stack.append(__[1])
372+
visited.append(__[1])
373+
ss =__[1]
374+
break
375+
376+
# check if all the children are visited
377+
if s == ss :
378+
stack.pop()
379+
on_the_way_back = True
380+
if len(stack) != 0:
381+
s = stack[len(stack) - 1]
382+
else:
383+
on_the_way_back = False
384+
indirect_parents.append(parent)
385+
parent = s
386+
s = ss
387+
388+
# check if se have reached the starting point
389+
if len(stack) == 0:
390+
return list(anticipating_nodes)
391+
392+
def has_cycle(self):
393+
stack = []
394+
visited = []
395+
s = list(self.graph.keys())[0]
396+
stack.append(s)
397+
visited.append(s)
398+
parent = -2
399+
indirect_parents = []
400+
ss = s
401+
anticipating_nodes = set()
402+
403+
while True:
404+
# check if there is any non isolated nodes
405+
if len(self.graph[s]) != 0:
406+
ss = s
407+
for __ in self.graph[s]:
408+
if visited.count(__[1]) > 0 and __[1] != parent and indirect_parents.count(__[1]) > 0 and not on_the_way_back:
409+
l = len(stack) - 1
410+
while True and l >= 0:
411+
if stack[l] == __[1]:
412+
anticipating_nodes.add(__[1])
413+
break
414+
else:
415+
return True
416+
anticipating_nodes.add(stack[l])
417+
l -= 1
418+
if visited.count(__[1]) < 1:
419+
stack.append(__[1])
420+
visited.append(__[1])
421+
ss =__[1]
422+
break
423+
424+
# check if all the children are visited
425+
if s == ss :
426+
stack.pop()
427+
on_the_way_back = True
428+
if len(stack) != 0:
429+
s = stack[len(stack) - 1]
430+
else:
431+
on_the_way_back = False
432+
indirect_parents.append(parent)
433+
parent = s
434+
s = ss
435+
436+
# check if se have reached the starting point
437+
if len(stack) == 0:
438+
return False

0 commit comments

Comments
 (0)