-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathc-14.53.py
83 lines (69 loc) · 2.48 KB
/
c-14.53.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
"""
C-14.53 An Euler tour of a directed graph G with n vertices and m edges is a
cycle that traverses each edge of G exactly once according to its direction.
Such a tour always exists if G is connected and the in-degree equals the
out-degree of each vertex in G . Describe an O(n+m)-time algorithm for
finding an Euler tour of such a directed graph G .
"""
from collections import defaultdict
def eulerian_cycle(g, u):
"""
returns cycle path of the euler tour for strongly connected
graph `g` assuming that each vertex `v` of graph `g` has the same
in/out degree.
"""
g_cpy = defaultdict(list) # O(n+m)
for v in g.vertices():
for e in g.incident_edges(v):
g_cpy[v].append(e)
s = [(u, None)]
path = []
while len(s) > 0:
v, edge = s[-1]
if g_cpy[v]:
e = g_cpy[v].pop(0)
w = e.opposite(v)
s.append((w, e))
else:
if edge is not None:
path.append(edge)
s.pop()
path.reverse()
return path
if __name__ == "__main__":
from shared_14_chapter import Graph
g = Graph(directed=True)
v1 = g.insert_vertex(element='v1')
v2 = g.insert_vertex(element='v2')
v3 = g.insert_vertex(element='v3')
e1 = g.insert_edge(v1, v2, element='e1')
e2 = g.insert_edge(v2, v3, element='e2')
e3 = g.insert_edge(v3, v1, element='e3')
path = eulerian_cycle(g, v1)
assert path == [e1, e2, e3]
g = Graph(directed=True)
v1 = g.insert_vertex(element='v1')
v2 = g.insert_vertex(element='v2')
v3 = g.insert_vertex(element='v3')
e1 = g.insert_edge(v1, v2, element='e1')
e2 = g.insert_edge(v1, v3, element='e2')
e3 = g.insert_edge(v2, v1, element='e3')
e4 = g.insert_edge(v2, v3, element='e4')
e5 = g.insert_edge(v3, v1, element='e5')
e6 = g.insert_edge(v3, v2, element='e6')
path = eulerian_cycle(g, v1)
assert path == [e1, e3, e2, e6, e4, e5]
g = Graph(directed=True)
v1 = g.insert_vertex(element='v1')
v2 = g.insert_vertex(element='v2')
v3 = g.insert_vertex(element='v3')
v4 = g.insert_vertex(element='v4')
v5 = g.insert_vertex(element='v5')
e1 = g.insert_edge(v1, v2, element='e1')
e2 = g.insert_edge(v2, v3, element='e2')
e3 = g.insert_edge(v3, v4, element='e3')
e4 = g.insert_edge(v4, v2, element='e4')
e5 = g.insert_edge(v2, v5, element='e5')
e6 = g.insert_edge(v5, v1, element='e6')
path = eulerian_cycle(g, v2)
assert path == [e2, e3, e4, e5, e6, e1]