📜  普里姆算法(1)

📅  最后修改于: 2023-12-03 15:10:31.793000             🧑  作者: Mango

普里姆算法介绍

普里姆算法是一种用来解决最小生成树(Minimum Spanning Tree)问题的贪心算法,它可以在加权连通图中找到一棵生成树,使得树的所有边之和最小。

原理

普里姆算法的原理很简单,先任选一个起始点,将其加入到生成树中,然后每次从未被加入到生成树中的点中选择一条与当前生成树相连的最小权值边加入到生成树中,直到所有点都被加入到生成树中为止。整个过程可以看做是不断地将点与生成树连通的过程,直到所有点都被连通。

实现

在实现普里姆算法时,我们需要用到一个数据结构来记录点的连通情况。可以使用一个数组来表示,数组中的元素记录该点是否被加入到生成树中,如果已经被加入,则标记为 true,否则为 false。另外,我们还需要借助一个优先队列来存储未被加入到生成树中的边,并按权值大小排序。

以下是普里姆算法的 Python3 代码实现:

import heapq

def prim(graph, start):
    n = len(graph)
    visited = [False] * n  # 标记节点是否加入到生成树中
    visited[start] = True  # 将起始点加入到生成树中

    edges = [[] for _ in range(n)]  # 存储每个节点及其与其他节点相连的边
    for i in range(n):
        for j in range(n):
            if graph[i][j] != 0:
                edges[i].append((j, graph[i][j]))

    min_heap = edges[start][:]
    heapq.heapify(min_heap)

    mst = []  # 存储最小生成树的边
    while min_heap:
        (w, v) = heapq.heappop(min_heap)  # 取出一条最小权值边
        if visited[v]:  # 如果该边指向的节点已经加入到生成树中,就跳过
            continue
        visited[v] = True  # 将该点加入到生成树中
        mst.append((w, v))  # 将该边加入到最小生成树中
        for neighbor in edges[v]:
            if not visited[neighbor[0]]:
                heapq.heappush(min_heap, neighbor)  # 将该点与其未被访问的相邻节点加入到堆中

    return mst
总结

普里姆算法的时间复杂度为 O(E log V),其中 E 表示边的数量,V 表示点的数量。在实际应用中,普里姆算法经常用来解决连通性问题,比如最小通信开销、最优电缆布线、最优铁路布线等。它是一种简单易懂、实现简单、效率较高的算法。