最小生成树-Prim算法实现

建立图

如果不了解算法思想,请移步 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)
上一篇:输入数字检测噪音


下一篇:2021-10-04(单元最短路建图,状压dp)