Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 506c5c1

Browse files
Euler图的实现和Euler Loop algorithm
1 parent d31f179 commit 506c5c1

File tree

10 files changed

+419
-0
lines changed

10 files changed

+419
-0
lines changed

‎Euler/EulerLoop.py‎

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
"""
2+
@author: Alex
3+
@contact: 1272296763@qq.com or jakinmili@gmail.com
4+
@file: EulerLoop.py
5+
@time: 2019年10月20日 19:12
6+
"""
7+
class EulerLoop:
8+
9+
def __init__(self, filename):
10+
self.V = 0 # 顶点数
11+
self.E = 0 # 边数
12+
self.adj = None
13+
self.__cccount = 0 # 联通分量
14+
self.__visited = None
15+
16+
with open(filename) as f:
17+
line_num = 0 # 第一行是顶点数和边数
18+
for line in f:
19+
if line_num == 0:
20+
v, e = line.strip().split()
21+
self.V = int(v)
22+
self.E = int(e)
23+
self.adj = [[] for i in range(self.V)] # 创建二维数组即邻接表
24+
else:
25+
# 读取边 写入邻接表
26+
v1, v2 = line.strip().split()
27+
# 转化为整数
28+
v1 = int(v1)
29+
v2 = int(v2)
30+
self.adj[v1].append(v2)
31+
self.adj[v2].append(v1)
32+
line_num += 1
33+
34+
# dfs遍历
35+
self.graphDFS()
36+
37+
def get_graph_information(self):
38+
"""
39+
打印图的邻接表
40+
:return:
41+
"""
42+
print("V={}, E={}".format(self.V, self.E))
43+
for i, v in enumerate(self.adj):
44+
print("{} : {}".format(i, v))
45+
46+
def validateVertex(self, v):
47+
"""
48+
验证顶点取值
49+
:param v:
50+
:return:
51+
"""
52+
if v<0 or v>=self.V:
53+
raise ValueError("v值超出范围")
54+
55+
56+
57+
def hasEdge(self, v, w):
58+
"""
59+
判断两个顶点是否存在
60+
:param v: 第一个顶点
61+
:param w: 第二个顶点
62+
:return: true or false
63+
"""
64+
self.validateVertex(v)
65+
self.validateVertex(w)
66+
return w in self.adj[v]
67+
68+
def degree(self, v):
69+
"""
70+
求某个顶点的度
71+
:param v:
72+
:return:
73+
"""
74+
self.validateVertex(v)
75+
return len(self.adj[v])
76+
77+
78+
def graphDFS(self):
79+
visited = [-1 for i in range(self.V)]
80+
cccount = 0 # 联通分量
81+
82+
def dfs(v, ccid):
83+
# 标记v顶点已经遍历过了
84+
visited[v] = ccid
85+
# 添加
86+
for w in self.adj[v]:
87+
if visited[w] == -1:
88+
dfs(w, ccid)
89+
# 此刻对某个顶点的邻点已经遍历结束
90+
91+
# 顾及到有多个联通分量,对每个顶点都做DFS
92+
for i in range(self.V):
93+
if visited[i] == -1:
94+
dfs(i, cccount)
95+
cccount += 1
96+
self.__cccount = cccount
97+
self.__visited = visited
98+
99+
100+
def get_cccount(self):
101+
"""
102+
获取该图的联通分量大小
103+
:return:
104+
"""
105+
return self.__cccount
106+
107+
108+
def hasEulerLoop(self):
109+
110+
# 联通分量判断
111+
if self.get_cccount() > 1:
112+
print("该图不存在欧拉回路(Euler Loop)")
113+
return False
114+
115+
# 度数判断
116+
for v in range(self.V):
117+
if self.degree(v) % 2 == 1:
118+
print("该图不存在欧拉回路(Euler Loop)")
119+
return False
120+
121+
print("该图存在欧拉回路(Euler Loop)")
122+
return True
123+
124+
if __name__ == '__main__':
125+
ELD = EulerLoopDetection("g.txt")
126+
ELD.get_graph_information()
127+
ELD.hasEulerLoop()
128+
129+
ELD2 = EulerLoopDetection("g2.txt")
130+
ELD2.get_graph_information()
131+
ELD2.hasEulerLoop()

‎Euler/EulerLoopDetection.py‎

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
"""
2+
@author: Alex
3+
@contact: 1272296763@qq.com or jakinmili@gmail.com
4+
@file: EulerLoopDetection.py
5+
@time: 2019年10月20日 19:12
6+
"""
7+
class EulerLoopDetection:
8+
9+
def __init__(self, filename):
10+
self.V = 0 # 顶点数
11+
self.E = 0 # 边数
12+
self.adj = None
13+
self.__cccount = 0 # 联通分量
14+
self.__visited = None
15+
16+
with open(filename) as f:
17+
line_num = 0 # 第一行是顶点数和边数
18+
for line in f:
19+
if line_num == 0:
20+
v, e = line.strip().split()
21+
self.V = int(v)
22+
self.E = int(e)
23+
self.adj = [[] for i in range(self.V)] # 创建二维数组即邻接表
24+
else:
25+
# 读取边 写入邻接表
26+
v1, v2 = line.strip().split()
27+
# 转化为整数
28+
v1 = int(v1)
29+
v2 = int(v2)
30+
self.adj[v1].append(v2)
31+
self.adj[v2].append(v1)
32+
line_num += 1
33+
34+
# dfs遍历
35+
self.graphDFS()
36+
37+
def get_graph_information(self):
38+
"""
39+
打印图的邻接表
40+
:return:
41+
"""
42+
print("V={}, E={}".format(self.V, self.E))
43+
for i, v in enumerate(self.adj):
44+
print("{} : {}".format(i, v))
45+
46+
def validateVertex(self, v):
47+
"""
48+
验证顶点取值
49+
:param v:
50+
:return:
51+
"""
52+
if v<0 or v>=self.V:
53+
raise ValueError("v值超出范围")
54+
55+
def hasEdge(self, v, w):
56+
"""
57+
判断两个顶点是否存在
58+
:param v: 第一个顶点
59+
:param w: 第二个顶点
60+
:return: true or false
61+
"""
62+
self.validateVertex(v)
63+
self.validateVertex(w)
64+
return w in self.adj[v]
65+
66+
def degree(self, v):
67+
"""
68+
求某个顶点的度
69+
:param v:
70+
:return:
71+
"""
72+
self.validateVertex(v)
73+
return len(self.adj[v])
74+
75+
76+
def graphDFS(self):
77+
visited = [-1 for i in range(self.V)]
78+
cccount = 0 # 联通分量
79+
80+
def dfs(v, ccid):
81+
# 标记v顶点已经遍历过了
82+
visited[v] = ccid
83+
# 添加
84+
for w in self.adj[v]:
85+
if visited[w] == -1:
86+
dfs(w, ccid)
87+
# 此刻对某个顶点的邻点已经遍历结束
88+
89+
# 顾及到有多个联通分量,对每个顶点都做DFS
90+
for i in range(self.V):
91+
if visited[i] == -1:
92+
dfs(i, cccount)
93+
cccount += 1
94+
self.__cccount = cccount
95+
self.__visited = visited
96+
97+
98+
def get_cccount(self):
99+
"""
100+
获取该图的联通分量大小
101+
:return:
102+
"""
103+
return self.__cccount
104+
105+
106+
def hasEulerLoop(self):
107+
108+
# 联通分量判断
109+
if self.get_cccount() > 1:
110+
print("该图不存在欧拉回路(Euler Loop)")
111+
return False
112+
113+
# 度数判断
114+
for v in range(self.V):
115+
if self.degree(v) % 2 == 1:
116+
print("该图不存在欧拉回路(Euler Loop)")
117+
return False
118+
119+
print("该图存在欧拉回路(Euler Loop)")
120+
return True
121+
122+
if __name__ == '__main__':
123+
ELD = EulerLoopDetection("g.txt")
124+
ELD.get_graph_information()
125+
ELD.hasEulerLoop()
126+
127+
ELD2 = EulerLoopDetection("g2.txt")
128+
ELD2.get_graph_information()
129+
ELD2.hasEulerLoop()

‎Euler/__init__.py‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
"""
2+
@author: Alex
3+
@contact: 1272296763@qq.com or jakinmili@gmail.com
4+
@file: __init__.py.py
5+
@time: 2019年11月15日 13:03
6+
"""
7+

‎Euler/g.txt‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
5 6
2+
0 1
3+
0 2
4+
1 2
5+
2 3
6+
2 4
7+
3 4

‎Euler/g2.txt‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
11 15
2+
0 1
3+
0 3
4+
1 2
5+
1 4
6+
1 5
7+
2 5
8+
3 4
9+
4 5
10+
4 6
11+
5 7
12+
6 7
13+
7 8
14+
7 9
15+
8 10
16+
9 10

‎WeightedGraph/__init__.py‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
"""
2+
@author: Alex
3+
@contact: 1272296763@qq.com or jakinmili@gmail.com
4+
@file: __init__.py.py
5+
@time: 2019年11月16日 16:31
6+
"""
7+

‎WeightedGraph/g.txt‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
7 12
2+
0 1 2
3+
0 3 7
4+
0 5 2
5+
1 2 1
6+
1 3 4
7+
1 4 3
8+
1 5 5
9+
2 4 4
10+
2 5 4
11+
3 4 1
12+
3 6 5
13+
4 6 7

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /