图论模型:最短路
- 格式:ppt
- 大小:554.50 KB
- 文档页数:21
基于最短路问题的研究及应用令狐采学姓名:Fanmeng学号:指导老师:摘要最短路问题是图论中的一大问题,对最短路的研究在数学建模和实际生活中具有很重要的实际意义,介绍最短路问题的定义及这类问题的解决办法Dijkstra算法,并且能够在水渠修建实例运用到此数学建模的方法,为我们解决这类图论问题提供了基本思路与方法。
关键字数学建模最短路问题Dijkstra算法水渠修建。
目录第一章.研究背景1第二章.理论基础22.1 定义22.2 单源最短路问题Dijkstra求解:22.2.1 局限性22.2.2 Dijkstra算法求解步骤22.2.3 时间复杂度22.3 简单样例3第三章.应用实例43.1 题目描述43.2 问题分析43.3符号说明43.4 模型假设53.5模型建立与求解53.5.1模型选用53.5.2模型应用及求解53.6模型评价5第四章. 参考文献5第五章.附录6第一章.研究背景在现实生活中中,我们经常会遇到图类问题,图是一种有顶点和边组成,顶点代表对象,在示意图中我们经常使用点或者原来表示,边表示的是两个对象之间的连接关系,在示意图中,我们使用连接两点G点直接按的下端来表示。
顶点的集合是V,边的集合是E的图记为G[V,E] ,连接两点u和v的边用e(u,v)表示[1]。
最短问题是图论中的基础问题,也是解决图类问题的有效办法之一,在数学建模中会经常遇到,通常会把一个实际问题抽象成一个图,然后来进行求的接任意两点之间的最短距离。
因此掌握最短路问题具有很重要的意义。
第二章.理论基础2.1 定义最短路问题(short-path problem ):若网络中的每条边都有一个数值(长度、成本、时间等),则找出两节点,(通常是源节点和目标节点)之间总权和最小的路径就是最短路问题。
最短路问题是网络理论解决的典型问题之一,可用来解决管道铺设,线路安装,厂区布局和设备更新等实际问题[2]。
2.2 单源最短路问题Dijkstra 求解: 2.2.1局限性Dijkstra 算法不能够处理带有负边的图,即图中任意两点之间的权值必须非负。
最短路dijkstra算法详解最短路问题是图论中的一个经典问题,其目标是在给定图中找到从一个起点到其他所有节点的最短路径。
Dijkstra算法是解决最短路问题的一种常用算法,本文将详细介绍Dijkstra算法的原理、实现以及时间复杂度等相关内容。
一、Dijkstra算法的原理Dijkstra算法是一种贪心算法,其基本思想是从起点开始,逐步扩展到其他节点。
具体而言,Dijkstra算法通过维护一个集合S来记录已经找到了最短路径的节点,以及一个数组dist来记录每个节点到起点的距离。
初始时,S集合为空,dist数组中除了起点外所有节点都被初始化为无穷大。
接下来,重复以下步骤直到所有节点都被加入S集合:1. 从dist数组中选择距离起点最近的未加入S集合的节点u;2. 将u加入S集合;3. 更新与u相邻的未加入S集合的节点v的距离:如果从起点出发经过u可以得到更短的路径,则更新v对应位置上dist数组中存储的值。
重复以上步骤直至所有节点都被加入S集合,并且dist数组中存储了每个节点到起点的最短距离。
最后,根据dist数组中存储的信息可以得到起点到任意节点的最短路径。
二、Dijkstra算法的实现在实现Dijkstra算法时,需要使用一个优先队列来维护未加入S集合的节点,并且每次从队列中选择距离起点最近的节点。
由于C++标准库中没有提供优先队列,因此需要手动实现或者使用第三方库。
以下是一个基于STL堆实现的Dijkstra算法代码示例:```c++#include <iostream>#include <vector>#include <queue>using namespace std;const int INF = 0x3f3f3f3f;vector<pair<int, int>> adj[10001];int dist[10001];void dijkstra(int start) {priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;pq.push(make_pair(0, start));dist[start] = 0;while (!pq.empty()) {int u = pq.top().second;pq.pop();for (auto v : adj[u]) {if (dist[u] + v.second < dist[v.first]) {dist[v.first] = dist[u] + v.second;pq.push(make_pair(dist[v.first], v.first));}}}}int main() {int n, m, start;cin >> n >> m >> start;for (int i = 1; i <= n; i++) {dist[i] = INF;}for (int i = 1; i <= m; i++) {int u, v, w;cin >> u >> v >> w;adj[u].push_back(make_pair(v, w));}dijkstra(start);for (int i = 1; i <= n; i++) {if (dist[i] == INF) {cout << "INF" << endl;} else {cout << dist[i] << endl;}}return 0;}```以上代码中,adj数组用于存储图的邻接表,dist数组用于存储每个节点到起点的最短距离。
图论——单源最短路一、最短路两点之间的最短路:给定一个带权图,图中两点i与j的最短路是指从i到j的一条路径,这条路径经过的边的权值之和最小。
求单源最短路:给定一个带权图,求图以结点start为起点的单源最短路是指对每一个结点j<>start,求出start到j的最短路。
二、图的存储方式对于求最短路类问题的算法,图的不同存储方式会产生很大的影响,总的来说,图的存储方式有邻接矩阵,邻接表,前向星等几种。
邻接矩阵:这种存储方法需要开设一个V^2的二维数组edge,对于每两个顶点i和j,如果ij有边,则edge[i,j]=w[i,j],否则edge[i,j]=-1,这里w[i,j]为边Eij的权。
邻接表:邻接表有链表与数组两种实现方式,如果用数组实现,同邻接矩阵一样需要一个V^2的二维数组edge,edge的每个元素包含两个信息:终点和权值。
另有一个数组a记录从指定顶点出发的边数。
对于每个顶点i,edge[i, j](j=1~a[i])表示从i出发的第j条边的终点与权值。
若用链表实现邻接表,我们可以将edge减成一维,在每个edge[i]后面连一条链表,链表上的每个结点都表示由i出发的一条边。
前向星:前向星的存法只需两个一维数组pos与edge,其中edge[i]存储了第i条边的信息,这些边是按照起点由小到大排好序的,而pos[i]则表示以i为起点的第一条边的位置。
这样在edge[pos[i]~pos[i+1]-1]中便可找到从i出发的所有边的信息。
以下的例子显示了这四种存储图的方法:2 4邻接矩阵:邻接表(数组):邻接表(链表):edge各种存储方法的比较:#对于稀疏图而言,复杂度约为常数。
*需要一个O(ElogE)的预处理(排序)。
总的来说,邻接矩阵比较好编写,存储方式简单明了,适合中小规模数据;用数组实现的邻接表与邻接矩阵相差不多;用链表实现的邻接表编程复杂度较高,但效率很好,适合各种各样的图论类题目;前向星只对数组进行操作,编写不是很难,同时效率也不错,在不需要修改边的最短路问题中,前向星是遇到大数据时的最佳选择。