建立图
如果不了解算法思想,请移步 http://c.biancheng.net/algorithm/prim.html
class Graph:
def __init__(self,vertex_num,edges):
# 权重初始化为无穷
self.vertex_num = vertex_num
self.edges = np.zeros(shape=(vertex_num,vertex_num),dtype=int)
self.edges = self.edges+np.inf
# 对角线初始化为0
for i in range(vertex_num):
self.edges[i][i] = 0
# 初始化边
for i,j,weight in edges:
self.edges[i][j] = weight
def prim(self,start):
pass
vertex_num = 6
edges = [
(0,1,6),(0,2,3),(0,4,7),
(1,0,6),(1,2,4),(1,3,2),(1,5,5),
(2,0,3),(2,1,4),(2,3,3),(2,4,8),
(3,1,2),(3,2,3),(3,5,2),
(4,0,7),(4,2,8),
(5,1,5),(5,3,2)
]
graph = Graph(vertex_num,edges)
关键数据结构
需要一个静态链表parent来表示生成树(树的双亲表示法)
需要一个dist数组表示当前生成树距离各个顶点的距离
parent = {}
dist = {}
初始化
然后有一个非常关键的步骤是dist和parent的初始化。
此时dist中已经有一个起点start
初始化dist为start到其它顶点的距离
start的邻接点的parent需要初始化为start
# 初始化距离
for i in range(self.vertex_num):
dist[i] = self.edges[start][i]
parent[i] = start
parent[start] = -1
循环过程
找到离树最近的顶点
# 取出离树最近的顶点
min_dist = np.inf
min_vertex = 0
for i in range(self.vertex_num):
if dist[i] and dist[i]<min_dist:
min_dist = dist[i]
min_vertex = i
然后将该顶点添加到树中,即将dist[min_vertex]置零即可
# 将min_vertex添加到树中
dist[min_vertex] = 0
# 更新该顶点的邻接节点到树的距离
for i in range(self.vertex_num):
if dist[i] and self.edges[min_vertex][i]<dist[i]:
dist[i] = self.edges[min_vertex][i]
parent[i] = min_vertex
循环上面两个过程,直到所有的节点都添加到树中
# 当找不到最近的节点时,也就是说所有的节点都在树中,即可退出
if min_dist==np.inf:
break
完整代码
class Graph:
def __init__(self,vertex_num,edges):
# 权重初始化为无穷
self.vertex_num = vertex_num
self.edges = np.zeros(shape=(vertex_num,vertex_num),dtype=int)
self.edges = self.edges+np.inf
# 对角线初始化为0
for i in range(vertex_num):
self.edges[i][i] = 0
# 初始化边
for i,j,weight in edges:
self.edges[i][j] = weight
def prim(self,start):
# 表示树
parent = {}
# 表示当前树到各个顶点的距离,已经在树内的顶点距离为0
# 与树邻接的顶点距离为weight,不相邻的顶点距离为无穷大
dist = {}
# 初始化距离
for i in range(self.vertex_num):
dist[i] = self.edges[start][i]
parent[i] = start
parent[start] = -1
while True:
# 取出离树最近的顶点
min_dist = np.inf
min_vertex = 0
for i in range(self.vertex_num):
if dist[i] and dist[i]<min_dist:
min_dist = dist[i]
min_vertex = i
# 当找不到最近的节点时,也就是说所有的节点都在树中,即可退出
if min_dist==np.inf:
break
# 将min_vertex添加到树中
dist[min_vertex] = 0
# 更新该顶点的邻接节点到树的距离
for i in range(self.vertex_num):
if dist[i] and self.edges[min_vertex][i]<dist[i]:
dist[i] = self.edges[min_vertex][i]
parent[i] = min_vertex
return parent
vertex_num = 6
edges = [
(0,1,6),(0,2,3),(0,4,7),
(1,0,6),(1,2,4),(1,3,2),(1,5,5),
(2,0,3),(2,1,4),(2,3,3),(2,4,8),
(3,1,2),(3,2,3),(3,5,2),
(4,0,7),(4,2,8),
(5,1,5),(5,3,2)
]
graph = Graph(vertex_num,edges)
graph.prim(0)