算法练习:最小生成树 (Minimum Spanning Tree)

(注:此贴是为了回答同事提出的一个问题而匆匆写就,算法代码只求得出答案为目的,效率方面还有很大的改进空间)

最小生成树是指对于给定的带权无向图,需要生成一个总权重最小的连通图。
其问题描述及算法可以详见:https://en.wikipedia.org/wiki/Minimum_spanning_tree
以下我选用其中一个简单的算法描述,编写 Python 代码尝试解决此问题。

下面是同事提出的问题的原图:

程序:

 1 # coding: utf-8
 2
 3 from sets import Set
 4
 5 def edge_name(v1, v2):
 6     if v1 < v2:
 7         return v1 + v2
 8     return v2 + v1
 9
10
11 # Prim algorithm
12 def mst(vectors, costs, vectors_in_g, edges_in_g):
13     if len(vectors) == len(vectors_in_g):
14         return (vectors_in_g, edges_in_g)
15
16     min_cost = max(costs.values()) + 1
17     remaining_vectors = vectors.difference(vectors_in_g)
18     next_vector = ‘‘
19     next_edge = ‘‘
20
21     for x in vectors_in_g:
22         for y in remaining_vectors:
23             ename = edge_name(x, y)
24             if ename not in costs:
25                 continue
26             cost = costs[ename]
27             if cost < min_cost:
28                 next_vector = y
29                 next_edge = ename
30                 min_cost = cost
31
32     if next_vector <> ‘‘ and next_edge <> ‘‘:
33         new_vectors_in_g = vectors_in_g.copy()
34         new_edges_in_g = edges_in_g[:]
35         new_vectors_in_g.add(next_vector)
36         new_edges_in_g.append(next_edge)
37
38         return mst(vectors, costs, new_vectors_in_g, new_edges_in_g)
39     else:
40         raise Exception("The MST can not be found.")
41
42 my_vectors = Set([‘a‘, ‘b‘, ‘c‘, ‘d‘, ‘e‘, ‘f‘, ‘g‘])
43 my_costs = {
44     ‘ab‘: 12,
45     ‘ad‘: 11,
46     ‘ae‘: 16,
47     ‘ag‘: 14,
48     ‘bc‘: 11,
49     ‘bd‘: 13,
50     ‘cd‘: 13,
51     ‘cf‘: 15,
52     ‘df‘: 16,
53     ‘ef‘: 15,
54     ‘eg‘: 10,
55     ‘fg‘: 14
56 }
57
58 vs, es = mst(my_vectors, my_costs, Set(list(my_vectors)[0]), [])
59
60 print vs
61 print es
62
63 total_cost = 0
64 for e in es:
65     total_cost += my_costs[e]
66
67 print total_cost

程序输出如下:

Set([‘a‘, ‘c‘, ‘b‘, ‘e‘, ‘d‘, ‘g‘, ‘f‘])
[‘ad‘, ‘ab‘, ‘bc‘, ‘ag‘, ‘eg‘, ‘fg‘]
72

从输出结果可知最优解的总权重72. 图示如下:

时间: 2024-08-11 09:56:36

算法练习:最小生成树 (Minimum Spanning Tree)的相关文章

【算法】关于图论中的最小生成树(Minimum Spanning Tree)详解

喜欢的话可以扫码关注我们的公众号哦,更多精彩尽在微信公众号[程序猿声] 本节纲要 什么是图(network) 什么是最小生成树 (minimum spanning tree) 最小生成树的算法 什么是图(network)? 这里的图当然不是我们日常说的图片或者地图.通常情况下,我们把图看成是一种由"顶点"和"边"组成的抽象网络.在各个"顶点"间可以由"边"连接起来,使两个顶点间相互关联起来.图的结构可以描述多种复杂的数据对象,

最小生成树 (Minimum Spanning Tree,MST) ---Kruskal算法

引导问题: 假设要在N个城市之间建立通信联络网,则连通N个城市只需要N - 1条线路.这时,自然会考虑这样一个问题,如何在最省经费的前提下建立这个通信网. 基于问题所建立的定义: 可以用联通网来表示N个城市以及N个城市之间可能设置的连通线路,其中网的顶点表示城市,边表示两城市之间的线路,赋予边的权值表示相应的代价.对于N个顶点的连通网可以建立许多不同的生成树,每一棵生成树都可以是一个通信网.现在,要选择这样一颗生成树,也就是使总的耗费最少,这个问题就是构造连通网的的最小代价生成树的问题,即最小生

Geeks : Kruskal’s Minimum Spanning Tree Algorithm 最小生成树

寻找图中最小连通的路径,图如下: 算法步骤: 1. Sort all the edges in non-decreasing order of their weight. 2. Pick the smallest edge. Check if it forms a cycle with the spanning tree formed so far. If cycle is not formed, include this edge. Else, discard it. 3. Repeat st

【HDU 4408】Minimum Spanning Tree(最小生成树计数)

Problem Description XXX is very interested in algorithm. After learning the Prim algorithm and Kruskal algorithm of minimum spanning tree, XXX finds that there might be multiple solutions. Given an undirected weighted graph with n (1<=n<=100) vertex

HDU 4408 Minimum Spanning Tree 最小生成树计数

Minimum Spanning Tree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) [Problem Description] XXX is very interested in algorithm. After learning the Prim algorithm and Kruskal algorithm of minimum spanning tree, XXX

CF609E. Minimum spanning tree for each edge

题解:随便构造一颗最小生成树 然后对于其他不在树上的边  考虑到 删除这条链上的最大值在把这条边加上去 能得到这条边所在的最小生成树 可以LCT维护 但是明显这个题是静态的树就没必要LCT 当然我觉得最优的是树剖以后ST nlogn的的复杂度 也可以树剖+线段树nlog^2的复杂度 #include <bits/stdc++.h> const int MAXN=2e5+10; #define ll long long using namespace std; ll read(){ ll x=0

[思维]Minimum Spanning Tree

题目描述 In the mathematical discipline of graph theory, the line graph of a simple undirected weighted graph G is another simple undirected weighted graph L(G) that represents the adjacency between every two edges in G. Precisely speaking, for an undire

11.5最小生成树(Minimum Spanning Trees)

11.5最小生成树(Minimum Spanning Trees) 对加权图求使得权值和最小的生成树,即为最小生成树,基于以点为基准和以边为基准,有两种求最小生成树的方法:Prim算法和Kruskal 最小生成树的具体算法实现 原文地址:https://www.cnblogs.com/SpicyArticle/p/12150738.html

HDOJ 题目4408 Minimum Spanning Tree(Kruskal+Matrix_Tree)

Minimum Spanning Tree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1408    Accepted Submission(s): 450 Problem Description XXX is very interested in algorithm. After learning the Prim algori