输入:一个加权连通图,其中顶点集合为V,边集合为E; 初始化:Vn = {x},其中x为集合V中的任一节点(起始点),Enew = {}; 重复下列操作,直到Vn = V: 在集合E中选取权值最小的边(u, v),其中u为集合Vn中的元素,而v则是V中没有加入Vn的顶点(如果存在有多条满足前述条件即具有相同权值的边,则可任意选取其中之一); 将v加入集合Vn中,将(u, v)加入集合En中; 输出:使用集合Vn和En来描述所得到的最小生成树。 以下面这张图作为例子,表格中的Vertex、Kown、Cost、Path分别表示顶点信息、是否访问过,权值,到达路径; 我们随机的选择顶点0作为起点,其执行步骤为: 步骤 选中结点 顶点0作为起始点 0 根据(6, 7, 8)的方案选中6 1 根据顶点1能够到达的权值(7, 4, 3)和顶点0能够到达的权值(7, 8)中选择3 5 根据顶点5能够到达的权值(8)和根据顶点1能够到达的权值(7, 4)和顶点0能够到达的权值(7, 8)中选择4 6 根据顶点6能够到达的权值(6, 7)和顶点0能够到达的权值(7)中选择6 2 根据顶点0能够到达的权值(7)和顶点6能够到达的权值(7)中选择7 4 根据顶点6能够到达的权值(7)选择7 7 根据顶点7能够到达的权值(2)选择2 3 全部结点都访问过,退出 最终得到下面的结果,其中Path中的-1表示其作为起始点; ): def __init__(self, graph): self.graph = graph self.N = len(self.graph) pass def prim(self, start): index = start cost, path = [0] * self.N, [0] * self.N # 初始化起点 known = [x for x in map(lambda x: True if x == start else False, [x for x in range(self.N)])] path[start] = -1 for i in range(self.N): cost[i] = self.graph[start][i] # 遍历其余各个结点 for i in range(1, self.N): mi = 1e9 # 找出相对最小权重的结点 for j in range(self.N): if not known[j] and mi > cost[j]: mi, index = cost[j], j # 计算路径值 for j in range(self.N): if self.graph[j][index] == mi: path[index] = j known[index] = True # 更新index连通其它结点的权重 for j in range(self.N): if not known[j] and cost[j] > self.graph[index][j]: cost[j] = self.graph[index][j] print(path) # 图用临接矩阵表示 MST([ [1e9, 6, 8, 1e9, 7, 1e9, 1e9, 1e9], [6, 1e9, 7, 1e9, 1e9, 3, 4, 1e9], [8, 7, 1e9, 1e9, 1e9, 1e9, 6, 1e9], [1e9, 1e9, 1e9, 1e9, 1e9, 1e9, 1e9, 2], [7, 1e9, 1e9, 1e9, 1e9, 1e9, 1e9, 1e9], [1e9, 3, 1e9, 1e9, 1e9, 1e9, 1e9, 9], [1e9, 4, 6, 1e9, 1e9, 1e9, 1e9, 7], [1e9, 1e9, 1e9, 2, 1e9, 9, 7, 1e9], ]).prim(0) 相关文章: 2021-10-05 2021-05-08