算法思路

问题

给定顶点集合为 V,边集合为 E,求最小生成树 T?

解过程

任意时刻的边都可以划分为到三个集合:

  • X:边的所有顶点都是最小生成树的一部分。
  • Y:边的末端节点不是最小生成树的一部分。
  • Z:其它。

从 Y 中选择权重最小的边,将其加入到 T 中。

优先级队列

该算法需要用到一个工具:优先级队列(从某个集合中选择最小的元素)。

  1         class PriorityQueue<T>2             where T : IComparable<T>3         {4             private T[] _items;5             private int _length;6 7             public PriorityQueue(int size)8             {9                 _items = new T[size];10             }11 12             public void EnQueue(T item)13             {14                 if (this.IsFull())15                 {16                     throw new InvalidOperationException("容量已满,不能插入!");17                 }18 19                 _items[_length++] = item;20                 this.MoveUp(_length - 1);21             }22 23             private void MoveUp(int index)24             {25                 var bottom = _items[index];26                 var current = index;27 28                 while (current > 0)29                 {30                     var parent = (current - 1) / 2;31                     if (_items[parent].CompareTo(bottom) < 0)32                     {33                         break;34                     }35 36                     _items[current] = _items[parent];37                     current = parent;38                 }39 40                 _items[current] = bottom;41             }42 43             public T DeQueue()44             {45                 if (this.IsEmpty())46                 {47                     throw new InvalidOperationException("容量已空,不能删除!");48                 }49 50                 var result = _items[0];51                 _items[0] = _items[--_length];52 53                 this.MoveDown(0);54 55                 return result;56             }57 58             private void MoveDown(int index)59             {60                 var top = _items[index];61                 var current = index;62 63                 while (current < _length)64                 {65                     var small = 0;66                     var left = 2 * current + 1;67                     var right = left + 1;68 69                     if (left < _length && right < _length)70                     {71                         if (_items[left].CompareTo(_items[right]) <= 0)72                         {73                             small = left;74                         }75                         else76                         {77                             small = right;78                         }79                     }80                     else if (left < _length)81                     {82                         small = left;83                     }84                     else85                     {86                         break;87                     }88 89                     if (_items[small].CompareTo(top) >= 0)90                     {91                         break;92                     }93 94                     _items[current] = _items[small];95                     current = small;96                 }97 98                 _items[current] = top;99             }
100
101             public bool IsFull()
102             {
103                 return _length == _items.Length;
104             }
105
106             public bool IsEmpty()
107             {
108                 return _length == 0;
109             }
110         }

最小生成树代码

  1         class Edge : IComparable<Edge>2         {3             public int StartIndex { get; set; }4 5             public int EndIndex { get; set; }6 7             public int Weight { get; set; }8 9             public string Description { get; set; }10 11             public int CompareTo(Edge other)12             {13                 return this.Weight.CompareTo(other.Weight);14             }15         }16 17         private class Path : IComparable<Path>18         {19             public Path()20             {21                 this.Edges = new List<Edge>();22             }23 24             public int StartVertexIndex { get; set; }25 26             public int EndVertexIndex { get; set; }27 28             public List<Edge> Edges { get; private set; }29 30             public int Weight { get; private set; }31 32             public void AddEdges(IEnumerable<Edge> edges)33             {34                 foreach (var edge in edges)35                 {36                     this.AddEdge(edge);37                 }38             }39 40             public void AddEdge(Edge edge)41             {42                 this.Edges.Add(edge);43                 this.Weight += edge.Weight;44             }45 46             public int CompareTo(Path other)47             {48                 return this.Weight.CompareTo(other.Weight);49             }50         }51 52         class Vertex<T>53         {54             public T Value { get; set; }55         }56 57         class Graph<T>58         {59             #region 私有字段60 61             private int _maxSize;62             private Vertex<T>[] _vertexs;63             private Edge[][] _edges;64             private int _vertexCount = 0;65 66             #endregion67 68             #region 构造方法69 70             public Graph(int maxSize)71             {72                 _maxSize = maxSize;73                 _vertexs = new Vertex<T>[_maxSize];74                 _edges = new Edge[_maxSize][];75                 for (var i = 0; i < _maxSize; i++)76                 {77                     _edges[i] = new Edge[_maxSize];78                 }79             }80 81             #endregion82 83             #region 添加顶点84 85             public Graph<T> AddVertex(T value)86             {87                 _vertexs[_vertexCount++] = new Vertex<T> { Value = value };88 89                 return this;90             }91 92             #endregion93 94             #region 添加边95 96             public Graph<T> AddUnDirectedEdge(T startItem, T endItem, int weight)97             {98                 var startIndex = this.GetVertexIndex(startItem);99                 var endIndex = this.GetVertexIndex(endItem);
100
101                 _edges[startIndex][endIndex] = new Edge { StartIndex = startIndex, EndIndex = endIndex, Weight = weight, Description = String.Format("{0}->{1}", startItem, endItem) };
102                 _edges[endIndex][startIndex] = new Edge { StartIndex = endIndex, EndIndex = startIndex, Weight = weight, Description = String.Format("{0}->{1}", endItem, startItem) };
103
104                 return this;
105             }
106
107             public Graph<T> AddDirectedEdge(T startItem, T endItem, int weight)
108             {
109                 var startIndex = this.GetVertexIndex(startItem);
110                 var endIndex = this.GetVertexIndex(endItem);
111
112                 _edges[startIndex][endIndex] = new Edge { StartIndex = startIndex, EndIndex = endIndex, Weight = weight, Description = String.Format("{0}->{1}", startItem, endItem) };
113
114                 return this;
115             }
116
117             #endregion
118
119             #region 最小生成树
120
121             public IEnumerable<Edge> GetMinimumSpanningTree()
122             {
123                 var minimumSpanningTrees = new List<Edge>();
124                 Dictionary<int, bool> vertexInTreesTracker = new Dictionary<int, bool>();
125                 var queue = new PriorityQueue<Edge>(_maxSize);
126
127                 var currentVertexIndex = 0;
128                 while (minimumSpanningTrees.Count < _vertexCount - 1)
129                 {
130                     vertexInTreesTracker[currentVertexIndex] = true;
131
132                     foreach (var item in _edges[currentVertexIndex])
133                     {
134                         if (item == null)
135                         {
136                             continue;
137                         }
138                         if (vertexInTreesTracker.ContainsKey(item.EndIndex))
139                         {
140                             continue;
141                         }
142
143                         queue.EnQueue(item);
144                     }
145
146                     var smallEdge = queue.DeQueue();
147                     while (vertexInTreesTracker.ContainsKey(smallEdge.EndIndex))
148                     {
149                         smallEdge = queue.DeQueue();
150                     }
151                     minimumSpanningTrees.Add(smallEdge);
152                     currentVertexIndex = smallEdge.EndIndex;
153                 }
154
155                 return minimumSpanningTrees;
156             }
157
158             #endregion
159
160             #region 最短路径
161
162             public IEnumerable<Edge> GetShortestPath(T startItem, T endItem)
163             {
164                 var startIndex = this.GetVertexIndex(startItem);
165                 var endIndex = this.GetVertexIndex(endItem);
166
167                 var shortestPaths = new Dictionary<int, Path>();
168                 var queue = new PriorityQueue<Path>(_maxSize);
169
170                 var currentVertexIndex = startIndex;
171                 var currentPath = new Path
172                 {
173                     StartVertexIndex = startIndex,
174                     EndVertexIndex = endIndex
175                 };
176
177                 while (!shortestPaths.ContainsKey(endIndex))
178                 {
179                     foreach (var item in _edges[currentVertexIndex])
180                     {
181                         if (item == null)
182                         {
183                             continue;
184                         }
185                         if (shortestPaths.ContainsKey(item.EndIndex))
186                         {
187                             continue;
188                         }
189
190                         var path = new Path
191                         {
192                             StartVertexIndex = startIndex,
193                             EndVertexIndex = item.EndIndex
194                         };
195                         path.AddEdges(currentPath.Edges);
196                         path.AddEdge(item);
197                         queue.EnQueue(path);
198                     }
199
200                     var smallPath = queue.DeQueue();
201                     while (shortestPaths.ContainsKey(smallPath.EndVertexIndex))
202                     {
203                         smallPath = queue.DeQueue();
204                     }
205                     shortestPaths[smallPath.EndVertexIndex] = smallPath;
206                     currentVertexIndex = smallPath.EndVertexIndex;
207                     currentPath = smallPath;
208                 }
209
210                 return shortestPaths[endIndex].Edges;
211             }
212
213             #endregion
214
215             #region 帮助方法
216
217             private int GetVertexIndex(T item)
218             {
219                 for (var i = 0; i < _vertexCount; i++)
220                 {
221                     if (_vertexs[i].Value.Equals(item))
222                     {
223                         return i;
224                     }
225                 }
226                 return -1;
227             }
228
229             #endregion
230         }

备注

最短路径的算法和最小生成树的算法非常相似,都是利用了:优先级队列。

转载于:https://www.cnblogs.com/happyframework/p/3497306.html

算法:权重图的最最小生成树算法相关推荐

  1. python棋盘最短路径_Python数据结构与算法之图的最短路径(Dijkstra算法)完整实例...

    本文实例讲述了Python数据结构与算法之图的最短路径(Dijkstra算法).分享给大家供大家参考,具体如下: # coding:utf-8 # Dijkstra算法--通过边实现松弛 # 指定一个 ...

  2. matlab求kcf算法响应图_matlab求kcf算法响应图_剖析KCF

    来源自我的博客 前言 核相关滤波算法是单目标跟踪领域一个举足轻重的算法,而kernelized correlation filters(KCF)是其原始形态,下面我以一个小白的角度慢慢揭开其神秘面纱. ...

  3. 算法导论-上课笔记10:最小生成树

    文章目录 0 前言 1 最小生成树 2 Kruskal算法 3 Prim算法 0 前言 在电路设计中,常常需要将多个组件的针脚连接在一起.要连接n个针脚,可以使用n-1根连线,每根连线连接两个针脚,则 ...

  4. 多机器人路径规划的代码_知荐 | 地平线机器人算法工程师总结六大路径规划算法...

    来源 | 知乎 知圈 | 进"高精度地图社群",请加微信15221054164,备注地图 目录 1 自主机器人近距离操作运动规划体系········1.1 单个自主机器人的规划体系 ...

  5. 算法:图(Graph)的遍历、最小生成树和拓扑排序

    背景 不同的数据结构有不同的用途,像:数组.链表.队列.栈多数是用来做为基本的工具使用,二叉树多用来作为已排序元素列表的存储,B 树用在存储中,本文介绍的 Graph 多数是为了解决现实问题(说到底, ...

  6. 证明kruskal算法求解图的最小生成树具有贪心选择性质_将并查集应用在图论中的最小生成树算法——Kruskal...

    点击上方蓝字,和我一起学技术. 今天是算法和数据结构专题的第19篇文章,我们一起来看看最小生成树. 我们先不讲算法的原理,也不讲一些七七八八的概念,因为对于初学者来说,看到这些术语和概念往往会很头疼. ...

  7. 算法:通过克鲁斯卡尔(Kruskal)算法,求出图的最小生成树

    之前我给大家分享过用普利姆(Prim)算法来求出图的最小生成树(点我去看看),今天我再给大家分享一个也是求图的最小生成树的克鲁斯卡尔(Kruskal)算法 克鲁斯卡尔(Kruskal)算法,就相当于先 ...

  8. 数据结构与算法——31. 图的应用:拓扑排序、强连通分支、最短路径问题、最小生成树

    文章目录 一.拓扑排序(Topological Sort) 实现思路 二.强连通分支 1. 转置的概念 2. 强连通分支算法:Kosaraju算法思路 三.最短路径问题 1. 最短路径问题:Dijks ...

  9. 图的最小生成树算法实现(Prim + Kruskal)

    1.采用书上第 161 页定义的图的邻接矩阵存储表示,编程实现构造最小生成树的 Prim 算法. 2.采用书上第 161 页定义的图的邻接矩阵存储表示,编程实现构造最小生成树的 Kruskal 算法. ...

最新文章

  1. python定义一个汽车类_汽车类Python程序
  2. 用Python解锁“吃鸡”正确姿势
  3. !!导致大智慧公式总是死循环的编码风格
  4. 测试C语言malloc申请内存不释放结果
  5. win8 linux分区工具,Ubuntu下挂载Win8磁盘分区
  6. Golang——包引入和闭包
  7. conda deactivate python3_conda进行python环境隔离
  8. 计算机视觉新范式: Transformer
  9. Python求数独的补充
  10. (day05)剑指 Offer 11. 旋转数组的最小数字-(二分法)
  11. bootstrap 模态框modal
  12. 【预测模型】基于matlab BP神经网络预测【含Matlab源码 221期】
  13. (超详细)算法学习:STL和基本数据结构
  14. c语言素数环实验报告,c语言素数环问题实例讲解
  15. jQuery 仿抖音时钟罗盘转动效果
  16. 数据库实验八--OpenGauss(数据库的备份与恢复)
  17. Windows + Linux 双系统 卸载 Liunx
  18. Unknown label type: ‘continuous
  19. HTML/CSS class6 table布局
  20. 场景调研 persona

热门文章

  1. 老男孩python爬虫视频教程_python爬虫入门
  2. C语言程序care用法,词汇精选:care的用法和辨析
  3. 如何明智的使用计算机,幼儿园如何正确使用计算机
  4. (12)Verilog HDL可综合与不可综合区别(第3天)
  5. (6)FPGA面试技能提升篇(OpenCV)
  6. bind mysql django_Django+bind dlz DNS管理平台
  7. java中类定义修饰符_Java 中类和方法修饰符
  8. STM32F103:三.(3)MPU6050
  9. 3.FreeRTOS学习笔记-任务
  10. boost::asio