1. 程式人生 > >Floyd演算法求最短路徑——Java

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的最短路徑的距離。

演算法描述:
  1. 從任意一條單邊路徑開始。所有兩點之間的距離是邊的權,如果兩點之間沒有邊相連,則權為無窮大,這也是所謂的初始化工作;
  2. 對於每一對頂點 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