Floyd演算法求最短路徑——Java
前面講述了利用貪心演算法求解最短路徑的兩種演算法,分別是BFS以及Dijkstra演算法。接下來要介紹的這種是一種動態規劃的演算法——弗洛伊德演算法。
用通俗的語言來描述的話,首先我們的目標是尋找從點i到點j的最短路徑。從動態規劃的角度看問題,我們需要為這個目標重新做一個詮釋。從任意節點i到任意節點j的最短路徑不外乎2種可能,1是直接從i到j,2是從i經過若干個節點k到j。所以,我們假設Dis(i,j)為節點u到節點v的最短路徑的距離,對於每一個節點k,我們檢查Dis(i,k) + Dis(k,j) < Dis(i,j)是否成立,如果成立,證明從i到k再到j的路徑比i直接到j的路徑短,我們便設定Dis(i,j) = Dis(i,k) + Dis(k,j),這樣一來,當我們遍歷完所有節點k,Dis(i,j)中記錄的便是i到j的最短路徑的距離。
演算法描述:
- 從任意一條單邊路徑開始。所有兩點之間的距離是邊的權,如果兩點之間沒有邊相連,則權為無窮大,這也是所謂的初始化工作;
- 對於每一對頂點 u 和 v,看看是否存在一個頂點 w 使得從 u 到 w 再到 v 比己知的路徑更短。如果是更新它。
以下圖為例,對Floyd 演算法進行演示。
首先是演算法的初始狀態:矩陣S是記錄各個頂點間最短路徑的矩陣。
第1步:
初始化S。矩陣S中頂點a[i][j]的距離為頂點i到頂點j的權值;如果i和j不相鄰,則a[i][j]=∞。實際上,就是將圖的原始矩陣複製到S中。
注:a[i][j]表示矩陣S中頂點i(第i個頂點)到頂點j(第j個頂點)的距離。
第2步:
以頂點A(第1個頂點)為中介點,若a[i][j] > a[i][0]+a[0][j],則設定a[i][j]=a[i][0]+a[0][j]。
以頂點a[1][6],上一步操作之後,a[1][6]=∞;而將A作為中介點時,(B,A)=12,(A,G)=14,因此B和G之間的距離可以更新為26。
同理,依次將頂點B,C,D,E,F,G作為中介點,並更新a[i][j]的大小。
下面我們給出實現的程式碼:
public class MatrixUDG {
private int mEdgNum; // 邊的數量
private char[] mVexs; // 頂點集合
private int[][] mMatrix; // 鄰接矩陣
private static final int INF = Integer.MAX_VALUE; // 最大值
...//省略部分程式碼
/**
* floyd最短路徑。
* 即,統計圖中各個頂點間的最短路徑。
* 引數說明:
* path -- 路徑。path[i][j]=k表示,"頂點i"到"頂點j"的最短路徑會經過頂點k。
* dist -- 長度陣列。即,dist[i][j]=sum表示,"頂點i"到"頂點j"的最短路徑的長度是sum。
*/
public void floyd(int[][] path, int[][] dist) {
// 初始化
for (int i = 0; i < mVexs.length; i++) {
for (int j = 0; j < mVexs.length; j++) {
dist[i][j] = mMatrix[i][j]; // "頂點i"到"頂點j"的路徑長度為"i到j的權值"。
path[i][j] = j; // "頂點i"到"頂點j"的最短路徑是經過頂點j。
}
}
// 計算最短路徑
for (int k = 0; k < mVexs.length; k++) {
for (int i = 0; i < mVexs.length; i++) {
for (int j = 0; j < mVexs.length; j++) {
// 如果經過下標為k頂點路徑比原兩點間路徑更短,則更新dist[i][j]和path[i][j]
int tmp = (dist[i][k]==INF || dist[k][j]==INF) ? INF : (dist[i][k] + dist[k][j]);
if (dist[i][j] > tmp) {
// "i到j最短路徑"對應的值設,為更小的一個(即經過k)
dist[i][j] = tmp;
// "i到j最短路徑"對應的路徑,經過k
path[i][j] = path[i][k];
}
}
}
}
// 列印floyd最短路徑的結果
System.out.printf("floyd: \n");
for (int i = 0; i < mVexs.length; i++) {
for (int j = 0; j < mVexs.length; j++)
System.out.printf("%2d ", dist[i][j]);
System.out.printf("\n");
}
}
}
下面分別給出“鄰接矩陣圖“和“鄰接表圖”的弗洛伊德原始碼。
相關推薦
Floyd演算法求最短路徑——Java
前面講述了利用貪心演算法求解最短路徑的兩種演算法,分別是BFS以及Dijkstra演算法。接下來要介紹的這種是一種動態規劃的演算法——弗洛伊德演算法。 用通俗的語言來描述的話,首先我們的目標是尋找從點i到點j的最短路徑。從動態規劃的角度看問題,我們需要為這個目
Dijkstra演算法求最短路徑(java)
任務描述:在一個無向圖中,獲取起始節點到所有其他節點的最短路徑描述 Dijkstra(迪傑斯特拉)演算法是典型的最短路徑路由演算法,用於計算一個節點到其他所有節點的最短路徑。主要特點是以起始點為中心向外層層擴充套件,直到擴充套件到終點為止。 Dijkstra一般的表述通常有
Floyd演算法求最短路徑(附程式碼例項)
Floyd演算法 使用範圍: 1)求每對頂點的最短路徑; 2)有向圖、無向圖和混合圖; 演算法思想: 直接在圖的帶權鄰接矩陣中用插入頂點的方法依次遞推地構造出n個矩陣D(1), D(2), …, D(n), D(n)是圖的距離矩陣, 同時引入一個後繼
資料結構學習之弗洛伊德floyd演算法求最短路徑
#include "stdio.h" #include "stdlib.h" #define MAX 20 #define INFINITY 9999 typedef bool PathMatrix[MAX+1][MAX+1][MAX+1]; typedef int Di
pku openjudge 我愛北大 floyd演算法求最短路徑
總時間限制: 1000ms 記憶體限制: 65535kB描述 “紅樓飛雪,一時英傑……”耳邊傳來了那熟悉的歌聲。而這,只怕是我最後一次聽到這個聲音了。 想當年,我們曾經懷著豪情壯志,許下心願,走過靜園,走過一體,走過未名湖畔的每個角落。 想當年,我們也曾慷慨高歌,瞻仰民主與科學,瞻仰博雅塔頂,那百年之前的遺
Floyd 演算法(最短路徑)
基本思想: 1,從任意一條單邊路徑開始。所有兩點之間的距離是邊的權,如果兩點之間沒有邊相連,則權為無窮大。 2,對於每一對頂點 u 和 v,看看是否存在一個頂點 w 使得從 u 到 w 再到 v 比已知的路徑更短。如果是更新它。 時間複雜度:O() 參考:弗洛伊德(Flo
Dijkstra演算法求最短路徑問題完整C程式碼
<pre name="code" class="cpp">/* Dijkstra演算法求圖的最短路徑問題C程式碼 */ #include <stdio.h> #include <string.h> #include <stdlib.h> #define Ma
floyd演算法求解最短路徑
轉自 http://blog.csdn.net/zhongkeli/article/details/8832946 這個演算法主要要弄懂三個迴圈的順序關係。 弗洛伊德(Floyd)演算法過程: 1、用D[v][w]記錄每一對頂點的最短距離。 2、依次掃描每一個點
迪傑斯特拉演算法求最短路徑 C++程式碼實現
#include<iostream> #include<string> using namespace std; /*鄰接矩陣的型別定義*/ #define MAX 10000000 #define MAX_VERTEX_NUM 20 typedef
貪心演算法 迪傑斯特拉演算法求最短路徑
之前我們學習過弗洛伊德演算法求最短路徑,但是使用了三重迴圈,導致時間複雜度是O(n^3),而迪傑斯特拉演算法應該是求最短路徑的最好的演算法了。 迪傑斯特拉演算法原理 迪傑斯特拉演算法實際上是使用貪心演算法和bfs來求最短問題的,它的核心思想是,按照頂點來迭代
Floyd-演算法的最短路徑儲存問題
Floyd 演算法思想和編寫程式碼都比較簡單,不重複,只是我在理解 Floyd 如何儲存找到的各個點之間的最短路勁時候理解了較久時間,做個筆記。 Floyd 演算法模板如下: void floyd(int n, int **map, int **dis ){// n 為節
dijkstra演算法求最短路徑
希望大家能看完prim演算法後再來看這個演算法,因為兩者思路差不多。 先來看一下自定義的結構體 typedef char VexType; typedef int AdjType; typedef struct{ int n; VexTy
隨機生成圖,dijkstra演算法求最短路徑,深度、廣度優先歷遍【待更新其他演算法】
graph_node.h (鄰接連結串列節點類):#pragma once #include "pre_definition.h" //代表邊的節點 class graph_node { int serial_num; int weight;//每條邊的權值 publi
(Java資料結構和演算法)最短路徑---Dijkstra+Floyd
參考博文 Floyd演算法和Dijkstra演算法都不能針對帶有負權邊的圖,否則一直走負權邊,沒有最小,只有更小!! Floyd演算法 import java.util.Scanner; //Floyd演算法 class Graph{ public int[][] ad
FLoyd演算法(求最短路徑)
【程式】#include <stdio.h> #define N 105 void Floyd(int D[][N],int n)//Floyd演算法 { int i,j,k; pri
圖中求最短路徑的演算法
在許多應用領域,帶權圖都被用來描述某個網路,比如通訊網路、交通網路等。這種情況下,各邊的權重就對應於兩點之間通訊的成本或交通費用。 此時,一類典型的問題就是:在任意指定的兩點之間如果存在通路,那麼最小的消耗是多少。這類問題實際上就是帶權圖中兩點之間最短
資料結構-基於鄰接矩陣實現圖的遍歷視覺化及使用Floyd、Dijkstra演算法求解最短路徑(JavaScript實現)
使用 JavaScript 基於鄰接矩陣實現了圖的深度、廣度遍歷,以及 Floyd、Dijkstra 演算法求解最短路徑。另外使用 SVG 實現圖的遍歷視覺化。一、輸入首先,輸入資料主要有兩個,一個是存放節點名的陣列,另一個是存放邊物件的陣列。例如://存放圖結點的陣列 va
Floyd演算法與Dijkstra演算法(最短路徑)
#include <iostream> #include <cstdio> #include <vector> using namespace std; int Dis[101]; bool mark[101]; struct E { int next; i
紫書第十一章-----圖論模型與演算法(最短路徑Dijkstra演算法Bellman-Ford演算法Floyd演算法)
最短路徑演算法一之Dijkstra演算法 演算法描述:在無向圖 G=(V,E) 中,假設每條邊 E[i] 的長度為 w[i],找到由頂點 V0 到其餘各點的最短路徑。 使用條件:單源最短路徑,適用於邊權非負的情況 結合上圖具體搜尋過程,我繪出下表,方便
C++ 求最短路徑問題之Dijkstra演算法(一)
求最短路徑之Dijkstra演算法 Dijkstra演算法是用來求單源最短路徑問題,即給定圖G和起點s,通過演算法得到s到達其他每個頂點的最短距離。 基本思想:對圖G(V,E)設定集合S,存放已被訪問的頂點,然後每次從集合V-S中選擇與起點s的最短距離最小的一個頂點(記為u