-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy patheuler_fleury_alg.py
105 lines (83 loc) · 2.73 KB
/
euler_fleury_alg.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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# Find euler cycle/path in undirected graph by Fleury algorithm
# Make sure the graph has 0 or 2 odd vertices
# If there 0 odd vertices, start anywhere. If there 2 odd vertices, start at one of them
# Follow the edges one at a time. If you have a choice between a bridge and
# non-bridge, always choose non-bridge
# Stop when you run out of edges.
# Remember that the complexity of this Algorithm is O((V+E)^2)
from collections import defaultdict
class Graph:
def __init__(self, vertices):
self.V = vertices # No. of vertices
self.graph = defaultdict(list) # default dictionary to store graph
self.time = 0
# function to add an edge to graph
def addEdge(self, u, v):
self.graph[u].append(v)
self.graph[v].append(u)
def rmvEdge(self, u, v):
for index, key in enumerate(self.graph[u]):
if key == v:
self.graph[u].pop(index)
for index, key in enumerate(self.graph[v]):
if key == u:
self.graph[v].pop(index)
def DFSCount(self, v, visited):
count = 1
visited[v] = True
for i in self.graph[v]:
if visited[i] == False:
count = count + self.DFSCount(i, visited)
return count
def isValidNextEdge(self, u, v):
# the edge u-v is valid in one of the two case
# 1. if v only adjacent vertex of u
if len(self.graph[u]) == 1:
return True
else:
# 2. If there are multiple adjacent
# Count number of vertices reachable from u
visited = [False] * self.V
count1 = self.DFSCount(u, visited)
# Remove edge (u,v) and after remove count number of vertices reachable
# from u
self.rmvEdge(u, v)
count2 = self.DFSCount(u, visited)
# Re-add edge (u, v)
self.addEdge(u, v)
return False if count1 > count2 else True
def printEulerUtil(self, u):
for v in self.graph[u]:
if self.isValidNextEdge(u, v):
print("%d-%d " % (u, v))
self.rmvEdge(u, v)
self.printEulerUtil(v)
def printEulerTour(self):
u = 0
for i in range(self.V):
if len(self.graph[i]) % 2 != 0:
u = i
break
print ("\n")
self.printEulerUtil(u)
g1 = Graph(4)
g1.addEdge(0, 1)
g1.addEdge(0, 2)
g1.addEdge(1, 2)
g1.addEdge(2, 3)
g1.printEulerTour()
g2 = Graph(3)
g2.addEdge(0, 1)
g2.addEdge(1, 2)
g2.addEdge(2, 0)
g2.printEulerTour()
g3 = Graph(5)
g3.addEdge(1, 0)
g3.addEdge(0, 2)
g3.addEdge(2, 1)
g3.addEdge(0, 3)
g3.addEdge(3, 4)
g3.addEdge(3, 2)
g3.addEdge(3, 1)
g3.addEdge(2, 4)
g3.printEulerTour()