最小生成树(prim 算法)

这篇博客详细介绍了如何运用Prim算法来找到加权无向图的最小生成树。通过示例展示了算法的每一步操作,包括节点的选取、边的更新以及最小生成树的构造过程。
摘要由CSDN通过智能技术生成

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选取一个点,并将该点的所有路径连通,如果新路径距离小于已有路径,则替换

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值