最小生成树,最短路径

最小生成树与最短路径 图的最小生成树及最短路径算法详解 阅读详情

prim最小生成树算法

 

1.任意选取一个起始顶点,并将它添加到最小生成树中。

2.将所有含起始顶点的边按照权重次序添加到minheap(最小堆)中。

3.从最小堆中取出最小边,并将这条边和那个新顶点添加到最小生成树中。

4.我们往minheap中添加所有含新顶点且另一顶点不在最小生成树中的边。

5.重复这一过程直到最小生成树含有原始图中的所有顶点时结束。

 

 

 

public Network mstNetwork()

   {

      int x, y;

      int index;

      double weight;

      int[] edge = new int[2];

      Heap<Double> minHeap = new Heap<Double>();

      Network<T> resultGraph = new Network<T>();

 

      if (isEmpty() || !isConnected())

         return resultGraph;

 

      resultGraph.adjMatrix = new double[numVertices][numVertices];

      for (int i = 0; i < numVertices; i++)

         for (int j = 0; j < numVertices; j++)

            resultGraph.adjMatrix[i][j] = Double.POSITIVE_INFINITY;

      resultGraph.vertices = (T[])(new Object[numVertices]);     

      

      boolean[] visited = new boolean[numVertices];

      for (int i = 0; i < numVertices; i++)

         visited[i] = false;

     

      edge[0] = 0;

      resultGraph.vertices[0] = this.vertices[0];

      resultGraph.numVertices++;

      visited[0] = true;

 

      /** Add all edges, which are adjacent to the starting vertex,

          to the heap */

      for (int i = 0; i < numVertices; i++)

            minHeap.addElement(new Double(adjMatrix[0][i]));

 

      while ((resultGraph.size() < this.size()) && !minHeap.isEmpty())

      {

         /** Get the edge with the smallest weight that has exactly

             one vertex already in the resultGraph */

         do

         {

            weight = (minHeap.removeMin()).doubleValue();

            edge = getEdgeWithWeightOf(weight, visited);

         } while (!indexIsValid(edge[0]) || !indexIsValid(edge[1]));

 

         x = edge[0];

         y = edge[1];

         if (!visited[x])

            index = x;

         else

            index = y;

 

         /** Add the new edge and vertex to the resultGraph */

         resultGraph.vertices[index] = this.vertices[index];

         visited[index] = true;

         resultGraph.numVertices++;

 

         resultGraph.adjMatrix[x][y] = this.adjMatrix[x][y];

         resultGraph.adjMatrix[y][x] = this.adjMatrix[y][x];

 

         /** Add all edges, that are adjacent to the newly added vertex,

             to the heap */

         for (int i = 0; i < numVertices; i++)

         {

            if (!visited[i] && (this.adjMatrix[i][index] <

                                Double.POSITIVE_INFINITY))

            {

               edge[0] = index;

               edge[1] = i;

               minHeap.addElement(new Double(adjMatrix[index][i]));

            }

         }

      }

      return resultGraph;

   }

 

最短路径:

 

A:两个顶点之间的最小边数

 

 

将广度优先遍历算法转变成寻找最短路径的算法

在遍历期间为每个顶点多存储两个信息

1.  从起始点到本顶点的路径长度,以及本顶点的前驱顶点

2.  起始顶点到本顶点的长度。

 

接着修改循环,使得当抵达目标顶点时循环终止,最短路径数就是从起始顶点到目标顶点前驱的路径长度再加1;如果要输出最短路径上的顶点,只需沿着前驱链回溯即可。

protected Iterator<Integer> iteratorShortestPathIndices

                              (int startIndex, int targetIndex)

   {

      int index = startIndex;

      int[] pathLength = new int[numVertices];

      int[] predecessor = new int[numVertices];

      LinkedQueue<Integer> traversalQueue = new LinkedQueue<Integer>();

      ArrayUnorderedList<Integer> resultList =

                                  new ArrayUnorderedList<Integer>();

 

      if (!indexIsValid(startIndex) || !indexIsValid(targetIndex) ||

                                       (startIndex == targetIndex))

         return resultList.iterator();

 

      boolean[] visited = new boolean[numVertices];

      for (int i = 0; i < numVertices; i++)

         visited[i] = false;

     

      traversalQueue.enqueue(new Integer(startIndex));

      visited[startIndex] = true;

      pathLength[startIndex] = 0;

      predecessor[startIndex] = -1;

 

      while (!traversalQueue.isEmpty() && (index != targetIndex))

      {

         index = (traversalQueue.dequeue()).intValue();

 

         /** Update the pathLength for each unvisited vertex adjacent

             to the vertex at the current index. */

         for (int i = 0; i < numVertices; i++)

         {

            if (adjMatrix[index][i] && !visited[i])

            {

               pathLength[i] = pathLength[index] + 1;

               predecessor[i] = index;

               traversalQueue.enqueue(new Integer(i));

               visited[i] = true;

            }

         }

      }

      if (index != targetIndex)  // no path must have been found

         return resultList.iterator();

 

      LinkedStack<Integer> stack = new LinkedStack<Integer>();

      index = targetIndex;

      stack.push(new Integer(index));

      do

      {

         index = predecessor[index];

         stack.push(new Integer(index));

      } while (index != startIndex);

     

      while (!stack.isEmpty())

         resultList.addToRear(((Integer)stack.pop()));

 

      return resultList.iterator();

   }

 

B:加权图的最小路径

使用一个minheap或优先队列来存储顶点,基于总权重(从起始顶点到本顶点的权重和)来衡量顶点对。这样我们总是能优先沿着最便宜的路径来游历图。

对每个顶点,都必须存储该顶点的标签,从起始顶点到本顶点的最便宜的路径的权重,路径上本顶点的前驱。在minheap中将存储顶点,对每条已经遇到但尚未游历的候选路径来权衡顶点对。从minheap取出顶点的时候,会权衡取自minheap的顶点对;如果遇到一个顶点的权重小于目前顶点中已存储的权重,则更新路径的代价。

 

protected Iterator<Integer> iteratorShortestPathIndices

                              (int startIndex, int targetIndex)

   {

      int index;

      double weight;

      int[] predecessor = new int[numVertices];

      Heap<Double> traversalMinHeap = new Heap<Double>();

      ArrayUnorderedList<Integer> resultList =

                                  new ArrayUnorderedList<Integer>();

      LinkedStack<Integer> stack = new LinkedStack<Integer>();

 

      int[] pathIndex = new int[numVertices];

      double[] pathWeight = new double[numVertices];

      for (int i = 0; i < numVertices; i++)

         pathWeight[i] = Double.POSITIVE_INFINITY;

 

      boolean[] visited = new boolean[numVertices];

      for (int i = 0; i < numVertices; i++)

         visited[i] = false;

 

      if (!indexIsValid(startIndex) || !indexIsValid(targetIndex) ||

                       (startIndex == targetIndex) || isEmpty())

         return resultList.iterator();

 

      pathWeight[startIndex] = 0;

      predecessor[startIndex] = -1;     

      visited[startIndex] = true;

      weight = 0;

 

      /** Update the pathWeight for each vertex except the

          startVertex. Notice that all vertices not adjacent

          to the startVertex  will have a pathWeight of

          infinity for now. */

      for (int i = 0; i < numVertices; i++)

      {

         if (!visited[i])

         {

            pathWeight[i] = pathWeight[startIndex] +

                            adjMatrix[startIndex][i];

            predecessor[i] = startIndex;

            traversalMinHeap.addElement(new Double(pathWeight[i]));

         }

      }

 

      do

      {

         weight = (traversalMinHeap.removeMin()).doubleValue();

         traversalMinHeap = new Heap<Double>();

         if (weight == Double.POSITIVE_INFINITY)  // no possible path

            return resultList.iterator();

         else

         {

            index = getIndexOfAdjVertexWithWeightOf(visited, pathWeight,

                                                    weight);

            visited[index] = true;

         }

 

         /** Update the pathWeight for each vertex that has has not been

             visited and is adjacent to the last vertex that was visited.

             Also, add each unvisited vertex to the heap. */

         for (int i = 0; i < numVertices; i++)

         {

            if (!visited[i])

            {

               if((adjMatrix[index][i] < Double.POSITIVE_INFINITY) &&

                  (pathWeight[index] + adjMatrix[index][i]) < pathWeight[i])

               {

                  pathWeight[i] = pathWeight[index] + adjMatrix[index][i];

                  predecessor[i] = index;

               }       

               traversalMinHeap.addElement(new Double(pathWeight[i]));

            }

         }

      } while (!traversalMinHeap.isEmpty() && !visited[targetIndex]);

 

      index = targetIndex;

      stack.push(new Integer(index));

      do

      {

         index = predecessor[index];

         stack.push(new Integer(index));

      } while (index != startIndex);

     

      while (!stack.isEmpty())

         resultList.addToRear((stack.pop()));

 

      return resultList.iterator();

   }

数据结构第六章(四)-最小生成树、最短路径 讲了求最小生成树的Prim算法、Kruskal算法和求最短路径的BFS算法、Dijkstra算法与Floyd算法,主要还是得知道过程。BFS求无权图,Dijkstra是单源带权图,Floyd是多源带权图,这些过程还是有点麻烦的,别搞错就行了。 阅读详情

相关推荐

Surface Go 2 变身 Linux 开发本:保姆级 Ubuntu 20.04 双系统安装与驱动配置全攻略

本文详细介绍了如何将 Surface Go 2 变身为高效的 Linux 开发本,涵盖 Ubuntu 20.04 双系统安装、专用内核配置、驱动优化等全流程。通过 linux-surface 内核安装和硬件驱动优化,确保 Surface Go 2 的触控、笔输入、摄像头等功能完美运行,适合开发者打造便携生产力工具。

weixin_30596165的博客 616

最小生成树和最短路径

最小生成树和最短路径最小生成树普里姆(Pim)算法克鲁斯卡尔(Kruskal)算法最短路径狄克斯特拉(Dijkstra)算法Floyd算法 最小生成树 生成树概念: 一个连通图的生成树是一个极小连通子图,它含有图中全部n个顶点和构成一棵树的(n-1)条边。 可以通过遍历方法产生生成树: 由深度优先遍历得到的生成树称为深度优先生成树。 由广度优先遍历得到的生成树称为广度优先生成树。 最小生成树概念: 对于带权连通图G (每 条边上的权均为大于零的实数),可能有多棵不同生成树。 每棵生 成树的所

qq_45454698的博客 4848

IAR调试CC1310的错误:Fatal error:Failed to connect to the XDS emlulator (Error -241 @ 0x0:)

从simplelink_cc13x0_sdk_2_10_00_36导入collector工程后,rebuild后进行debug,出现了如图错误:Fatal error:Failed to connect to the XDS emlulator (connect ICEPick)...(Error -241 @ 0x0)A router subpath could not be accessed....

qq_40417648的博客 6228

最小生成树,最短路径算法

经典的贪心策略 Prim算法,Kruskal算法求最小

xiuweikang的专栏 1528

【RTOS】 Vxworks 653 第一章 —— 初识 vx653 3.x

。。不是很重要,自己搜吧鲁棒分区是一种确保共享计算资源中独立运行功能实现​​时空隔离​​的机制,其目标是为集成模块中的混合临界性应用提供与联邦式部署(federated implementation)同等级别的功能隔离保障。具体表现为:​​多关键性共存​​:支持不同安全等级应用(如飞控系统A级与娱乐系统D级)在同一模块中协同运行。​​抗干扰能力​​:防止未授权或意外的时空干扰(如内存越界、时间窗口冲突),确保应用间互不影响。​​。

qq_38183694的博客 1280

C++软件异常分析概述

本文将详细讲述Windows系统中软件异常的分类以及常用的排查方法,给大家提供一个借鉴与参考。

dvlinker的技术专栏 4万+

数据结构和算法三-栈的简单实现

1 栈的简单介绍 栈是一种先进后出的数据结构,主要的api如下 pop:弹栈,返回并弹出栈顶元素 push:压栈,往栈里添加元素 peek:返回栈顶元素 2 通过链表实现栈 public class LinkedStack<T> implements Iterable<T>, Stack<T> { /** * 定义一个指向栈顶的引用 */ private Node<T> top; private Inte...

qq_35930102的博客 205

常用元器件使用方法13:物理层接口芯片DP83848的使用方法

介绍: DP83848是以太网物理层接口芯片,具有多种型号,从便于焊接角度考虑LQFP-48封装较为合适,采用LQFP-48封装的芯片,有2种型号,分别为DP83848I和DP83848C,如下图所示。 其主要区别是使用温度不同,如下图所示。 这2种芯片芯片网上均有销售,按理说DP83848C价格应该更加便宜,实际不然,DP83848I的价格低于DP83848C,考虑或与芯片的出货量...

snmplink的博客 1万+

51nod3220 最短路径 easy ver.

3220 最短路径 easy ver. 题目详情见51nod2673 最短路径 这里就不放代码与解析

ZCH1901的博客 320

LeRobot 宇树人形机器人 G1 部署 GR00T 运动策略

本文详细介绍了Unitree G1人形机器人的完整设置流程。首先通过以太网连接机器人并进行SSH访问,然后配置WiFi网络实现无线连接。在机器人端安装LeRobot软件并运行服务器程序,最后在控制端配置IP地址并运行GR00T移动控制系统。指南涵盖了29自由度和23自由度版本G1机器人的配置方法,支持通过WiFi进行远程策略部署,提供双足行走与平衡控制功能,并详细说明了遥控器操作方式。

2506_90492529的博客 2171

Python在Genesis2000 CAM软件中的编程应用

Genesis2000是一款功能强大的计算机辅助制造(CAM)软件,它提供了广泛的功能和工具,用于帮助制造商进行CAD(计算机辅助设计)到CAM的转换。在Genesis2000中,我们可以利用Python的灵活性和功能来扩展软件的自定义能力,并通过编写脚本来自动化各种制造任务。例如,假设我们需要在Genesis2000中添加一个新的操作,用于自动计算零部件的重量。我们可以编写一个Python脚本,通过遍历模型的几何数据并应用相关的计算公式,来实现这个功能。

PixelEnigma的博客 2423

我用Java学数据结构之栈底层实现

栈和队列在很多地方都有应用,比如非递归前序遍历二叉树,还有做题的时候会经常用到 首先定义栈的接口,与java内置的栈接口相同,依然使用泛型实现 public interface Stack<E> { int getSize(); boolean isEmpty(); void push(E e); E pop(); E p...

路途遥远’s blog 695

第21章—技术管理篇(上):身为技术人该怎样带好团队并做好管理者

上节讲了职业规划和学习提升这两个话题,随着职业规划的不断落地,或者自己能力的不断提升,大家也会逐渐被提拔成“职级更高”的人。企业规模扩张时,员工数量也会变多,意味着Boss需要更多的人来辅助管理,而管理者会从外部招聘吗?也许会,但大多企业更喜欢从内部选拔,毕竟人的天性更希望找的人值得信赖。此时,一些能力不错、做事靠谱的老员工,就会被“赶上”管理者的位子。作管理不难,但想要“”就需要一定情商。

运维老生常谈 1364

最短路径、最短路径树和最小生成树

首先介绍这三个概念,很多人都听过最短路径了,但是最短路径树却很少听过,关于最短路径树的介绍也不太多。而最短路径树和最小生成树更是完全不同的两个概念。 最短路径就是从一个指定的顶点出发,计算从该顶点出发到其他所有顶点的最短路径。通常用Dijkstra算法,Floyd算法求解。 最短路径树SPT(Short Path Tree)是网络的源点到所有结点的最短路径构成的树。...

jinking01的专栏 1万+

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

最小生成树、最短路径树

最小生成树 在图论中,无向图 G 的生成树(英语:Spanning Tree)是具有 G 的全部顶点,但边数最少的连通子图。[1] 一个图的生成树可能有多个。 带权图的生成树中,总权重最小的称为最小生成树。 它在实际中有什么应用呢?比如说有N个城市需要建立互联的通信网路,如何使得需要铺设的通信电缆的总长度最小呢?这就需要用到最小生成树的思想了。 求取最小生成树的算法: Prim算法原理: 1)以某一个点开始,寻找当前该点可以访问的所有的边; 2)在已经寻找的边中发现最小边,这个边必须有一个点还没有访问过,

Anne033的博客 9306

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

最小生成树与最短路径的区别以及实现方法

一 区别 最小生成树能够保证整个拓扑图的所有路径之和最小,但不能保证任意两点之间是最短路径。 最短路径是从一点出发,到达目的地的路径最小。 二 实现方法 1. 最小生成树 最小生成树有两种算法来得到:Prims算法和Kruskal算法。 Kruskal算法:根据边的加权值以递增的方式,一次找出加权值最低的边来构建最小生成树,而且规定:每次添加的边不能造成生成树有回路,知道找到N-1个边

WangIcter的专栏 2万+

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

最短路径、最小生成树

概念:对于一个带权连通无向图G=(.E),生成树不同,每棵树的权(即树中所有边上的权值之和)也可能不同。设R为G的所有生成树的集合,若7为R中边的权值之和最小的生成树,则7称为G的最小生成树(Minimum-Spanning-Tree, MST)。对于有的边是相同的权,最小生成树可能有多个。如果一个连通图本身就是一棵树,则其最小生成树就是它本身。只有连通图才有生成树,非连通图只有生成森林。

2401_88817961的博客 717

最小生成树和最短路径问题的总结

最小生成树问题是指给定一个图,在图中选择n-1条边使n个点之间相互连通且边长和最小,例题如下。(注意以下两种算法只能应用于无向图中)。

qq_63870615的博客 1754

最短路径,最短路径树和最小生成树

       首先介绍这三个概念,很多人都听过最短路径了,但是最短路径树却很少听过,关于最短路径树的介绍也不太多。而最短路径树和最小生成树更是完全不同的两个概念。       最短路径就是从一个指定的顶点出发,计算从该顶点出发到其他所有顶点的最短路径。通常用Dijkstra算法,Floyd算法求解。      最短路径树SPT(Short Path Tree)是网络的源点到所有结点的最短路径构成的...

annie_ooo的博客 1万+

最小生成树 && 最短路径

连通图生成树,非连通图生成森林生成树是包含图中全部顶点的一个极小连通子图特性:图中有n个顶点,则它的生成树含有n-1条边。去除一条边会变成非连通图;加上一条边会变成一个回路之前学过广度优先生成树和深度优先生成树。最小生成树,也叫最小代价树。在带权连通无向图的所有生成树中,所有边的代价和最小。最小生成树可能很多,但边的权值之和总是唯一且最小的。最小生成树的边树=顶点数-1。

一只小水豚 1105

最短路径VS最小生成树

最小生成树VS最短路径算法大集合

爱敲代码的小赤佬 715

图的最小生成树与最短路径

一个连通图的生成树是一个极小的连通子图,它含有图中全部顶点,但只有足以构成一棵树的n-1条边。那么我们把构造连通网的最小代价生成树称为最小生成树。 找连通网的最小生成树,经典的有两种算法,普里姆算法和克鲁斯卡尔算法。下面分别介绍两种算法。

飞扬的青春的专栏 2万+

最小生成树和单源最短路径

最小生成树和单源最短路径 文章目录最小生成树和单源最短路径1 最小生成树1.1 书本代码:1.2 精简代码1.3 优化代码2 单源最短路径2.1 书本代码2.2 精简代码2.3 优化代码3 总结 n个顶点的最小生成树只有n-1条边。 最小生成树能够保证整个拓扑图的所有路径之和最小,但不能保证任意两点之间是最短路径。 最短路径是从一点出发,到达目的地的路径最小。 最小生成树构成后所有的点都被连通,而最短路只要到达目的地走的是最短的路径即可,与所有的点连不连通没有关系。 1 最小生成树 最小生成树:构造连通网的

Teemos的博客 1371

最小生成树和最短路径的区别

最小生成树能够保证整个拓扑图的所有路径之和最小,但不能保证任意两点之间是最短路径。 最短路径是从一点出发,到达目的地的路径最小。 最小生成树所有点被连通 。把连通的图的所有顶点连起来路径之和最小的问题,即生成树总权值之和最小。整体来分析。 最短路径不一定所有点。只着眼于点与点之间的路径问题,并不关注整个图,也就意味着对一个节点运行算法的结果与另一个节点的结果之间没有多少关系。单条路径来分析。 Prims算法代码 while(alreadyVisited.size() != Switches.s.

qq_42824207的博客 2218
上一篇: Reform(改革) must be incremental
下一篇: 国家重点软件企业
easyjsf
博客等级 码龄17年 19粉丝 82原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值