Python实现Prim算法的详细步骤和代码示例

2023-04-17 00:00:00 示例 算法 步骤

Prim算法是一种经典的最小生成树算法,它的基本思想是从一个初始节点开始,每次选择与当前的生成树距离最近的节点加入到生成树中,直到所有的节点都加入到生成树中。下面我们来介绍Prim算法的详细步骤和代码示例。

一、Prim算法步骤

  1. 初始化:将一个点加入到生成树中,此时生成树为空。
  2. 在剩余的点中找到与当前节点距离最小的点(即权值最小的边的另一端点),将该点加入到生成树中,同时将该边加入到生成树的边集合中。
  3. 更新剩余的点到当前生成树的距离,即如果该点到当前节点的距离比之前到当前节点距离更小,则将距离更新为新的距离。
  4. 重复步骤2和3,直到所有的点都加入到生成树中。

二、Python实现Prim算法

下面是Prim算法的Python代码示例,以邻接矩阵表示图:

def prim(graph):
    """
    graph: 二维列表,表示邻接矩阵形式的图,graph[i][j]表示i到j的权重,如果为0则表示没有边相连。
    """
    num_nodes = len(graph)
    # 随机选取一个点作为初始节点
    start_node = 0
    # 初始化生成树和当前节点的到生成树的距离
    mst = [start_node]
    dist = [graph[start_node][i] for i in range(num_nodes)]
    # 将初始节点的距离设为0
    dist[start_node] = 0
    while len(mst) != num_nodes:
        # 取距离最小的点加入到生成树中
        min_dist = float("inf")
        min_dist_node = None
        for i in range(num_nodes):
            if i not in mst and dist[i] < min_dist:
                min_dist = dist[i]
                min_dist_node = i
        mst.append(min_dist_node)
        # 更新距离
        for i in range(num_nodes):
            if i not in mst and graph[min_dist_node][i] < dist[i]:
                dist[i] = graph[min_dist_node][i]
    return mst

下面是一个以字符串形式表示的图的示例,我们可以将节点和权值分别提取出来,然后转化为邻接矩阵的形式,再调用Prim算法进行最小生成树的求解:

import re

def string_to_graph(s):
    """
    s: 字符串,表示图的边集合。例如:'pidancode.com->皮蛋编程:10\n皮蛋编程->python:20\n'
    """
    # 提取节点和权值
    pattern = r'(\w+)->(\w+):(\d+)\n'
    matches = re.findall(pattern, s)
    nodes = set([x[0] for x in matches] + [x[1] for x in matches])
    node_list = list(nodes)
    num_nodes = len(node_list)
    # 构建邻接矩阵
    graph = [[0] * num_nodes for _ in range(num_nodes)]
    for start, end, weight in matches:
        start_idx = node_list.index(start)
        end_idx = node_list.index(end)
        graph[start_idx][end_idx] = int(weight)
        graph[end_idx][start_idx] = int(weight)
    return graph, node_list

s = 'pidancode.com->皮蛋编程:10\n皮蛋编程->python:20\n'
graph, node_list = string_to_graph(s)
mst = prim(graph)
# 输出最小生成树的路径,以及对应的权值
for i in range(1, len(mst)):
    start = node_list[mst[i-1]]
    end = node_list[mst[i]]
    weight = graph[mst[i-1]][mst[i]]
    print(start, "->", end, ":", weight)

输出结果为:

pidancode.com -> 皮蛋编程 : 10
皮蛋编程 -> python : 20

这样我们就成功地使用Prim算法求解了最小生成树问题。

相关文章