Skip to content

Commit 879d9d9

Browse files
committed
添加无向无权图的最短路径、环检测、二部图检测算法实现
1 parent c0f129d commit 879d9d9

File tree

6 files changed

+232
-16
lines changed

6 files changed

+232
-16
lines changed

Graph_BFS/BiPartitionDetection.py

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
"""
2+
@author: Alex
3+
@contact: 1272296763@qq.com or jakinmili@gmail.com
4+
@file: BiPartitionDetection.py
5+
@time: 2019/10/26 16:11
6+
"""
7+
import queue
8+
class BiPartitionDetection:
9+
10+
def __init__(self, filename):
11+
self.V = 0 # 顶点数
12+
self.E = 0 # 边数
13+
self.adj = None
14+
self.__initGraph(filename)
15+
self.__isBiPartitie = True
16+
17+
# 检测二部图
18+
self.visited = [False for i in range(self.V)]
19+
self.colors = [-1 for i in range(self.V)]
20+
for v in range(self.V):
21+
if self.visited[v] == False:
22+
if self.bfs(v) == False:
23+
self.__isBiPartitie = False
24+
break
25+
26+
27+
def __initGraph(self, filename):
28+
with open(filename) as f:
29+
line_num = 0 # 第一行是顶点数和边数
30+
for line in f:
31+
if line_num == 0:
32+
v, e = line.strip().split()
33+
self.V = int(v)
34+
self.E = int(e)
35+
self.adj = [[] for i in range(self.V)] # 创建二维数组即邻接表
36+
else:
37+
# 读取边 写入邻接表
38+
v1, v2 = line.strip().split()
39+
# 转化为整数
40+
v1 = int(v1)
41+
v2 = int(v2)
42+
self.adj[v1].append(v2)
43+
self.adj[v2].append(v1)
44+
line_num += 1
45+
46+
def bfs(self, s):
47+
que = queue.Queue(self.V)
48+
# 往队列中添加顶点s
49+
que.put(s)
50+
self.visited[s] = True
51+
self.colors[s] = 0
52+
53+
while que.empty() == False:
54+
v = que.get()
55+
56+
for w in self.adj[v]:
57+
if self.visited[w] == False:
58+
que.put(w)
59+
self.visited[w] = True
60+
self.colors[w] = 1 - self.colors[v]
61+
elif self.colors[w] == self.colors[v]:
62+
return False
63+
return True
64+
65+
def isBiPartite(self):
66+
return self.__isBiPartitie
67+
68+
if __name__ == '__main__':
69+
print("=====first graph======")
70+
g = BiPartitionDetection("g.txt")
71+
print(g.isBiPartite())
72+
print("=====second graph======")
73+
g = BiPartitionDetection("g2.txt")
74+
print(g.isBiPartite())
75+
print("=====third graph======")
76+
g = BiPartitionDetection("g3.txt")
77+
print(g.isBiPartite())

Graph_BFS/USSSPath.py

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
"""
2+
@author: Alex
3+
@contact: 1272296763@qq.com or jakinmili@gmail.com
4+
@file: USSSPath.py
5+
@time: 2019/10/26 16:41
6+
"""
7+
import queue
8+
class USSSPath:
9+
10+
def __init__(self, filename, s):
11+
self.V = 0 # 顶点数
12+
self.E = 0 # 边数
13+
self.adj = None
14+
self.__initGraph(filename)
15+
16+
# 计算路径和最短路径
17+
self.visited = [False for i in range(self.V)]
18+
self.__dis = [-1 for i in range(self.V)] # 记录每个结点离根节点的最小距离
19+
self.pre = [-1 for i in range(self.V)] # 每一个结点的上一个结点
20+
self.s = s
21+
self.bfs(s)
22+
23+
def __initGraph(self, filename):
24+
with open(filename) as f:
25+
line_num = 0 # 第一行是顶点数和边数
26+
for line in f:
27+
if line_num == 0:
28+
v, e = line.strip().split()
29+
self.V = int(v)
30+
self.E = int(e)
31+
self.adj = [[] for i in range(self.V)] # 创建二维数组即邻接表
32+
else:
33+
# 读取边 写入邻接表
34+
v1, v2 = line.strip().split()
35+
# 转化为整数
36+
v1 = int(v1)
37+
v2 = int(v2)
38+
self.adj[v1].append(v2)
39+
self.adj[v2].append(v1)
40+
line_num += 1
41+
42+
def get_graph_information(self):
43+
"""
44+
打印图的邻接表
45+
:return:
46+
"""
47+
print("V={}, E={}".format(self.V, self.E))
48+
for i, v in enumerate(self.adj):
49+
print("{} : {}".format(i, v))
50+
51+
def validateVertex(self, v):
52+
"""
53+
验证顶点取值
54+
:param v:
55+
:return:
56+
"""
57+
if v<0 or v>=self.V:
58+
raise ValueError("v值超出范围")
59+
60+
def bfs(self, s):
61+
que = queue.Queue(self.V)
62+
self.visited[s] = True
63+
que.put(s)
64+
self.pre[s] = s
65+
self.__dis[s] = 0
66+
while que.empty() == False:
67+
v = que.get()
68+
69+
for w in self.adj[v]:
70+
if self.visited[w] == False:
71+
que.put(w)
72+
self.visited[w] = True
73+
self.pre[w] = v
74+
self.__dis[w] = self.__dis[v] + 1
75+
76+
def isConnectedTo(self, t):
77+
self.validateVertex(t)
78+
return self.visited[t]
79+
80+
def dis(self, t):
81+
self.validateVertex(t)
82+
print("{} -> {}的距离为:{}".format(self.s, t, self.__dis[t]))
83+
84+
def path(self, t):
85+
res = []
86+
if self.isConnectedTo(t) == False:
87+
return res
88+
cur = t
89+
while cur != self.s:
90+
res.append(cur)
91+
cur = self.pre[cur]
92+
res.append(self.s)
93+
94+
res.reverse()
95+
print("{} -> {}的路径为:{}".format(self.s, t, res))
96+
97+
if __name__ == '__main__':
98+
usssp = USSSPath("../g_ssp.txt", 0)
99+
usssp.get_graph_information()
100+
usssp.path(6)
101+
usssp.dis(6)

Graph_BFS/g.txt

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

Graph_BFS/g2.txt

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

Graph_BFS/g3.txt

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

readme.md

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -110,20 +110,22 @@ BFS类中,和树的广度优先遍历类似,区别在于图的广度优先遍
110110
bfs.get_BFSorder()
111111

112112
> PS:此处可以注意到dfs和bfs的在非递归实现的相同之处,除了使用不同的数据结构存放遍历过程的数据外,其他基本相同
113-
> visited[0 .... v-1] = false
114-
> for v in range(self.V):
115-
> if visited[v] == False:
116-
> search(v)
117-
>
118-
> search(s):
119-
> x.push(s)
120-
> visited[s] = True
121-
> while !x.isEmplty():
122-
> v = x.pop()
123-
> for w in self.adj[w]:
124-
> if visited[w] == False:
125-
> x.push(w)
126-
> visited[w] = True
113+
114+
visited[0 .... v-1] = false
115+
for v in range(self.V):
116+
if visited[v] == False:
117+
search(v)
118+
119+
search(s):
120+
x.push(s)
121+
visited[s] = True
122+
while !x.isEmplty():
123+
v = x.pop()
124+
for w in self.adj[w]:
125+
if visited[w] == False:
126+
x.push(w)
127+
visited[w] = True
128+
127129
> 此处当x为栈时,为广度优先遍历,为队列的时候为深度优先遍历,除此之外还可以是随机队列等其他数据结构,发挥不同的作用
128130
129131
#### 2.2 环检测
@@ -140,5 +142,22 @@ SingleSourcePath类中
140142
ssp.path(4)
141143

142144
#### 2.4 二部图检测
143-
144-
#### 2.5 最短路径(注意!此处是无向无权图)
145+
BiPartitionDetection类中
146+
147+
print("=====first graph======")
148+
g = BiPartitionDetection("g.txt")
149+
print(g.isBiPartite())
150+
print("=====second graph======")
151+
g = BiPartitionDetection("g2.txt")
152+
print(g.isBiPartite())
153+
print("=====third graph======")
154+
g = BiPartitionDetection("g3.txt")
155+
print(g.isBiPartite())
156+
157+
#### 2.5 最短路径(注意!此处是无向无权图)
158+
USSSPath类中
159+
160+
usssp = USSSPath("../g_ssp.txt", 0)
161+
usssp.get_graph_information()
162+
usssp.path(6)
163+
usssp.dis(6)

0 commit comments

Comments
 (0)