最小路径算法(Dijkstra算法和Floyd算法)

1.单源点的最短路径问题:给定带权有向图G和源点v,求从v到G中其余各顶点的最短路径。

我们用一个例子来具体说明迪杰斯特拉算法的流程。

定义源点为 0,dist[i]为源点 0 到顶点 i 的最短路径。其过程描述如下:

步骤dist[1]dist[2]dist[3]dist[4]已找到的集合
第 1 步812+∞{2}
第 2 步8×24{2, 3}
第 3 步5××4{2, 3, 4}
第 4 步5×××{2, 3, 4, 1}
第 5 步××××{2, 3, 4, 1}

第 1 步:从源点 0 开始,找到与其邻接的点:1,2,3,更新dist[]数组,因 0 不与 4 邻接,故dist[4]为正无穷。在dist[]中找到最小值,其顶点为 2,即此时已找到 0 到 2 的最短路。

第 2 步:从 2 开始,继续更新dist[]数组:2 与 1 不邻接,不更新;2 与 3 邻接,因0→2→3dist[3]大,故不更新dist[3] ;2 与 4 邻接,因0→2→4dist[4]小,故更新dist[4]为 4。在dist[]中找到最小值,其顶点为 3,即此时又找到 0 到 3 的最短路。

第 3 步:从 3 开始,继续更新dist[]数组:3 与 1 邻接,因0→3→1dist[1]小,更新dist[1]为 5;3 与 4 邻接,因0→3→4dist[4]大,故不更新。在dist[]中找到最小值,其顶点为 4,即此时又找到 0 到 4 的最短路。

第 4 步:从 4 开始,继续更新dist[]数组:4 与 1 不邻接,不更新。在dist[]中找到最小值,其顶点为 1,即此时又找到 0 到 1 的最短路。

第 5 步:所有点都已找到,停止。

对于上述步骤,你可能存在以下的疑问:

若 A 作为源点,与其邻接的只有 B,C,D 三点,其dist[]最小时顶点为 C,即就可以确定A→C为 A 到 C 的最短路。但是我们存在疑问的是:是否还存在另一条路径使 A 到 C 的距离更小? 用反证法证明。

假设存在如上图的红色虚线路径,使A→D→C的距离更小,那么A→D作为A→D→C的子路径,其距离也比A→C小,这与前面所述 “dist[]最小时顶点为 C” 矛盾,故假设不成立。因此这个疑问不存在。

根据上面的证明,我们可以推断出,Dijkstra 每次循环都可以确定一个顶点的最短路径,故程序需要循环 n-1 次。

/*
迪杰斯特拉求单节点到其余各节点的最短路径。
visited数组用于保存顶点是否已经求过最短路径,pre数组用于保存最短路径的下标
dist数组用于保存初始节点到其余节点的最短路径长度。
该算法求有向图G的某顶点到其余节点的最短路径pre以及长度dist
pre[v]的值是v0-->...->v的路径中的前驱节点。D[v]表示v0-->...-->v的最短路径长度和。可以证明迪杰斯特拉算法每次循环可以确定一个顶点的最短路径,所以主程序循环n-1次。
主程序循环主要做两件事:首先找出dist数组中的最小值,并记录下标,说明找到初始点到该下标的最短路径。
然后要比价初始点到该点的最短路径加上这点到其他初始点需要到的点的距离是否比初始点直接到这些点的距离短
如果要短,那么就更新dist数组,并且这些点的前驱节点就会变为v而不是开始的v0点。下一次主循环再去从dist中找
最小的值并且未求过的点,就是该点的最短路径。
*/
#include<iostream>
using namespace std;
int matrix[100][100];//邻接矩阵
bool visited[100];//标记数组
int dist[100];//原点到i顶点的最短距离
int pre[100];//记录最短路径。pre[i]放的是i的前驱节点
int source;//源节点
int vertex_num;//顶点数
int edge_num;//边数void Dijkstra(int source)
{//首先初始化memset(visited,0,sizeof(visited));visited[source] = true;for (int i = 0; i < vertex_num; i++){dist[i] = matrix[source][i];pre[i] = source;}int min_cost;//最短距离int min_cost_index;//权值最小的那个顶点的下标。(求好了)//主循环for (int i = 1; i < vertex_num; i++){min_cost = INT_MAX;for (int j = 0; j < vertex_num; j++){//注意要确保这个点没有找过。if (visited[j]==false&&dist[j] < min_cost){min_cost_index = j;min_cost = dist[j];}}visited[min_cost_index] = true;//找到某一个点的最短距离//利用该点进行dist的更新,并且调整前驱。for (int j = 0; j < vertex_num; j++){//确保有连接if (visited[j] == false && matrix[min_cost_index][j] != INT_MAX&&min_cost+ matrix[min_cost_index][j] < dist[j]){dist[j] = min_cost + matrix[min_cost_index][j];pre[j] = min_cost_index;}}}
}int main()
{cout << "请输入图的顶点数(<100):";cin >> vertex_num;cout << "请输出图的边数: ";cin >> edge_num;for (int i = 0; i < vertex_num; i++){for (int j = 0; j < vertex_num; j++){matrix[i][j] = (i != j) ? INT_MAX : 0;}}cout << "请输入边的信息:\n";int u, v, w;for (int i = 0; i < edge_num; i++){cin >> u >> v >> w;matrix[u][v] = matrix[v][u] = w;}cout << "请输入源点(<" << vertex_num << "): ";cin >> source;Dijkstra(source);for (int i = 0; i < vertex_num; i++){if (i != source){//路径是反的,从目标点向前不断找前驱的过程。cout << source << "" << i << "最短距离: " << dist[i] << ",路径是:" << i;int t = pre[i];while (t != source){cout << "--" << t;t = pre[t];}cout << "--" << source << endl;}}return 0;
}

2、弗洛伊德算法:

1)算法思想原理:

     Floyd算法是一个经典的动态规划算法。用通俗的语言来描述的话,首先我们的目标是寻找从点i到点j的最短路径。从动态规划的角度看问题,我们需要为这个目标重新做一个诠释(这个诠释正是动态规划最富创造力的精华所在)

      从任意节点i到任意节点j的最短路径不外乎2种可能,1是直接从i到j,2是从i经过若干个节点k到j。所以,我们假设Dis(i,j)为节点u到节点v的最短路径的距离,对于每一个节点k,我们检查Dis(i,k) + Dis(k,j) < Dis(i,j)是否成立,如果成立,证明从i到k再到j的路径比i直接到j的路径短,我们便设置Dis(i,j) = Dis(i,k) + Dis(k,j),这样一来,当我们遍历完所有节点k,Dis(i,j)中记录的便是i到j的最短路径的距离。

2).算法描述:

a.从任意一条单边路径开始。所有两点之间的距离是边的权,如果两点之间没有边相连,则权为无穷大。   

b.对于每一对顶点 u 和 v,看看是否存在一个顶点 w 使得从 u 到 w 再到 v 比己知的路径更短。如果是更新它。

3).Floyd算法过程矩阵的计算----十字交叉法

方法:两条线,从左上角开始计算一直到右下角 如下所示

给出矩阵,其中矩阵A是邻接矩阵,而矩阵Path记录u,v两点之间最短路径所必须经过的点

相应计算方法如下:

最后A3即为所求结果

typedef struct          
{        char vertex[VertexNum];                                //顶点表         int edges[VertexNum][VertexNum];                       //邻接矩阵,可看做边表         int n,e;                                               //图中当前的顶点数和边数         
}MGraph; void Floyd(MGraph g)
{int A[MAXV][MAXV];int path[MAXV][MAXV];int i,j,k,n=g.n;for(i=0;i<n;i++)for(j=0;j<n;j++){   A[i][j]=g.edges[i][j];path[i][j]=-1;}for(k=0;k<n;k++){ for(i=0;i<n;i++)for(j=0;j<n;j++)if(A[i][j]>(A[i][k]+A[k][j])){A[i][j]=A[i][k]+A[k][j];path[i][j]=k;} } 
}

//代码来自于wsw_seu大佬

//仅仅是作为笔记,谢谢

转载于:https://www.cnblogs.com/crazily/p/9608448.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/365846.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

matlab tsai手眼标定程序代码_标定系列一 | 机器人手眼标定的基础理论分析

旷视MegMaster机器人系列是旷视自主研发的一系列AI智能机器人硬件设备&#xff0c;基于旷视全球领先的人工智能算法及机器人技术&#xff0c;可实现搬运、分拣、托举、存储等功能&#xff0c;被广泛应用于物流仓储、工厂制造等场景。旷视SLAM组主要负责多传感器建图、定位、标定…

Java8中的外观(JavaFX8)

JavaFX8在外观方面进行了一些更改 &#xff0c;其中最相关的是新CSS API &#xff0c;它允许您为控件以及已公开的Skin类创建新CSS属性和伪类。 使用CSS可以改变控件的很多外观&#xff0c;但是CSS只能实现很多功能&#xff0c;而这正是Skin类的用处。从“ UI控件体系结构”快…

600分理科选计算机专业,天津600分左右,计算机或电子信息专业,怎么选院校?...

原标题&#xff1a;天津600分左右&#xff0c;计算机或电子信息专业&#xff0c;怎么选院校&#xff1f;想学计算机或电子信息&#xff0c;一定是偏理选科对吧&#xff01;所谓的换算&#xff0c;是指的高考后出了全天津市不分文理的总排名后&#xff0c;如何换算成相当于天津市…

[TypeScript] Export public types from your library

If youre a library author, its useful to expose your public types as interfaces, to allow your consumers to extend them if needed. For example: To resolve the issues, we can do : // typings.d.tsinterface JQuery {hideChildren(): JQuery } 转载于:https://www.…

python tkinter选择路径控件_Python3 Tkinter选择路径功能的实现方法

效果基于Python3。 在自己写小工具的时候因为这个功能纠结了一会儿&#xff0c;这里写个小例子&#xff0c;供有需要的参考。 小例子&#xff0c;就是点击按钮打开路径选择窗口&#xff0c;选择后把值传给Entry输出。 效果预览 这是选择前&#xff1a;选择&#xff1a;选择后&a…

小米10pro使用说明书_华为Mate40、华为P40和小米10拍照对比:哪一款最好?

华为Mate 40 Pro、华为P40 Pro和小米10 Pro拍照对比&#xff1a;哪一款最好&#xff1f;华为Mate 40 Pro、小米10至尊纪念版、华为P40 Pro和小米10 Pro三款手机是在DxOMark上排名靠前的4部手机。而我们刚好拥有华为Mate 40 Pro、华为P40 Pro和小米10 Pro三款手机——作为同样搭…

xml和xml解析

1.简介XML XML 可扩展标记语言&#xff0c;传输数据 HTML超文本标记语言&#xff0c;显示数据 XML 文档声明 只能放在第一行&#xff0c;注释不能放在声明之前 <?xml version"1.0" encoding"UTF-8" standalone"no"?> standalone表示文…

win8.1 计算机 桌面快捷方式,win8.1操作系统中我的电脑在哪里?win8.1我的电脑快捷键添加方法介绍...

很多刚刚接触win8的用户会发现&#xff0c;xp中的“我的电脑”&#xff0c;win7中的“计算机”&#xff0c;到了win8难道只有“资源管理器”了吗&#xff1f;开始菜单里边倒是有“计算机”&#xff0c;但是无法放到桌面。在最新版的win8.1中也是如此&#xff0c;大家会发现熟悉…

mac你没有权限打开应用程序_如何管理Mac的隐私权限控制

在使用MAC电脑清理软件的时候&#xff0c;经常会出现需要权限问题&#xff0c;在没有权限的情况下&#xff0c;我们不能对一些文件进行更改和删除&#xff0c;那么该如何管理Mac的隐私权限控制呢&#xff1f;下面的文章就来告诉大家该如何设置隐身权限问题。第一步&#xff1a;…

Linux网卡绑定

很多情况下我们都需要用到网卡绑定这中情况&#xff0c;例如&#xff1a;大数据传输备份、网卡冗余。使用网卡绑定可以提高网络的传输速度&#xff0c;并且还能保证网络安全性&#xff0c;做到网卡的高可用&#xff0c;甚至可以节省IP地址。 网卡绑定模式 mode0&#xff1a;轮询…

c# 中通快递对接_快递共配是什么?行业前景怎么样?

首先了解快递共配是什么&#xff0c;随着快递市场竞争的加剧&#xff0c;降本增效成为快递网点越来越重视的方面&#xff0c;末端整合就成为快递网点普遍关注的一个焦点&#xff0c;即大家通常所说的共配。如何提升快递末端效率&#xff0c;一直都是快递企业比较关心的话题。不…

ceph存储原理_热门的分布式存储系统ceph入门介绍

一、什么是cephceph是当前最热门的分布式存储系统之一&#xff0c;是软件定义存储(SDS,SoftwareDefinedStorage)解决方案中的典范。其具备良好的可靠性、可扩展性&#xff0c;应用范围包括块存储(RBD,RadosBlockDevice)、文件存储(CephFS,CephFileSystem)和对象存储(RADOSGW,Re…

小程序点击调转带参数_带你走遍苏大的每个角落,校园导览小程序上线!

精彩推荐 1. 招新 | 携手趁韶华&#xff0c;约你同做“校媒人”&#xff01;2. 迎新现场 | 今天&#xff0c;“小20”是苏大的主角3. 苏州大学与亨通集团签订战略合作协议钟楼、红楼、精正楼……存菊堂、敬贤堂、子实堂……初至校园的“小20”们是否会有这样的烦恼在这楼宇亭台…

爬虫

爬虫 1、设计 分布式爬虫系统允许位于多个不同主机上的爬虫程序并行爬取提交的爬虫作业&#xff0c;进而协调他们之间的爬取能力。爬取队列由redis管理&#xff0c;每个spider通过修改的调度程序从queue中拉取job。 页面被spider成功爬取后&#xff0c;就交给管线进行进一步处理…

python下划线怎么输入_python下划线怎么打出来

python中下划线使用键盘上的Shift减号键即可打出&#xff0c;减号键位于0和加号键之间。 在Python中下划线还具有 private 和 protected 类似的访问权限作用&#xff0c;下面我们具体分析。Python主要存在四种命名&#xff1a; &#xff08;1&#xff09;object #公用方法 &…

二、先在SD卡上启动U-boot,再烧写新的U-boot进Nandflash

1. 制作SD卡 先准备一张2G的SD卡&#xff08;不能用8G的&#xff0c;2G的卡和8G的卡协议不一样&#xff09;&#xff0c;和烧写SD卡的工具write_sd以及需要烧写到SD卡中的u-boot-movi.bin。将SD卡格式化后连接到Ubuntu虚拟机中&#xff0c;注意在SD卡需要插入到读卡器中&#x…

java comparator_Java基础之String漫谈(二)

Java-String1. 导读上期分享了本人关于String四个问题, 本期我们继续探讨String中的两个问题:.1 String既然已经实现了Comparable接口, 为什么还要提供内部类----CaseInsensitiveComparator;.2 使用 "" 拼接String究竟干了什么? 为什么在循环中不让使用""…

掌握Java字节码

嘿! Happy Advent&#xff1a;D我是ZeroTurnaround的技术布道者Simon Maple&#xff08; sjmaple&#xff09; 。 您知道&#xff0c; JRebel伙计们&#xff01; 由于编写了类似于JRebel的产品&#xff0c;该产品与字节码进行交互的结果比您想像的更多&#xff0c;因此&#xf…

敲代码括号技巧_理解代码块概念,养成良好编程习惯 | 亲子课堂 第 3 课

亲子课堂关卡解析 / 英语教学 / 编程讲解 做亲子编程教育的好帮手&#xff01; 每周二、四定期更新 地牢面向真正0编程基础的孩子们&#xff0c;关卡被设计成迷宫的形式&#xff0c;引导孩子们使用编程思维解决问题。以循序渐进的方式&#xff0c;让大家理解掌握几个Pyth…

在struts2中push方法的使用_电脑使用中怎么截屏的几种方法

电脑在日常工作中经常需要用到截屏的操作&#xff0c;为了截取画面提供证明或者说明&#xff0c;像我就经常需要用到&#xff0c;当然我在写文章的时候更是需要用到&#xff0c;来配合文字的描述&#xff0c;使大家能更直观更容易的去操作&#xff0c;以达到快速解决电脑问题的…