数学建模学习笔记(七)——图论最短路问题
文章目錄
- 一、綜述
- 二、圖論最短路問題
- 三、幾個(gè)簡單的作圖方法
- 四、Dijkstra(迪杰斯特拉)算法
- 五、Bellman-Ford算法
- 六、總結(jié)
一、綜述
本文主要根據(jù)圖論的基本概念,介紹圖論中常見的建模問題——最短路問題。同時(shí),介紹了解決圖論最短路問題的兩種算法:Dijkstra(迪杰斯特拉)算法和Bellman-Ford(貝爾曼-福特)算法。
在此之前,需要具備基本的圖論知識哦~~~
二、圖論最短路問題
圖論最短路問題指的是在帶權(quán)重的圖中,求出一條從一點(diǎn)節(jié)點(diǎn)到另一個(gè)節(jié)點(diǎn)的路徑,使這條路徑上的權(quán)重之和最小。
三、幾個(gè)簡單的作圖方法
1.CS Academy:
https://csacademy.com/app/graph_editor/
2. Matlab:
無向圖:graph()函數(shù)
有向圖:digraph()函數(shù)
四、Dijkstra(迪杰斯特拉)算法
DijkstraDijkstraDijkstra(迪杰斯特拉)算法描述
假設(shè)未選取的節(jié)點(diǎn)集合未V,已選取的節(jié)點(diǎn)集合為S。
-除起點(diǎn)外,其他節(jié)點(diǎn)初始距離為 ∞\infty∞,起點(diǎn)距離為0。
-更新節(jié)點(diǎn)之間的距離(相鄰接的節(jié)點(diǎn)距離即為權(quán)值,不相鄰接的節(jié)點(diǎn)距離仍為 ∞\infty∞)。
-選取另一個(gè)未被選取過且距離最小的節(jié)點(diǎn)作為中轉(zhuǎn)點(diǎn),更新距離。(原距離 + 該節(jié)點(diǎn)和目標(biāo)節(jié)點(diǎn)的權(quán)值 < 目標(biāo)節(jié)點(diǎn)的原距離,則更新目標(biāo)節(jié)點(diǎn)的距離為前者;否則不更新)。
-重復(fù)第三步,直到到達(dá)目標(biāo)節(jié)點(diǎn)。
下面來看一個(gè)例子:
有一個(gè)旅行者想要從 v1v1v1 節(jié)點(diǎn)到 v8v8v8 ,求出最短旅行路線。
解決步驟
第一步:初始化表格
| 是否已被訪問(0/1) | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 距離 | inf?\infinf | inf?\infinf | inf?\infinf | inf?\infinf | inf?\infinf | inf?\infinf | inf?\infinf | inf?\infinf | inf?\infinf |
| 父親節(jié)點(diǎn) | -1 | -1 | -1 | -1 | -1 | -1 | -1 | -1 | -1 |
第二步:從 v1 節(jié)點(diǎn)開始
| 是否已被訪問(0/1) | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 距離 | 0 | inf?\infinf | inf?\infinf | inf?\infinf | inf?\infinf | inf?\infinf | inf?\infinf | inf?\infinf | inf?\infinf |
| 父親節(jié)點(diǎn) | v1 | -1 | -1 | -1 | -1 | -1 | -1 | -1 | -1 |
第三步:更新從 v1 可到達(dá)的節(jié)點(diǎn)的距離
| 是否已被訪問(0/1) | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 距離 | 0 | 6 | 3 | 1 | inf?\infinf | inf?\infinf | inf?\infinf | inf?\infinf | inf?\infinf |
| 父親節(jié)點(diǎn) | v1 | v1 | v1 | v1 | -1 | -1 | -1 | -1 | -1 |
第四步:取距離最小的節(jié)點(diǎn) v4 作為中轉(zhuǎn)點(diǎn),更新從 v4 可到達(dá)的節(jié)點(diǎn)標(biāo)號(注意比較與原距離的大小)
| 是否已被訪問(0/1) | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
| 距離 | 0 | 6 | 3 | 1 | inf?\infinf | inf?\infinf | inf?\infinf | inf?\infinf | inf?\infinf |
| 父親節(jié)點(diǎn) | v1 | v1 | v1 | v1 | -1 | -1 | -1 | -1 | -1 |
第五步:更新后的結(jié)果
| 是否已被訪問(0/1) | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
| 距離 | 0 | 6 | 3 | 1 | inf?\infinf | 11 | inf?\infinf | inf?\infinf | inf?\infinf |
| 父親節(jié)點(diǎn) | v1 | v1 | v1 | v1 | -1 | v4 | -1 | -1 | -1 |
第六步:再取距離最小的節(jié)點(diǎn) v3 作為中轉(zhuǎn)點(diǎn),更新從 v3 可到達(dá)的節(jié)點(diǎn)標(biāo)號(注意比較與原距離的大小)
| 是否已被訪問(0/1) | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 |
| 距離 | 0 | 6 | 3 | 1 | inf?\infinf | 11 | inf?\infinf | inf?\infinf | inf?\infinf |
| 父親節(jié)點(diǎn) | v1 | v1 | v1 | v1 | -1 | v4 | -1 | -1 | -1 |
第七步:更新后的結(jié)果(由于3 + 2(v3 到 v2 的距離)= 5 < 6,因此更新 v2 列的距離)
| 是否已被訪問(0/1) | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 |
| 距離 | 0 | 5 | 3 | 1 | inf?\infinf | 11 | inf?\infinf | inf?\infinf | inf?\infinf |
| 父親節(jié)點(diǎn) | v1 | v3 | v1 | v1 | -1 | v4 | -1 | -1 | -1 |
第八步:再取距離最小的節(jié)點(diǎn) v2 作為中轉(zhuǎn)點(diǎn),更新從 v2 可到達(dá)的節(jié)點(diǎn)標(biāo)號(注意比較與原距離的大小)
| 是否已被訪問(0/1) | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 |
| 距離 | 0 | 5 | 3 | 1 | 6 | 11 | inf?\infinf | inf?\infinf | inf?\infinf |
| 父親節(jié)點(diǎn) | v1 | v3 | v1 | v1 | v2 | v4 | -1 | -1 | -1 |
第九步:再取距離最小的節(jié)點(diǎn) v5 作為中轉(zhuǎn)點(diǎn),更新從 v5 可到達(dá)的節(jié)點(diǎn)標(biāo)號(注意比較與原距離的大小)
| 是否已被訪問(0/1) | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 |
| 距離 | 0 | 5 | 3 | 1 | 6 | 11 | inf?\infinf | inf?\infinf | inf?\infinf |
| 父親節(jié)點(diǎn) | v1 | v3 | v1 | v1 | v2 | v4 | -1 | -1 | -1 |
第十步:更新后的結(jié)果
| 是否已被訪問(0/1) | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 |
| 距離 | 0 | 5 | 3 | 1 | 6 | 10 | 9 | 12 | inf?\infinf |
| 父親節(jié)點(diǎn) | v1 | v3 | v1 | v1 | v2 | v5 | v5 | v5 | -1 |
第十一步:再取距離最小的節(jié)點(diǎn) v7 作為中轉(zhuǎn)點(diǎn),更新從 v7 可到達(dá)的節(jié)點(diǎn)標(biāo)號(注意比較與原距離的大小)
| 是否已被訪問(0/1) | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | 0 |
| 距離 | 0 | 5 | 3 | 1 | 6 | 10 | 9 | 12 | inf?\infinf |
| 父親節(jié)點(diǎn) | v1 | v3 | v1 | v1 | v2 | v5 | v5 | v5 | -1 |
第十二步:再取距離最小的節(jié)點(diǎn) v6 作為中轉(zhuǎn)點(diǎn),更新從 v6 可到達(dá)的節(jié)點(diǎn)標(biāo)號(注意比較與原距離的大小)
| 是否已被訪問(0/1) | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 |
| 距離 | 0 | 5 | 3 | 1 | 6 | 10 | 9 | 12 | inf?\infinf |
| 父親節(jié)點(diǎn) | v1 | v3 | v1 | v1 | v2 | v5 | v5 | v5 | -1 |
第十三步:再取距離最小的節(jié)點(diǎn) v8 作為中轉(zhuǎn)點(diǎn),更新從 v8 可到達(dá)的節(jié)點(diǎn)標(biāo)號(注意比較與原距離的大小)
| 是否已被訪問(0/1) | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 |
| 距離 | 0 | 5 | 3 | 1 | 6 | 10 | 9 | 12 | 15 |
| 父親節(jié)點(diǎn) | v1 | v3 | v1 | v1 | v2 | v5 | v5 | v5 | v8 |
第十四步:最終結(jié)果
| 是否已被訪問(0/1) | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
| 距離 | 0 | 5 | 3 | 1 | 6 | 10 | 9 | 12 | 15 |
| 父親節(jié)點(diǎn) | v1 | v3 | v1 | v1 | v2 | v5 | v5 | v5 | v8 |
可以從終點(diǎn)v8倒推:v8?v5?v2?v3?v1v_8 \Leftarrow v_5 \Leftarrow v_2 \Leftarrow v_3 \Leftarrow v_1v8??v5??v2??v3??v1?,這就是最短路徑。將路徑上的權(quán)值相加可以得出,最短路徑的長度為:12(可以直接有 v8 那一列的距離得出),結(jié)果如圖:
若只考慮路徑長度,而不考慮具體路徑,還可以這樣列表:
| 0 | ∞\infty∞ | ∞\infty∞ | ∞\infty∞ | ∞\infty∞ | ∞\infty∞ | ∞\infty∞ | ∞\infty∞ | ∞\infty∞ |
| $ | 6 | 3 | 1 | ∞\infty∞ | ∞\infty∞ | ∞\infty∞ | ∞\infty∞ | ∞\infty∞ |
| $ | 6 | 3 | ∞\infty∞ | 11 | ∞\infty∞ | ∞\infty∞ | ∞\infty∞ | |
| $ | 5 | ∞\infty∞ | 11 | ∞\infty∞ | ∞\infty∞ | ∞\infty∞ | ||
| $ | 6 | 11 | ∞\infty∞ | ∞\infty∞ | ∞\infty∞ | |||
| $ | 10 | 9 | 12 | ∞\infty∞ | ||||
| $ | 10 | 9 | 12 | ∞\infty∞ | ||||
| $ | 12 | ∞\infty∞ | ||||||
| $ | 15 |
加粗的數(shù)字即為從起點(diǎn)到各節(jié)點(diǎn)的最短路徑長度。
Dijkstra(迪杰斯特拉)算法的局限
DijkstraDijkstraDijkstra(迪杰斯特拉)算法可以用于解決無向帶權(quán)圖和有向帶權(quán)圖的最短路徑問題。但是要求權(quán)重全是正數(shù),不能使負(fù)數(shù)。為了解決帶負(fù)權(quán)重的最短路徑問題,我們可以采用 Bellman?FordBellman-FordBellman?Ford(貝爾曼-福特)算法來解決。
五、Bellman-Ford算法
貝爾曼-福特算法實(shí)際上處理的是具有負(fù)權(quán)重的有向圖(且該有向圖不能含有負(fù)權(quán)回路,因此函數(shù)負(fù)權(quán)回路的圖可以在權(quán)重的回路中不斷循環(huán),路徑長無窮小)
貝爾曼-福特算法簡介
更新規(guī)則:如果(A與B的距離 + A列表中的距離)< (B列表中的距離),那么我們就將B列表中的距離更新為較小的距離,并將B的父親節(jié)點(diǎn)更新為A。
在 Matlab 中使用貝爾曼-福特算法
在 MatlabMatlabMatlab 中調(diào)用命令:[P, d] = shortestpath(G, start, end [, 'Method', algorithm])
輸入?yún)?shù):{G:輸入圖對象start:起始的節(jié)點(diǎn)end:目標(biāo)的節(jié)點(diǎn)[,′Method′,algorithm]:可選參數(shù),表示計(jì)算路徑所使用的算法。默認(rèn)為‘a(chǎn)uto’輸入?yún)?shù):\left\{ \begin{aligned} &G:\text{輸入圖對象} \\ &start:\text{起始的節(jié)點(diǎn)} \\ &end:\text{目標(biāo)的節(jié)點(diǎn)} \\&[, 'Method', algorithm]:\text{可選參數(shù),表示計(jì)算路徑所使用的算法。默認(rèn)為‘a(chǎn)uto’} \end{aligned}\right.輸入參數(shù):?????????????G:輸入圖對象start:起始的節(jié)點(diǎn)end:目標(biāo)的節(jié)點(diǎn)[,′Method′,algorithm]:可選參數(shù),表示計(jì)算路徑所使用的算法。默認(rèn)為‘a(chǎn)uto’?
輸出參數(shù):{P:最短路徑經(jīng)過的節(jié)點(diǎn)d:最短距離輸出參數(shù):\left\{ \begin{aligned} &P:\text{最短路徑經(jīng)過的節(jié)點(diǎn)} \\ &d:\text{最短距離} \end{aligned} \right.輸出參數(shù):{?P:最短路徑經(jīng)過的節(jié)點(diǎn)d:最短距離?
可選的算法:{auto:自動選擇算法unweighted:廣度優(yōu)先計(jì)算,將所有便權(quán)重視為1positive:Dijkstra算法mixed:Bellman-Ford算法可選的算法:\left\{ \begin{aligned} &auto:\text{自動選擇算法} \\ &unweighted:\text{廣度優(yōu)先計(jì)算,將所有便權(quán)重視為1} \\ &positive:\text{Dijkstra算法} \\ &mixed:\text{Bellman-Ford算法} \end{aligned}\right.可選的算法:?????????????auto:自動選擇算法unweighted:廣度優(yōu)先計(jì)算,將所有便權(quán)重視為1positive:Dijkstra算法mixed:Bellman-Ford算法?
六、總結(jié)
如果有什么錯(cuò)誤,請一定提出哦~~~
總結(jié)
以上是生活随笔為你收集整理的数学建模学习笔记(七)——图论最短路问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 没有bug队——加贝——Python 4
- 下一篇: rtmp协议 java_基于rtmp协议