1. 程式人生 > >最短路徑-Floyd演算法的matlab實現.md

最短路徑-Floyd演算法的matlab實現.md

最短路徑-Floyd演算法的matlab實現

​ 弗洛伊德演算法是解決任意兩點間的最短路徑的一種演算法,可以正確處理有向圖或有向圖或負權(但不可存在負權迴路)的最短路徑問題。

​ 在Floyd演算法中一般有兩個矩陣,一個距離矩陣D,一個路由矩陣R,其中距離矩陣用於儲存任意兩點之間的最短距離,而路由矩陣則記錄任意兩點之間的最短路徑資訊。

其思想是:如果可以從一個點進行中轉,就進行比較從這個點中轉和不中轉的距離,儲存距離小的情況,並更新距離矩陣和路由矩陣

從演算法思想中我們可以大概推斷我們要遍歷n箇中轉點,在每個中轉點進行操作的時候,需要對任意兩點之間 的距離進行遍歷。那麼演算法就應該有三重迴圈,第一重迴圈是遍歷中轉點,第二重和第三重迴圈是遍歷任意兩個點之間的距離。假設中轉節點為K,那麼節點i與j之間的最小距離怎麼更新呢?
D

(i,K)+D(K,j)<D(i,j) D(i,K)+D(K,j) < D(i,j)

其中D(i,K)+D(K,j)表示i到j從K中轉的距離,D(i,j)表示從i到j的最短距離,如果前者比後者小,那麼就D(i,j)進行更新:D(i,j)=D(i,K)+D(K,j)D(i,j) = D(i,K)+D(K,j),這樣就更新了距離矩陣。怎麼記錄這條最短路徑呢,這個時候就需要更新我們的路由矩陣:R(i,j)=R(i,K)R(i,j) = R(i,K)

路由矩陣很好理解,比如最開始是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程式碼實現

最短路徑的概念最短路徑的問題是比較典型的應用問題。在圖中,確定了起始點和終點之後,一般情況下都可以有很多條路徑來連線兩者。而邊或弧的權值最小的那一條路徑就稱為兩點之間的最短路徑,路徑上的第一個頂點為源點,最後一個頂點為終點。圖的最短路徑的演算法有很多,本文主要介紹狄克斯特拉(