Skip to content

Commit 67c13a4

Browse files
committed
implement hamilton Loop
1 parent adfb713 commit 67c13a4

File tree

2 files changed

+68
-37
lines changed

2 files changed

+68
-37
lines changed

Hamilton/HamiltonLoop.py

+47-37
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
"""
22
@author: Alex
33
@contact: 1272296763@qq.com or jakinmili@gmail.com
4-
@file: AdjacencyList.py
4+
@file: HamiltonLoop.py
55
@time: 2019/10/20 19:12
66
"""
7-
class AdjList:
7+
class HamiltonLoop:
88

99
def __init__(self, filename):
1010
self.V = 0 # 顶点数
1111
self.E = 0 # 边数
1212
self.adj = None
13-
self.__cccount = 0 # 联通分量
13+
1414
with open(filename) as f:
1515
line_num = 0 # 第一行是顶点数和边数
1616
for line in f:
@@ -28,6 +28,10 @@ def __init__(self, filename):
2828
self.adj[v1].append(v2)
2929
self.adj[v2].append(v1)
3030
line_num += 1
31+
self.__visited = [False for i in range(self.V)]
32+
self.__pre = [-1 for i in range(self.V)]
33+
self.__end = -1
34+
self.graphDFS(0,0)
3135

3236
def get_graph_information(self):
3337
"""
@@ -67,43 +71,49 @@ def degree(self, v):
6771
self.validateVertex(v)
6872
return len(self.adj[v])
6973

74+
def allVisited(self):
75+
for v in range(self.V):
76+
if self.__visited[v] == False:
77+
return False
78+
return True
7079

71-
def graphDFS(self):
72-
visited = [False for i in range(self.V)]
73-
pre_order = [] # 前序遍历结果
74-
post_order = [] # 后序遍历结果
75-
cccount = 0 # 联通分量
80+
def graphDFS(self, v, parent):
7681

77-
def dfs(v):
78-
# 标记v顶点已经遍历过了
79-
visited[v] = True
80-
# 添加
81-
pre_order.append(v)
82-
for w in self.adj[v]:
83-
if visited[w] == False:
84-
dfs(w)
85-
# 此刻对某个顶点的邻点已经遍历结束
86-
post_order.append(v)
82+
# 标记v顶点已经遍历过了
83+
self.__visited[v] = True
84+
# 记录父亲结点
85+
self.__pre[v] = parent
8786

88-
# 顾及到有多个联通分量,对每个顶点都做DFS
89-
for i in range(self.V):
90-
if visited[i] == False:
91-
dfs(i)
92-
cccount += 1
93-
self.__cccount = cccount
94-
return pre_order,post_order
87+
for w in self.adj[v]:
88+
if self.__visited[w] == False:
89+
if self.graphDFS(w, v):
90+
return True
91+
elif w == 0 and self.allVisited():
92+
# 记录到达的最后一个结点
93+
self.__end = v
94+
return True
95+
# 找不到HamiltonLoop,开始回溯到上一个结点
96+
self.__visited[v] = False
97+
return False
9598

96-
def get_cccount(self):
97-
"""
98-
获取该图的联通分量
99-
:return:
100-
"""
101-
return self.__cccount
99+
def getHamiltonLoop(self):
100+
res = []
101+
if self.__end == -1:
102+
return res
103+
104+
cur = self.__end
105+
while cur != 0:
106+
res.append(cur)
107+
cur = self.__pre[cur]
108+
res.append(0)
109+
res.reverse()
110+
print(res)
102111

103112
if __name__ == '__main__':
104-
adjl = AdjList("../g.txt")
105-
adjl.get_graph_information()
106-
print(adjl.hasEdge(0,4))
107-
print(adjl.degree(1))
108-
print(adjl.graphDFS())
109-
print(adjl.get_cccount())
113+
hl = HamiltonLoop("g.txt")
114+
hl.get_graph_information()
115+
hl.getHamiltonLoop()
116+
117+
hl = HamiltonLoop("g2.txt")
118+
hl.get_graph_information()
119+
hl.getHamiltonLoop()

readme.md

+21
Original file line numberDiff line numberDiff line change
@@ -207,3 +207,24 @@ USSSPath类中
207207
fb1 = findCutPoint("../tree.txt")
208208
fb1.get_graph_information()
209209
fb1.findCutPoint()
210+
211+
### 4. 哈密顿图(Hamilton)
212+
213+
#### 4.1 哈密顿回路(Hamilton Loop)
214+
215+
1. 从顶点0开始dfs(0, 0)
216+
2. 对整个图模型进行dfs(w, v),其中v是w的父亲结点,dfs(w, v)返回的是true,说明找到Hamilton Loop Path
217+
3. 若此时已经回到顶点0了,并且所有顶点都已经访问过了,说明存在Hamilton Loop
218+
4. 如果在对每一个结点进行dfs的过程中找不到Hamilton Loop,则返回到上一个结点
219+
220+
> 返回Hamilton Loop Path的存储变量是, pre
221+
222+
223+
hl = HamiltonLoop("g.txt")
224+
hl.get_graph_information()
225+
hl.getHamiltonLoop()
226+
227+
hl = HamiltonLoop("g2.txt")
228+
hl.get_graph_information()
229+
hl.getHamiltonLoop()
230+

0 commit comments

Comments
 (0)