最小生成树是连接的无向图中的边子集.它将所有点连接在一起.没有任何循环.并且具
有最小可能的总边权.MST是一个生成树.其边权重之和尽可能小.
生成树的代价是树中所有边的权重之和.可以有很多颗生成树.最小生成树是所有生成
树中最小的树.
1.Prim算法:
Prim算法也使用贪心算法来寻找最小生成树.在Prim算法中.从起始位置开始生成树.
与Kruskal算法不同.Prim算法将顶点添加到不断增长的生成树中.
2.应用场景:
网络设计:
在计算机网络中.设计高效的网络拓扑非常重要.最小生成树可用于识别连接网络中所
有节点需要的最小连接集.
交通系统:
最小生成树可用于寻找连接一个国家所有城市的最低成本.可用于规划货物和服务交
通的运输.
图像处理:
在图像处理中.最小生成树可以用于识别给定图像的最小生成树,并分析图像结构.
3.Prim算法介绍:
Prim算法是一种贪心算法.用于从图中找到最小生成树.Prim算法找到包含图的每个
顶点的边的子集.以便可以最小化边的权重之和.Prim算法从单个节点开始.并在每一
步探索所有具有连接边的相邻节点.因为选择了具有最小权重的边.所以图中没有循环.
4.Prim算法步骤:
使用随机选择顶点初始化一个最小生成树.
找到将步骤一生成的树与新顶点连接起来的所有边.从找到的边中选择最小边将其添加到树中.
重复步骤二直到形成最小生成树.
5.实现:
5.1方法:
package data
import "math"
const MAX = math.MaxInt32
func Prims(graph [][]int, n int) int {
//初始化变量.
key := make([]int, n)
mst := make([]int, n)
visited := make([]bool, n)
for i := 0; i < n; i++ {
key[i] = MAX
mst[i] = -1
}
key[0] = 0
mst[0] = -1
//寻找最小生成树.
for i := 0; i < n-1; i++ {
minIndex := findMinVertex(key, visited, n)
visited[minIndex] = true
for j := 0; j < n; j++ {
if graph[minIndex][j] != 0 && !visited[j] && graph[minIndex][j] < key[j] {
key[j] = graph[minIndex][j]
mst[j] = minIndex
}
}
}
//计算最小生成树的权重.
sum := 0
for i := 1; i < n; i++ {
sum += graph[i][mst[i]]
}
return sum
}
func findMinVertex(key []int, visited []bool, n int) int {
min := MAX
minIndex := -1
for i := 0; i < n; i++ {
if visited[i] == false && key[i] < min {
min = key[i]
minIndex = i
}
}
return minIndex
}
5.2main方法:
func main() {
graph := [][]int{
{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},
}
fmt.Println("最小生成树的权重", data.Prims(graph, 5))
}
6.实战:
6.1方法:
// 最小生成树的prim算法.
func MinCost(points [][]int) (ans int) {
n := len(points)
dis := make([]int, n)
x, y := points[0][0], points[0][1]
for i := range dis {
dis[i] = absPrim(points[i][0]-x) + abs(points[i][1]-y)
}
mark := make([]bool, n)
for {
chosen, min := -1, 1_000_000_000
for i := range dis {
if !mark[i] && dis[i] < min {
min, chosen = dis[i], i
}
}
if chosen == -1 {
break
}
mark[chosen] = true
ans += dis[chosen]
for i := range dis {
if mark[i] {
continue
}
d := absPrim(points[i][0]-points[chosen][0]) + absPrim(points[i][1]-points[chosen][1])
if dis[i] > d {
dis[i] = d
}
}
}
return
}
func absPrim(x int) int {
if x < 0 {
return -x
}
return x
}
6.2main方法:
func main() {
points := [][]int{{1, 2}, {3, 4}}
res := data.MinCost(points)
fmt.Println(res)
}
辞去经年.
如果大家喜欢我的分享话.可以关注我的微信公众号
念何架构之路