cite from
https://www.jianshu.com/p/efcd21494dff
https://www.geeksforgeeks.org/prims-minimum-spanning-tree-mst-greedy-algo-5/
# -*- coding: utf-8 -*-
"""
Created on Sat Mar 28 15:44:28 2020
@author: tm_sh
"""
# A Python program for Prim's Minimum Spanning Tree (MST) algorithm.
# The program is for adjacency matrix representation of the graph
import sys # Library for INT_MAX
class Graph():
def __init__(self, vertices):
self.V = vertices
self.graph = [[0 for column in range(vertices)]
for row in range(vertices)]
# A utility function to print the constructed MST stored in parent[], according to numerical order
def printMST(self, parent):
print ("Edge \tWeight")
for i in range(1, self.V):
print (parent[i], "-", i, "\t", self.graph[i][ parent[i] ],'\n')
# A utility function to find the vertex with minimum distance value, from the set of vertices not yet included in shortest path tree
# key[v] is the closest dist from a point to no.v point
def minKey(self, key, mstSet):
# Initilaize min value
min = sys.maxsize
for v in range(self.V):
if key[v] < min and mstSet[v] == False:
min = key[v]
min_index = v
print ("minkey在v=",v,"次的输出是min=",min,"与u=min_index=",min_index,'\n')
return min_index
# Function to construct and print MST for a graph
# represented using adjacency matrix representation
def primMST(self):
# Key values used to pick minimum weight edge in cut
key = [sys.maxsize] * self.V #initially key is all INF, if a road is built up, then update it in update block
parent = [None] * self.V # Array to store constructed MST
# Make key 0 so that this vertex is picked as first vertex
key[0] = 0
mstSet = [False] * self.V #boolean array used to judge whether vertices are included in shortest path tree
parent[0] = -1 # First node is always the root of
for cout in range(self.V):
# Pick the minimum distance vertex from the set of vertices not yet processed.
# u is always equal to src/source in first iteration
print ("在cout=",cout,"时")
u = self.minKey(key, mstSet)
# Put the minimum distance vertex in the shortest path tree
mstSet[u] = True
print ("mstSet是:",mstSet)
# This is update block
# Update dist value of the adjacent vertices of the picked vertex
# only if the current distance is greater than new distance and the vertex in not in the shotest path tree
for v in range(self.V):
# graph[u][v] is non zero only for adjacent vertices of m
# mstSet[v] is false for vertices not yet included in MST
# Update the key only if graph[u][v] is smaller than key[v]
if self.graph[u][v] > 0 and mstSet[v] == False and key[v] > self.graph[u][v]:
key[v] = self.graph[u][v]
parent[v] = u
print ("update块的","v是",v,"时","update块的key[v]是",key,"parent[v]是",parent,'\n')
self.printMST(parent)
print ("example #1",'\n')
g = Graph(5)
g.graph = [ [0, 2, 0, 6, 0],
[2, 0, 3, 8, 5],
[0, 3, 0, 0, 7],
[6, 8, 0, 0, 9],
[0, 5, 7, 9, 0]]
g.primMST();
print ("example #2",'\n')
g = Graph(5)
g.graph = [ [0, 2, 0, 8, 0],
[2, 0, 3, 6, 5],
[0, 3, 0, 0, 7],
[8, 6, 0, 0, 9],
[0, 5, 7, 9, 0]]
g.primMST();
print ("example #3",'\n')
g = Graph(6)
g.graph = [ [0,7,4,0,0,0],
[7,0,6,2,0,4],
[4,6,0,0,9,8],
[0,2,0,0,0,7],
[0,0,9,0,0,1],
[0,4,8,7,1,0]]
g.primMST();
# Contributed by Divyanshu Mehta
The results are:
example #1
在cout= 0 时
minkey在v= 0 次的输出是min= 0 与u=min_index= 0
mstSet是: [True, False, False, False, False]
update块的 v是 1 时 update块的key[v]是 [0, 2, 9223372036854775807, 9223372036854775807, 9223372036854775807] parent[v]是 [-1, 0, None, None, None]
update块的 v是 3 时 update块的key[v]是 [0, 2, 9223372036854775807, 6, 9223372036854775807] parent[v]是 [-1, 0, None, 0, None]
在cout= 1 时
minkey在v= 1 次的输出是min= 2 与u=min_index= 1
mstSet是: [True, True, False, False, False]
update块的 v是 2 时 update块的key[v]是 [0, 2, 3, 6, 9223372036854775807] parent[v]是 [-1, 0, 1, 0, None]
update块的 v是 4 时 update块的key[v]是 [0, 2, 3, 6, 5] parent[v]是 [-1, 0, 1, 0, 1]
在cout= 2 时
minkey在v= 2 次的输出是min= 3 与u=min_index= 2
mstSet是: [True, True, True, False, False]
在cout= 3 时
minkey在v= 3 次的输出是min= 6 与u=min_index= 3
minkey在v= 4 次的输出是min= 5 与u=min_index= 4
mstSet是: [True, True, True, False, True]
在cout= 4 时
minkey在v= 3 次的输出是min= 6 与u=min_index= 3
mstSet是: [True, True, True, True, True]
Edge Weight
0 - 1 2
1 - 2 3
0 - 3 6
1 - 4 5
example #2
在cout= 0 时
minkey在v= 0 次的输出是min= 0 与u=min_index= 0
mstSet是: [True, False, False, False, False]
update块的 v是 1 时 update块的key[v]是 [0, 2, 9223372036854775807, 9223372036854775807, 9223372036854775807] parent[v]是 [-1, 0, None, None, None]
update块的 v是 3 时 update块的key[v]是 [0, 2, 9223372036854775807, 8, 9223372036854775807] parent[v]是 [-1, 0, None, 0, None]
在cout= 1 时
minkey在v= 1 次的输出是min= 2 与u=min_index= 1
mstSet是: [True, True, False, False, False]
update块的 v是 2 时 update块的key[v]是 [0, 2, 3, 8, 9223372036854775807] parent[v]是 [-1, 0, 1, 0, None]
update块的 v是 3 时 update块的key[v]是 [0, 2, 3, 6, 9223372036854775807] parent[v]是 [-1, 0, 1, 1, None]
update块的 v是 4 时 update块的key[v]是 [0, 2, 3, 6, 5] parent[v]是 [-1, 0, 1, 1, 1]
在cout= 2 时
minkey在v= 2 次的输出是min= 3 与u=min_index= 2
mstSet是: [True, True, True, False, False]
在cout= 3 时
minkey在v= 3 次的输出是min= 6 与u=min_index= 3
minkey在v= 4 次的输出是min= 5 与u=min_index= 4
mstSet是: [True, True, True, False, True]
在cout= 4 时
minkey在v= 3 次的输出是min= 6 与u=min_index= 3
mstSet是: [True, True, True, True, True]
Edge Weight
0 - 1 2
1 - 2 3
1 - 3 6
1 - 4 5
example #3
在cout= 0 时
minkey在v= 0 次的输出是min= 0 与u=min_index= 0
mstSet是: [True, False, False, False, False, False]
update块的 v是 1 时 update块的key[v]是 [0, 7, 9223372036854775807, 9223372036854775807, 9223372036854775807, 9223372036854775807] parent[v]是 [-1, 0, None, None, None, None]
update块的 v是 2 时 update块的key[v]是 [0, 7, 4, 9223372036854775807, 9223372036854775807, 9223372036854775807] parent[v]是 [-1, 0, 0, None, None, None]
在cout= 1 时
minkey在v= 1 次的输出是min= 7 与u=min_index= 1
minkey在v= 2 次的输出是min= 4 与u=min_index= 2
mstSet是: [True, False, True, False, False, False]
update块的 v是 1 时 update块的key[v]是 [0, 6, 4, 9223372036854775807, 9223372036854775807, 9223372036854775807] parent[v]是 [-1, 2, 0, None, None, None]
update块的 v是 4 时 update块的key[v]是 [0, 6, 4, 9223372036854775807, 9, 9223372036854775807] parent[v]是 [-1, 2, 0, None, 2, None]
update块的 v是 5 时 update块的key[v]是 [0, 6, 4, 9223372036854775807, 9, 8] parent[v]是 [-1, 2, 0, None, 2, 2]
在cout= 2 时
minkey在v= 1 次的输出是min= 6 与u=min_index= 1
mstSet是: [True, True, True, False, False, False]
update块的 v是 3 时 update块的key[v]是 [0, 6, 4, 2, 9, 8] parent[v]是 [-1, 2, 0, 1, 2, 2]
update块的 v是 5 时 update块的key[v]是 [0, 6, 4, 2, 9, 4] parent[v]是 [-1, 2, 0, 1, 2, 1]
在cout= 3 时
minkey在v= 3 次的输出是min= 2 与u=min_index= 3
mstSet是: [True, True, True, True, False, False]
在cout= 4 时
minkey在v= 4 次的输出是min= 9 与u=min_index= 4
minkey在v= 5 次的输出是min= 4 与u=min_index= 5
mstSet是: [True, True, True, True, False, True]
update块的 v是 4 时 update块的key[v]是 [0, 6, 4, 2, 1, 4] parent[v]是 [-1, 2, 0, 1, 5, 1]
在cout= 5 时
minkey在v= 4 次的输出是min= 1 与u=min_index= 4
mstSet是: [True, True, True, True, True, True]
Edge Weight
2 - 1 6
0 - 2 4
1 - 3 2
5 - 4 1
1 - 5 4
分析:
以#3为例, 选取0号点为root,root与自己相连,初始key=[0,…,max]表明v号节点是否连接以及最小的连接距离,mstset=[false,…,false]表示u=min_index号点已被加入树, parent=[-1,none,none,none,none,none]表明v号点与parent[v]连接。
在cout= 0 时,minKey选取0号点,分析graph[0],update key=[0, 7, 4, max, max, max],mstSet是: [True, False, False, False, False, False],parent=[-1,0,0,none,none,none]
在cout= 1 时,minKey选取2号点,分析graph[2],mstSet是: [True, False, True, False, False, False],update key=[0, 6, 4, max, 9, 8], parent=[-1,2,0,none,2,2]
在cout= 2 时,minKey选取1号点,分析graph[1],mstSet是: [True, True, True, False, False, False],update key=[0, 6, 4, 2, 9, 4], parent=[-1,2,0,1,2,1]
在cout= 3 时,minKey选取3号点,分析graph[3],mstSet是: [True, True, True, True, False, False],key[5]<graph[3][5] , 没有update,3号点不会与5号点连接
在cout= 4 时,minKey选取5号点,分析graph[5],mstSet是: [True, True, True, True, False, True],update key=[0, 6, 4, 2, 1, 4], parent=[-1,2,0,1,5,1], 4号点与2号点的连接被替换为与5号点连接
在cout= 5 时,minKey选取4号点,分析graph[4],mstSet是: [True, True, True, True, True, True],update key=[0, 6, 4, 2, 1, 4], parent=[-1,2,0,1,5,1],
整体逻辑:每次minKey选取一个点,并将该点的所有路径连通,如果新路径距离小于已有路径,则替换