最短路径-Dijkstra算法与Floyd算法
一、最短路径
①在非网图中,最短路径是指两顶点之间经历的边数最少的路径。
AE:1 ADE:2 ADCE:3 ABCE:3
②在网图中,最短路径是指两顶点之间经历的边上权值之和最短的路径。
AE:100 ADE:90 ADCE:60 ABCE:70
③单源点最短路径问题
问题描述:给定带权有向图G=(V, E)和源点v∈V,求从v到G中其余各顶点的最短路径。
应用实例——计算机网络传输的问题:怎样找到一种最经济的方式,从一台计算机向网上所有其它计算机发送一条消息。
④每一对顶点之间的最短路径
问题描述:给定带权有向图G=(V, E),对任意顶点vi,vj∈V(i≠j),求顶点vi到顶点vj的最短路径。
解决办法1:每次以一个顶点为源点,调用Dijkstra算法n次。显然,时间复杂度为O(n3)。 解决办法2:弗洛伊德提出的求每一对顶点之间的最短路径算法——Floyd算法,其时间复杂度也是O(n3),但形式上要简单些。
二、Dijkstra算法
①基本思想:设置一个集合S存放已经找到最短路径的顶点,S的初始状态只包含源点v,对vi∈V-S,假设从源点v到vi的有向边为最短路径。以后每求得一条最短路径v, …, vk,就将vk加入集合S中,并将路径v, …, vk , vi与原来的假设相比较,取路径长度较小者为最短路径。重复上述过程,直到集合V中全部顶点加入到集合S中。
②设计数据结构 :
1、图的存储结构:带权的邻接矩阵存储结构 。
2、数组dist[n]:每个分量dist[i]表示当前所找到的从始点v到终点vi的最短路径的长度。初态为:若从v到vi有弧,则dist[i]为弧上权值;否则置dist[i]为∞。
3、数组path[n]:path[i]是一个字符串,表示当前所找到的从始点v到终点vi的最短路径。初态为:若从v到vi有弧,则path[i]为vvi;否则置path[i]空串。
4、数组s[n]:存放源点和已经生成的终点,其初态为只有一个源点v。
③Dijkstra算法——伪代码
. 初始化数组dist、path和s;
. while (s中的元素个数<n)
2.1 在dist[n]中求最小值,其下标为k;
2.2 输出dist[j]和path[j];
2.3 修改数组dist和path;
2.4 将顶点vk添加到数组s中;
④C++代码实现
#include<iostream>
#include<fstream>
#include<string>
using namespace std;
#define MaxSize 10
#define MAXCOST 10000
// 图的结构
template<class T>
struct Graph
{
T vertex[MaxSize];// 存放图中顶点的数组
int arc[MaxSize][MaxSize];// 存放图中边的数组
int vertexNum, arcNum;// 图中顶点数和边数
};
// 最短路径Dijkstra算法
void Dijkstra(Graph<string> G,int v)
{
int dist[MaxSize];// i到j的路径长度
string path[MaxSize];// 路径的串
int s[MaxSize];// 已找到最短路径的点的集合
bool Final[MaxSize];//Final[w]=1表示求得顶点V0至Vw的最短路径
// 初始化dist\path
for (int i = ; i < G.vertexNum; i++)
{
Final[i] = false;
dist[i] = G.arc[v][i];
if (dist[i] != MAXCOST)
path[i] = G.vertex[v] + G.vertex[i];
else
path[i] = " ";
}
s[] = v; // 初始化s
Final[v] = true;
int num = ;
while (num < G.vertexNum)
{
// 在dist中查找最小值元素
int k = ,min= MAXCOST;
for (int i = ; i < G.vertexNum; i++)
{
if (i == v)continue;
if (!Final[i] && dist[i] < min)
{
k = i;
min = dist[i];
}
}
cout << dist[k]<<path[k]<<endl;
s[num++] = k;// 将新生成的结点加入集合s
Final[k] = true;
// 修改dist和path数组
for (int i = ; i < G.vertexNum; i++)
{
if (!Final[i]&&dist[i] > dist[k] + G.arc[k][i])
{
dist[i] = dist[k] + G.arc[k][i];
path[i] = path[k] + G.vertex[i];
}
}
}
}
int main()
{
// 新建图
Graph<string> G;
string temp[]= { "v0","v1","v2","v3","v4" };
/*int length = sizeof(temp) / sizeof(temp[0]);
G.vertexNum = length;
G.arcNum = 7;*/
ifstream in("input.txt");
in >> G.vertexNum >> G.arcNum;
// 初始化图的顶点信息
for (int i = ; i < G.vertexNum; i++)
{
G.vertex[i] = temp[i];
}
//初始化图G的边权值
for (int i =; i <G.vertexNum; i++)
{
for (int j = ; j <G.vertexNum; j++)
{
G.arc[i][j] = MAXCOST;
}
}
for (int i = ; i < G.arcNum; i++)
{
int m, n,cost;
in >> m >> n >> cost;
G.arc[m][n] = cost;
}
Dijkstra(G, );
system("pause");
return ;
}
// input.txt
1
三、Floyd算法
①基本思想:对于从vi到vj的弧,进行n次试探:首先考虑路径vi,v0,vj是否存在,如果存在,则比较vi,vj和vi,v0,vj的路径长度,取较短者为从vi到vj的中间顶点的序号不大于0的最短路径。在路径上再增加一个顶点v1,依此类推,在经过n次比较后,最后求得的必是从顶点vi到顶点vj的最短路径。
②设计数据结构
1、图的存储结构:带权的邻接矩阵存储结构 。
2、数组dist[n][n]:存放在迭代过程中求得的最短路径长度。迭代公式:
3、数组path[n][n]:存放从vi到vj的最短路径,初始为path[i][j]="vivj"。
③C++代码实现
#include<iostream>
#include<fstream>
#include<string>
using namespace std;
#define MaxSize 10
#define MAXCOST 10000
int dist[MaxSize][MaxSize];// 存放在迭代过程中求得的最短路径
string path[MaxSize][MaxSize];// vi到vj的最短路径
// 图的结构
template<class T>
struct Graph
{
T vertex[MaxSize];// 存放图中顶点的数组
int arc[MaxSize][MaxSize];// 存放图中边的数组
int vertexNum, arcNum;// 图中顶点数和边数
};
void Floyd(Graph<string> G)
{
// 初始化
for(int i=;i<G.vertexNum;i++)
for (int j = ; j < G.vertexNum; j++)
{
if (i == j) { dist[i][j] = ; path[i][j] = ""; }
dist[i][j] = G.arc[i][j];
if (dist[i][j] != MAXCOST)
path[i][j] = G.vertex[i] + G.vertex[j];
else
path[i][j] = " ";
}
// 进行n次迭代
for(int k=;k<G.vertexNum;k++)
for(int i=;i<G.vertexNum;i++)
for (int j = ; j < G.vertexNum; j++)
if (dist[i][k] + dist[k][j] < dist[i][j])
{
dist[i][j] = dist[i][k] + dist[k][j];
path[i][j] = path[i][k] + path[k][j];
}
}
int main()
{
int i, j, cost;
Graph<string> G;// 存放图的信息
ifstream in("input.txt");
in >> G.vertexNum >> G.arcNum;
string temp[] = { "a","b","c" };
// 初始化图的顶点信息
for (int i = ; i < G.vertexNum; i++)
{
G.vertex[i] = temp[i];
}
//初始化图G
for (i = ; i < G.vertexNum; i++)
{
for (j = ; j < G.vertexNum; j++)
{
G.arc[i][j] = MAXCOST;
}
}
//构建图G
for (int k = ; k <G.arcNum; k++)
{
in >> i >> j >> cost;
G.arc[i][j] = cost;
}
Floyd(G);
for (i = ; i < G.vertexNum; i++)
{
for (j = ; j < G.vertexNum; j++)
{
if (i != j)
{
cout << "顶点" << i << "到顶点" << j << "的最短路径长度为" << dist[i][j] << endl;
cout << "具体路径为:" << path[i][j] << endl;
}
}
}
system("pause");
return ;
}
// input.txt
参考文献:
[1]王红梅, 胡明, 王涛. 数据结构(C++版)[M]. 北京:清华大学出版社。
最短路径-Dijkstra算法与Floyd算法的更多相关文章
- 最短路径——Dijkstra算法和Floyd算法
Dijkstra算法概述 Dijkstra算法是由荷兰计算机科学家狄克斯特拉(Dijkstra)于1959 年提出的,因此又叫狄克斯特拉算法.是从一个顶点到其余各顶点的最短路径算法,解决的是有向图(无 ...
- 最短路径Dijkstra算法和Floyd算法整理、
转载自:http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html 最短路径—Dijkstra算法和Floyd算法 Dijks ...
- 【转】最短路径——Dijkstra算法和Floyd算法
[转]最短路径--Dijkstra算法和Floyd算法 标签(空格分隔): 算法 本文是转载,原文在:最短路径-Dijkstra算法和Floyd算法 注意:以下代码 只是描述思路,没有测试过!! Di ...
- 最短路径—Dijkstra算法和Floyd算法
原文链接:http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html 最后边附有我根据文中Dijkstra算法的描述使用jav ...
- 最短路径—Dijkstra算法和Floyd算法【转】
本文来自博客园的文章:http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html Dijkstra算法 1.定义概览 Dijk ...
- 图的最短路径——dijkstra算法和Floyd算法
dijkstra算法 求某一顶点到其它各个顶点的最短路径:已知某一顶点v0,求它顶点到其它顶点的最短路径,该算法按照最短路径递增的顺序产生一点到其余各顶点的所有最短路径. 对于图G={V,{E}};将 ...
- 【转载】最短路径—Dijkstra算法和Floyd算法
注意:以下代码 只是描述思路,没有测试过!! Dijkstra算法 1.定义概览 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始 ...
- 最短路径—Dijkstra 算法和Floyd 算法
某省自从实行了很多年的畅通工程计划后,终于修建了很多路.不过路多了也不好,每次要从一个城镇到另一个城镇时,都有许多种道路方案可以选择,而某些方案要比另一些方案行走的距离要短很多.这让行人很困扰. 现在 ...
- C++编程练习(11)----“图的最短路径问题“(Dijkstra算法、Floyd算法)
1.Dijkstra算法 求一个顶点到其它所有顶点的最短路径,是一种按路径长度递增的次序产生最短路径的算法. 算法思想: 按路径长度递增次序产生算法: 把顶点集合V分成两组: (1)S:已求出的顶点的 ...
- 最小生成树(prime算法 & kruskal算法)和 最短路径算法(floyd算法 & dijkstra算法)
一.主要内容: 介绍图论中两大经典问题:最小生成树问题以及最短路径问题,以及给出解决每个问题的两种不同算法. 其中最小生成树问题可参考以下题目: 题目1012:畅通工程 http://ac.jobdu ...
随机推荐
- JAVA学习3:Eclipse中集成Tomcat
问题: 很多时候在Eclipse中启动Tmocat后,不能访问本机的localhost:8080主页,并且其他项目也不能访问. 原因: 打开Tomcat下的webapp后也找补到项目目录,这是因为Ec ...
- Android表格布局之设置边框
Android表格布局本身没有边框,不过可以通过背景色的设置可以实现表格边框的显示. 首先可以设置TableRow的背景色,然后设置内容的背景色.根据它们的颜色差就出现了边框.只要微调Content与 ...
- java 实现一套流程管理、流转的思路(伪工作流)
在做某个管理项目时,被要求实现一套流程管理,比如请假的申请审批流程等,在参考了很多资料,并和同事讨论后,得到了一个自主实现的流程管理. 以下提供我的设计思路,知道了思路,实现起来就简单很多了. 首先我 ...
- 日调度万亿次,微服务框架TSF大规模应用——云+未来峰会开发者专场回顾
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 演讲者:张浩 腾讯云中间件产品负责人 背景:众多开发者中,一定经历类似的甜蜜烦恼,就是当线上业务规模越来越大,系统分支发展越来越多的时候,初 ...
- MySql数据库与JDBC编程三
多表连接查询(两种规范 SQL92和SQL99) SQL92规范: 等值连接,非等值连接,外连接,广义笛卡儿积连接 多个表都放在from后,,连接条件放在where后,条件要求两列值相等,则为等值连接 ...
- Java - 线程封闭
保证并发安全性的方式有三: 不共享.不可变.同步 前两种方式相对第三种要简单一些. 这一篇不说语言特性和API提供的相关同步机制,主要记录一下关于共享的一些思考. 共享(shared),可以简单地认为 ...
- Error:All flavors must now belong to a named flavor dimension.
环境 android studio 3.0 错误 Error:All flavors must now belong to a named flavor dimension. 解决 在build.gr ...
- svn怎么下载代码到本地
1. 在我们安装好svn时,在指定的目录中点击鼠标右键SVN Checkout,弹出以下窗口.(在文件夹下各自建好前后台的文件夹分别check) 2. 在URL of repository:(存储库的 ...
- 详细解释什么是JavaEE?
也许你学习了那么久的Java了,但如果有人问你什么是JavaEE?你会怎么回答他呢?在此我来谈谈关于JavaEE的相关技术.(仅是个人见解) 在谈JavaEE时,我们首先来了解一下Java平台.目前, ...
- git版本控制的使用
特别说明:本文所有知识笔记是学习“表严肃”同学的git课程记录所得. 前辈个人网站地址:http://biaoyansu.com 特此感谢前辈! 一.git是版本控制利器 二.本地创建仓库 1.进入新 ...