最短路徑-Floyd演算法的matlab實現.md
最短路徑-Floyd演算法的matlab實現
弗洛伊德演算法是解決任意兩點間的最短路徑的一種演算法,可以正確處理有向圖或有向圖或負權(但不可存在負權迴路)的最短路徑問題。
在Floyd演算法中一般有兩個矩陣,一個距離矩陣D,一個路由矩陣R,其中距離矩陣用於儲存任意兩點之間的最短距離,而路由矩陣則記錄任意兩點之間的最短路徑資訊。
其思想是:如果可以從一個點進行中轉,就進行比較從這個點中轉和不中轉的距離,儲存距離小的情況,並更新距離矩陣和路由矩陣。
從演算法思想中我們可以大概推斷我們要遍歷n箇中轉點,在每個中轉點進行操作的時候,需要對任意兩點之間 的距離進行遍歷。那麼演算法就應該有三重迴圈,第一重迴圈是遍歷中轉點,第二重和第三重迴圈是遍歷任意兩個點之間的距離。假設中轉節點為K,那麼節點i與j之間的最小距離怎麼更新呢?
其中D(i,K)+D(K,j)表示i到j從K中轉的距離,D(i,j)表示從i到j的最短距離,如果前者比後者小,那麼就D(i,j)進行更新:,這樣就更新了距離矩陣。怎麼記錄這條最短路徑呢,這個時候就需要更新我們的路由矩陣:
路由矩陣很好理解,比如最開始是R(4,3) = 3,表示V4到V3一步就可以到達V3,如果現在可以從V2中轉到達,那麼R(4,3) = R(4,2) =2,表示V4->V3要先經過V2才能到達。
下面我將用一個簡單的例子來說明,下面是一個簡單的例子:
這個時候我們可以寫出距離矩陣D和路由矩陣R如下:
上面是初始的距離矩陣和路由矩陣,現在我們假設:**圖中的每個點之間可以經由V1中轉**。這個時候我們再來判斷任意兩點之間的最短距離。可以由V1中轉,那麼V1到到各個點的距離還是不變。V2沒有到達V1的路徑,所以也就不存在從V1中轉的情況,所以V2到各個點的距離還是不變。
V3可以經由V1中轉,那麼這個時候判斷一下中轉前和中轉後的距離大小,將最小距離留存下來如:
V3->V1 = 7 不變
V3->V2 = inf,經由V1中轉之後V3->V1->V2 = 9, 於是V3到V2的最短距離變化為9,更新路由矩陣R(3,2) = R(3,1) = 1
V3->V4 = 1,經由V1中轉之後V3->V1->V4 = 11, 於是V3到V4的最短距離就還是1
同理:
V4->V2 = inf, 經由V1中轉之後V4->V1->V2 = 7, 於是V4到V2的最短距離變化為7,更新路由矩陣R(4,2) = R(4,1) = 1
V4->V3 = 12,經由V1中轉之後V4->V1->V3 = 11, 於是V4到V2的最短距離變化為11,更新路由矩陣R(4,3) = R(4,1) = 1
那麼距離矩陣和路由矩陣變化為:
現在假設在從V1中轉的基礎上,圖中的每個點之間還可以經由V2中轉,於是:
V1->V2 = 2
V1->V3 = 6,經由V2中轉之後V1->V2->V3 = 5, 於是V1到V3的最短距離變化為5,更新路由矩陣R(1,3) = R(1,2) = 2
V1->V4 = 4
V2->V1 = inf
V2->V3 = 3
V2->V4 = inf
V3->V1 = 7
V3->V2 = 9
V3->V4 = 1
V4->V1 = 5
V4->V2 = 7
V4->V3 = 11,經由V2中轉之後V4->V2->V3 = 10, 於是V4到V3的最短距離變化為10,更新路由矩陣R(4,3) = R(4,2) = 1。
於是現在的距離矩陣和路由矩陣可以變為:
現在假設在從V1中轉的基礎上,圖中的每個點之間還可以經由V3中轉,於是:
V1->V2 = 2
V1->V3 = 5
V1->V4 = 4
V2->V1 = inf,經由V3中轉之後V2->V3->V1 = 10, 於是V2到V1的最短距離變化為10,更新路由矩陣R(2,1) = R(2,3) = 3。
V2->V3 = 3
V2->V4 = inf,經由V3中轉之後V2->V3->V4 = 4, 於是V2到V5的最短距離變化為4,更新路由矩陣R(2,4) = R(2,3) = 3。
V3->V1 = 7
V3->V2 = 9
V3->V4 = 1
V4->V1 = 5
V4->V2 = 7
V4->V3 = 10
於是現在的距離矩陣和路由矩陣可以變為:
現在假設在從V1中轉的基礎上,圖中的每個點之間還可以經由V4中轉,於是:
V1->V2 = 2
V1->V3 = 5
V1->V4 = 4
V2->V1 = 10,經由V4中轉之後V2->V4->V1 = 9, 於是V3到V1的最短距離變化為9,更新路由矩陣R(2,1) = R(2,4) = 3。
V2->V3 = 3
V2->V4 = 4
V3->V1 = 7,經由V4中轉之後V3->V4->V1 = 6, 於是V3到V1的最短距離變化為6,更新路由矩陣R(3,1) = R(3,4) = 4。
V3->V2 = 9,經由V4中轉之後V3->V4->V2 = 8, 於是V3到V1的最短距離變化為8,更新路由矩陣R(3,2) = R(3,4) = 4。
V3->V4 = 1
V4->V1 = 5
V4->V2 = 7
V4->V3 = 10
於是現在的距離矩陣和路由矩陣可以變為:
好了,到此所有點都中轉過了,任意兩點之間的最短距離就是最後距離矩陣中的資料,那麼其路徑該怎麼表示呢?路徑全部記錄在路由矩陣中了,我們只要讀取路由矩陣就可以了。
舉個例子:v4->V3
從距離矩陣中可以看出V4->V3的最短距離是D(4,3) = 10;根據其路由矩陣我們可以看出:
R(4,3) = 1,表示V4->V3,先經過V1,於是再看R(1,3) = 2,表示還需要再經過V2,於是我們看R(2,3) = 3,這個時候我們發現終於到了V3,所以我們梳理一下,V4->V3的最短路徑是:V4->V1->V2->V3。簡言之就是固定列,根據路由矩陣在行中跳轉,直到跳轉到對應的點。
所以最後我們展示出程式碼就很容易理解了:
% floyd.m
% 採用floyd演算法計算圖a中每對頂點最短路
% d是矩離矩陣
% r是路由矩陣
function [d,r]=floyd(a)
n=size(a,1);
% 初始化距離矩陣
d=a;
% 初始化路由矩陣
for i=1:n
for j=1:n
r(i,j)=j;
end
end
r;
% Floyd演算法開始
for k=1:n
for i=1:n
for j=1:n
if d(i,k)+d(k,j)<d(i,j)
d(i,j)=d(i,k)+d(k,j);
r(i,j)=r(i,k);
end
end
end
k;
d;
r;
end
d
r
最後我還寫了一個用於列印路徑的函式:
% DisplayPath.m 列印路徑函式
function DisplayPath(route, start, dest)
% 打印出任意兩點之間的最短路徑
% route : 路由表
% start : 起點index
% dest : 終點index
i = 1;
while 1
if(route(start, dest) ~= dest)
fprintf('V%s -> ', num2str(start));
start = route(start, dest);
else
fprintf('V%s -> ', num2str(start));
fprintf('V%s\n', num2str(dest));
break;
end
end
我將上面的舉例的圖使用floyd演算法進行計算,並最後打印出任意兩點之間的最短路徑:
a = [0 2 6 4;
inf 0 3 inf;
7 inf 0 1 ;
5 inf 12 0];
[d,r]=floyd(a)
disp('--------------------------')
for i = 1 : 4
for j = 1 : 4
DisplayPath(r, i, j);
end
end
執行結果為:
main
d =
0 2 5 4 9 0 3 4 6 8 0 1 5 7 10 0
r =
1 2 2 4 3 2 3 3 4 4 3 4 1 1 1 4
V1 -> V1
V1 -> V2
V1 -> V2 -> V3
V1 -> V4
V2 -> V3 -> V4 -> V1
V2 -> V2
V2 -> V3
V2 -> V3 -> V4
V3 -> V4 -> V1
V3 -> V4 -> V1 -> V2
V3 -> V3
V3 -> V4
V4 -> V1
V4 -> V1 -> V2
V4 -> V1 -> V2 -> V3
V4 -> V4
相關推薦
最短路徑-Floyd演算法的matlab實現.md
最短路徑-Floyd演算法的matlab實現 弗洛伊德演算法是解決任意兩點間的最短路徑的一種演算法,可以正確處理有向圖或有向圖或負權(但不可存在負權迴路)的最短路徑問題。 在Floyd演算法中一般有兩個矩陣,一個距離矩陣D,一個路由矩陣R,其中距離矩陣用
最短路徑—Floyd演算法
Floyd演算法: 1,從任意一條單邊路徑開始。所有兩點之間的距離是邊的權,如果兩點之間沒有邊相連,則權為無窮大。 2,對於每一對頂點 u 和 v,看看是否存在一個頂點 w 使得從 u 到 w 再到 v 比已知的路徑更短。如果是更新它。 Floyd-Warshall——
【資料結構】所有頂點對的最短路徑 Floyd演算法
所有頂點對的最短路徑問題是指:對於給定的有向圖G=(V,E),求任意一對頂點之間的最短路徑。 可以求解得到的 的遞推公式: #include <stdio.h> #include <stdlib.h> const int FINI
圖-最短路徑-Floyd演算法
給定高鐵的規劃方案,如何求任意兩點的最短路呢? 方法是Floyd演算法。 演算法思想: 1、計算從i出發,跳點為空,直接到j 的最短路。記做D[i][j]。 2、可選跳點為1時,i到j的路徑分為兩種情況: 或者不經過1, 此時前者最短為D[i][j], 或者經過1
最短路徑---Floyd演算法(C++)
Floyd演算法的介紹 演算法的特點: 弗洛伊德演算法是解決任意兩點間的最短路徑的一種演算法,可以正確處理有向圖或有向圖或負權(但不可存在負權迴路)的最短路徑問題,同時也被用於計算有向圖的傳遞閉包。 演算法的思路 通過Floyd計算圖G=(V,E)中各個頂點的最短路徑時,需要引入
多源最短路徑--Floyd演算法
#include<iostream> #include<cstdio> using namespace std; const int INF = 0x3f3f3f3f; int main(void) { int e[10][10] = { 0 }, dis[10], boo
路徑規劃(最短路徑)演算法C#實現
///<summary>/// RoutePlanner 提供圖演算法中常用的路徑規劃功能。 /// 2005.09.06 ///</summary>publicclass RoutePlanner { public RoutePlan
每一對頂點之間的最短路徑----Floyd演算法----(附完整程式碼)
1.Floyd演算法 2.輸出每兩對頂點之間的最短距離 #include<stdio.h> #include<stdlib.h> #define MaxVertexNum 100 #define INFINITY 65535 //#define MaxSize 1
最短路徑Floyd演算法具體演示
演示作品下載 最短路徑Floyd演算法具體演示 ----用VC++來實現路由選擇演算法 摘要: 確定圖的路由選擇的策略要考慮很多技術因素。其包括:選擇最短路由還是最佳路由;
最短路徑 Floyd演算法 Dijkstra演算法 Bellman-Ford(貝爾曼)演算法
相信大家應該對最短路徑演算法很感興趣吧!不感興趣也沒關係,我們一起來看看下面的例子。最短路徑應該是在眾多演算法中。最常用的一類演算法。為什麼這樣說呢?? 例如: 1.乘汽車旅行的人總希望找出到目的地的儘可能的短的行
最短路徑(Floyd演算法)
Floyd演算法又稱為弗洛伊德演算法,插點法,是一種用於尋找給定的加權圖中頂點間最短路徑的演算法。 標頭檔案:Floyd.h #ifndef FLOYD_H #define FLOYD_H #define INFINITY 65535 #define MAXVEX 2
求有向網中任意一對頂點之間的最短路徑 Floyd演算法
有向網中欲知任意一對頂點之間的最短路徑常用Floyd演算法,基本思想是任意一對頂點vi與vj,逐步在其中加入一箇中間節點v0,..,vk,...vn,若比原路徑短則更新最短路徑,經過n次比較和修正後,vi到vj的最短路徑可以求出。具體程式碼及相關注釋如下 //
最短路徑-Floyd(弗洛伊德)演算法
最短路徑-Floyd(弗洛伊德)演算法 簡介: 相較Dijkstra,Floyd是一個完全窮舉圖中每個點到末尾點的最短路徑 演算法思想: 按慣例說兩個工具 Path[MAX_SIZE][MAX_SIZE]:儲存所有的最短路徑(指向
圖-最短路徑—Dijkstra演算法和Floyd演算法
1.定義概覽 Dijkstra(迪傑斯特拉)演算法是典型的單源最短路徑演算法,用於計算一個節點到其他所有節點的最短路徑。主要特點是以起始點為中心向外層層擴充套件,直到擴充套件到終點為止。Dijkstra演算法是很有代表性的最短路徑演算法,演算法使用了廣度優先搜尋解決賦權有向圖或者無向圖的單源
結點對最短路徑Floyd弗洛伊德演算法解析
暑假,小哼準備去一些城市旅遊。有些城市之間有公路,有些城市之間則沒有,如下圖。為了節省經費以及方便計劃旅程,小哼希望在出發之前知道任意兩個城市之前的最短路程。 上圖中有4個城市8條公路,公路上的數字表示這條公路的長短。請注意這些公
資料結構與演算法——最短路徑Dijkstra演算法的C++實現
#ifndef GRAPH_H #define GRAPH_H #include <list> #include <iostream> #include <vector> #include <stdlib.h> #include <string.h>
紫書第十一章-----圖論模型與演算法(最短路徑Dijkstra演算法Bellman-Ford演算法Floyd演算法)
最短路徑演算法一之Dijkstra演算法 演算法描述:在無向圖 G=(V,E) 中,假設每條邊 E[i] 的長度為 w[i],找到由頂點 V0 到其餘各點的最短路徑。 使用條件:單源最短路徑,適用於邊權非負的情況 結合上圖具體搜尋過程,我繪出下表,方便
圖的最短路徑-Dijkstra演算法和Floyd演算法
Dijkstra演算法 單源點最短路徑問題 Dijkstra演算法主要用來解決單源點最短路徑問題。 給定帶權有向圖G=(V,E),其中每條邊的權是非負數。另外,還給定V中的一個頂點,稱為源。現在要計算從源到所有其他各頂點的最短路徑長度,這裡路徑的長度是指路徑上各邊權之和。這個問題
【原】單源最短路徑快速演算法(spfa)的python3.x實現
單源最短路徑快速演算法(spfa)的python3.x實現 0. 寫在最前面 最近比較忙呢,寫的比較少了。抽空寫了一下這篇文件,簡陋勿噴~(後面準備做個演算法包,包括基礎的資料結構和演算法,感覺任重而道遠) 1. SPFA的簡介[1] SPFA(
【資料結構】圖(最短路徑Dijkstra演算法)的JAVA程式碼實現
最短路徑的概念最短路徑的問題是比較典型的應用問題。在圖中,確定了起始點和終點之後,一般情況下都可以有很多條路徑來連線兩者。而邊或弧的權值最小的那一條路徑就稱為兩點之間的最短路徑,路徑上的第一個頂點為源點,最後一個頂點為終點。圖的最短路徑的演算法有很多,本文主要介紹狄克斯特拉(