国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

數(shù)據(jù)結(jié)構(gòu)與算法細(xì)節(jié)篇之最短路徑問(wèn)題:Dijkstra和Floyd算法詳細(xì)描述,java語(yǔ)言實(shí)現(xiàn)。

這篇具有很好參考價(jià)值的文章主要介紹了數(shù)據(jù)結(jié)構(gòu)與算法細(xì)節(jié)篇之最短路徑問(wèn)題:Dijkstra和Floyd算法詳細(xì)描述,java語(yǔ)言實(shí)現(xiàn)。。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

前言

  • 最短路徑的算法有兩個(gè),Dijkstra算法 和 Floyd算法
  • Dijkstra算法 解決的是 單源 最短路徑問(wèn)題。
  • Floyd算法解決的是 多源 最短路徑問(wèn)題,并且可以處理負(fù)權(quán)圖
  • 今天要講的就是Dijkstra算法。
  • 加:feng--Insist(大寫(xiě)的i),進(jìn)java交流群討論互聯(lián)網(wǎng)+技術(shù)。可索要PPT等資料。
  • 其他資料,建議先看本篇博客。:Dijkstra算法和Floyd算法:https://blog.csdn.net/weixin_43872728/article/details/100662957
  • 代碼位置:https://github.com/fengfanli/dataStructuresAndAlgorithm/tree/master/src/com/feng/algorithm/self_learn

一、單源最短路徑

1、單源最短路徑問(wèn)題

  • 解決的問(wèn)題: 求解單源最短路徑,即各個(gè)節(jié)點(diǎn)到達(dá)源點(diǎn)的最短路徑或權(quán)值。如下圖中
    數(shù)據(jù)結(jié)構(gòu)與算法細(xì)節(jié)篇之最短路徑問(wèn)題:Dijkstra和Floyd算法詳細(xì)描述,java語(yǔ)言實(shí)現(xiàn)。,數(shù)據(jù)結(jié)構(gòu)與算法,算法,java,開(kāi)發(fā)語(yǔ)言
    考察其他所有節(jié)點(diǎn)到源點(diǎn)的最短路徑和長(zhǎng)度
  • 局限性: 無(wú)法解決權(quán)值為負(fù)數(shù)的情況
  • 資料
    • 可先看匹配視頻:https://www.bilibili.com/video/BV1o44y1B7NM/
    • 代碼:待上傳。

2、Dijkstra 初始化

首先已知的是:
給定 鄰接矩陣表示的圖Graph、源點(diǎn)S、終點(diǎn)T。

a、參數(shù)

參數(shù):

參數(shù)名 解釋
S 記錄當(dāng)前已經(jīng)處理過(guò)的源點(diǎn)到最短節(jié)點(diǎn)
U 記錄還未處理的節(jié)點(diǎn)
dist[] 記錄各個(gè)節(jié)點(diǎn)到起始節(jié)點(diǎn)的最短權(quán)值
path[] 記錄各個(gè)節(jié)點(diǎn)的上一級(jí)節(jié)點(diǎn)(用來(lái)聯(lián)系該節(jié)點(diǎn)到起始節(jié)點(diǎn)的路徑)

b、初始化參數(shù)

  • 頂點(diǎn)集S: 節(jié)點(diǎn)A到自已的最短路徑長(zhǎng)度為0。只包含源點(diǎn),即S={A},代碼中沒(méi)有這個(gè),這里是為了步驟清晰而設(shè)置的。
  • 頂點(diǎn)集U: 包含除A外的其他頂點(diǎn). 即U={B,C,D,E,F,G}
  • dist[]: 源點(diǎn)還不能到達(dá)的節(jié)點(diǎn),其權(quán)值為∞
A B C D E F G
dist[]: 0 1 2 3 4 5 6
初始化值: 0 4 6 6

path[]: 記錄當(dāng)前節(jié)點(diǎn)的前驅(qū)節(jié)點(diǎn)下標(biāo)(源點(diǎn)還不能到達(dá)的節(jié)點(diǎn)為-1)

A B C D E F G
path[]: 0 1 2 3 4 5 6
初始化值: 0 0 0 0 -1 -1 -1

c、算法步驟

數(shù)據(jù)結(jié)構(gòu)與算法細(xì)節(jié)篇之最短路徑問(wèn)題:Dijkstra和Floyd算法詳細(xì)描述,java語(yǔ)言實(shí)現(xiàn)。,數(shù)據(jù)結(jié)構(gòu)與算法,算法,java,開(kāi)發(fā)語(yǔ)言

  1. 初始化:設(shè)定除源節(jié)點(diǎn)以外的其它所有節(jié)點(diǎn)到源節(jié)點(diǎn)的距離為INFINITE(一個(gè)很大的數(shù)),且這些節(jié)點(diǎn)都沒(méi)被處理過(guò)。如上圖所示
  2. 從源節(jié)點(diǎn)出發(fā),更新相鄰節(jié)點(diǎn)(圖中為B、C、D)到源節(jié)點(diǎn)的距離。然后在所有節(jié)點(diǎn)中選擇一個(gè)最段距離的點(diǎn)作為當(dāng)前節(jié)點(diǎn)。
  3. 標(biāo)記當(dāng)前節(jié)點(diǎn)為done(表示已經(jīng)被處理過(guò)),與步驟2類(lèi)似,更新其相鄰節(jié)點(diǎn)的距離。(這些相鄰節(jié)點(diǎn)的距離更新也叫 松弛,目的是讓它們與源節(jié)點(diǎn)的距離最小。因?yàn)槟闶窃诋?dāng)前最小距離的基礎(chǔ)上進(jìn)行更新的,由于當(dāng)前節(jié)點(diǎn)到源節(jié)點(diǎn)的距離已經(jīng)是最小的了,那么如果這些節(jié)點(diǎn)之前得到的距離比這個(gè)距離大的話(huà),我們就更新它)。
  4. 步驟3做完以后,設(shè)置這個(gè)當(dāng)前節(jié)點(diǎn)已被done,然后尋找下一個(gè)具有最小代價(jià)(cost)的點(diǎn),作為新的當(dāng)前節(jié)點(diǎn),重復(fù)步驟3.
  5. 如果最后檢測(cè)到目標(biāo)節(jié)點(diǎn)時(shí),其周?chē)械墓?jié)點(diǎn)都已被處理,那么目標(biāo)節(jié)點(diǎn)與源節(jié)點(diǎn)的距離就是最小距離了。如果想看這個(gè)最小距離所經(jīng)過(guò)的路徑,可以回溯,前提是你在步驟3里面加入了當(dāng)前節(jié)點(diǎn)的最優(yōu)路徑前驅(qū)節(jié)點(diǎn)信息。
  • 我總結(jié)了下可用如下幾句話(huà)代替:
    兩步走
    1. 從dist[]中在集合U中的選擇最小距離加入到S中,作為當(dāng)前節(jié)點(diǎn)。(最小距離:就是 當(dāng)前節(jié)點(diǎn)到源點(diǎn)的最小距離)
    2. 遍歷當(dāng)前節(jié)點(diǎn)的鄰邊節(jié)點(diǎn):更新dist[]和path[]
      • 如果經(jīng)過(guò)當(dāng)前節(jié)點(diǎn)+鄰邊權(quán)重 < 鄰邊節(jié)點(diǎn),則改變dist[]和path[],否者不改變。

3、Dijkstra 算法詳細(xì)步驟

a、第一輪算法執(zhí)行

數(shù)據(jù)結(jié)構(gòu)與算法細(xì)節(jié)篇之最短路徑問(wèn)題:Dijkstra和Floyd算法詳細(xì)描述,java語(yǔ)言實(shí)現(xiàn)。,數(shù)據(jù)結(jié)構(gòu)與算法,算法,java,開(kāi)發(fā)語(yǔ)言

  • 如上圖,因?yàn)閐ist[]中排出掉集合U中節(jié)點(diǎn),最小值是4,也就是節(jié)點(diǎn)B,所以將B納入到集合S中(圈中)。

  • 首先 在dist[]數(shù)組中并在集合U中 最小值是節(jié)點(diǎn)B,既當(dāng)前節(jié)點(diǎn),其鄰邊有C和E,所以看是否要更新C和E。

    • 節(jié)點(diǎn)C:因?yàn)?code>C的最小距離dist[1](B的最小距離)4+1(B到C的距離)=5 < dist[2](C的最小距離) = 6,所以 dist[2]=5,path[2]=1
    • 節(jié)點(diǎn)E:因?yàn)?code>E的最小距離 dist[1](B的最小距離)4+7(B到E的距離)=11 < dist[4] (E的最小距離)=無(wú)窮大,所以 dist[4]=11,path[4]=1
  • 第一輪算法兩個(gè)鄰邊節(jié)點(diǎn)C、E有改變

b、第二輪算法執(zhí)行

數(shù)據(jù)結(jié)構(gòu)與算法細(xì)節(jié)篇之最短路徑問(wèn)題:Dijkstra和Floyd算法詳細(xì)描述,java語(yǔ)言實(shí)現(xiàn)。,數(shù)據(jù)結(jié)構(gòu)與算法,算法,java,開(kāi)發(fā)語(yǔ)言

  • 如上圖,因?yàn)閐ist[]中排出掉集合U中節(jié)點(diǎn),最小值是5,也就是節(jié)點(diǎn)C,所以將C納入到集合S中(圈中)。
  • 首先在dist[]數(shù)組中并在集合U中 最小值是節(jié)點(diǎn)C,既當(dāng)前節(jié)點(diǎn),其鄰邊有E和F,所以看是否要更新E和F。
    • 節(jié)點(diǎn)E:因?yàn)?code>C的最小距離 dist[2](也就是C的最小距離)5+6(C到E的距離)=11 == dist[4](E的最小距離) = 11,所以不動(dòng)
    • 節(jié)點(diǎn)F:因?yàn)?code>F的最小距離 dist[2](也就是C的最小距離)5+4(C到F的距離)=9 < dist[5] (F的最小距離)=無(wú)窮大,所以 dist[5]=9,path[5]=2
  • 第二輪算法兩個(gè)鄰邊節(jié)點(diǎn)僅有 F有改變

c、第三輪算法執(zhí)行

數(shù)據(jù)結(jié)構(gòu)與算法細(xì)節(jié)篇之最短路徑問(wèn)題:Dijkstra和Floyd算法詳細(xì)描述,java語(yǔ)言實(shí)現(xiàn)。,數(shù)據(jù)結(jié)構(gòu)與算法,算法,java,開(kāi)發(fā)語(yǔ)言

  • 如上圖,因?yàn)閐ist[]中排出掉集合U中節(jié)點(diǎn),最小值是6,也就是節(jié)點(diǎn)D,所以將D納入到集合S中(圈中)。
  • 首先在dist[]數(shù)組中并在集合U中 最小值是節(jié)點(diǎn)D,既當(dāng)前節(jié)點(diǎn),其鄰邊有C和F,所以看是否要更新C和F。
  • 節(jié)點(diǎn)C:因?yàn)?code>C的最小距離 dist[3](也就是D的最小距離)6+2(D到C的距離)=8 > dist[2](C的最小距離) = 5 ,所以不動(dòng)
  • 節(jié)點(diǎn)F:因?yàn)?code>F的最小距離 dist[3](也就是D的最小距離)6+5(D到F的距離)=11 > dist[5] (F的最小距離)=9,所以不動(dòng)
  • 第三輪算法兩個(gè)鄰邊節(jié)點(diǎn)C、F都沒(méi)有改變

d、第四輪算法執(zhí)行

數(shù)據(jù)結(jié)構(gòu)與算法細(xì)節(jié)篇之最短路徑問(wèn)題:Dijkstra和Floyd算法詳細(xì)描述,java語(yǔ)言實(shí)現(xiàn)。,數(shù)據(jù)結(jié)構(gòu)與算法,算法,java,開(kāi)發(fā)語(yǔ)言

  • 如上圖,因?yàn)閐ist[]中排出掉集合U中節(jié)點(diǎn),最小值是9,也就是節(jié)點(diǎn)F,所以將F納入到集合S中(圈中)。
  • 首先在dist[]數(shù)組中并在集合U中 最小值是節(jié)點(diǎn)F,既當(dāng)前節(jié)點(diǎn),其鄰邊有E和G,所以看是否要更新E和G 。
  • 節(jié)點(diǎn)E:因?yàn)?code>E的最小距離 dist[5](也就是F的最小距離) 9 +1(F到E的距離)=10 < dist[4](E的最小距離) =11,所以 dist[4] = 10,path[4]=5
  • 節(jié)點(diǎn)G:因?yàn)?code>G的最小距離 dist[5](也就是F的最小距離) 9 +8(F到G的距離)=17 < dist[6](G的最小距離) =無(wú)窮大,所以 dist[6]=17,path[6]=5
  • 第四輪算法兩個(gè)鄰邊節(jié)點(diǎn)E、G都有改變

e、第五輪算法執(zhí)行

數(shù)據(jù)結(jié)構(gòu)與算法細(xì)節(jié)篇之最短路徑問(wèn)題:Dijkstra和Floyd算法詳細(xì)描述,java語(yǔ)言實(shí)現(xiàn)。,數(shù)據(jù)結(jié)構(gòu)與算法,算法,java,開(kāi)發(fā)語(yǔ)言

  • 如上圖,因?yàn)閐ist[]中排出掉集合U中節(jié)點(diǎn),最小值是9,也就是節(jié)點(diǎn)F,所以將F納入到集合S中(圈中)。
  • 首先在dist[]數(shù)組中并在集合U中 最小值是節(jié)點(diǎn)E,既當(dāng)前節(jié)點(diǎn),其鄰邊有G,所以看是否要更新G 。
  • 節(jié)點(diǎn)G:因?yàn)?code>G的最小距離 dist[4](也就是E的最小距離) 10 +6(E到G的距離)=16 < dist[6](G的最小距離) =17,所以 dist[6]=16,path[6]=4
  • 第五輪算法鄰邊 節(jié)點(diǎn)G有改變

f、第六輪算法執(zhí)行

數(shù)據(jù)結(jié)構(gòu)與算法細(xì)節(jié)篇之最短路徑問(wèn)題:Dijkstra和Floyd算法詳細(xì)描述,java語(yǔ)言實(shí)現(xiàn)。,數(shù)據(jù)結(jié)構(gòu)與算法,算法,java,開(kāi)發(fā)語(yǔ)言

  • 如上圖,因?yàn)閐ist[]中排出掉集合U中節(jié)點(diǎn),最小值是16,也就是節(jié)點(diǎn)G,所以將G納入到集合S中(圈中)。
  • 首先在dist[]數(shù)組中并在集合U中 最小值是節(jié)點(diǎn)G,既當(dāng)前節(jié)點(diǎn),其沒(méi)有鄰邊。
  • 第六輪算法鄰邊節(jié)點(diǎn)G沒(méi)有改變
  • 到此算法遍歷結(jié)束

4、java算法實(shí)現(xiàn)

給定矩陣表示的Graph結(jié)構(gòu)。輸入源點(diǎn)v0和終點(diǎn)v1。


二、多源最短路徑

1、多源最短路徑問(wèn)題

  • 上面的Dijkstra 解決的是單源最短路徑的問(wèn)題,首先要給定 開(kāi)始節(jié)點(diǎn)和終止結(jié)點(diǎn),如果換了開(kāi)始和終止節(jié)點(diǎn),那就要每次都要重新跑一次。
  • 那就引出了多源最短路徑問(wèn)題:就是執(zhí)行一次算法,求出每?jī)蓚€(gè)點(diǎn)之間的最短距離,這就是多源最短路徑算法。這個(gè)算法代碼略簡(jiǎn)單一些。
  • 思想只有一個(gè):要算兩個(gè)點(diǎn)之間的最短距離,就看有沒(méi)有第三個(gè)點(diǎn)使得

2、Floyd初始化

首先已知的是:
給定 **鄰接矩陣表示的圖Graph。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-672285.html

a、參數(shù)

參數(shù)名 解釋
A[][] 函數(shù)中的參數(shù),需要返回,存儲(chǔ)的是節(jié)點(diǎn)的前置節(jié)點(diǎn)。
path[][] 存儲(chǔ)的是每?jī)牲c(diǎn)之間的所需距離。

b、參數(shù)初始化

參數(shù)名 解釋
A[][] 就是圖的賦值,從代碼中可以看出,比較簡(jiǎn)單
path[][] 默認(rèn)都是-1.表示從A點(diǎn)到B點(diǎn)是直達(dá)的。

c、算法步驟

  1. 對(duì)于每個(gè)頂點(diǎn)v(體現(xiàn)在代碼的第一層for循環(huán)),和任意一頂點(diǎn)(i,j)(體現(xiàn)代碼的第二、三層循環(huán)),切 i!=j、v!=i、v!=j
  2. 如果A[i][j] > A[i][v] + A[]v[j],則將A[i][j] 更新為 A[i][v] + A[v][j] 的值,并且將path[i][j]改為v。

3、Floyd算法詳細(xì)步驟

4、java 算法實(shí)現(xiàn)

package com.feng.algorithm.self_learn.floyd.floyd1;

/**
 * 學(xué)習(xí)視頻:https://www.bilibili.com/video/BV1LE411R7CS
 */
public class FloydAlgorithm {
    public static void main(String[] args) {
        int[][] graph = new int[4][4];
        int N = Short.MAX_VALUE;
        graph[0] = new int[]{0, 5, N, 7};
        graph[1] = new int[]{N, 0, 4, 2};
        graph[2] = new int[]{3, 3, 0, 2};
        graph[3] = new int[]{N, N, 1, 0};

        int[][] path = new int[4][4];
        int[][] A = Floyd.floyd(graph, path);
        int u = 1;
        int v = 0;
        Floyd.printPath(u, v, path);
        System.out.println();
        System.out.println(u + "->" + v +" shortest path is :" + A[u][v]);
    }
}
class Floyd {

    /**
     * 佛洛依德算法,給定鄰接矩陣表示的圖,
     * path[][]:存放路徑中間的節(jié)點(diǎn),如果是-1就是直達(dá)
     * A[][]:存放任意兩個(gè)節(jié)點(diǎn)之間的距離
     * 舉例:從1-0,從A得出距離是6,從path得出 1-3-2-0
     * @param graph
     * @param path
     */
    static int[][] floyd(int[][] graph, int[][] path) {
        int n = graph.length;
        int v, i, j;
        int[][] A = new int[n][n];
        for (i = 0; i < n; i++) {
            for (j = 0; j < n; j++) {
                A[i][j] = graph[i][j];
                path[i][j] = -1;
            }
        }

        for (v = 0; v < n; v++) {
            for (i = 0; i < n; i++) {
                for (j = 0; j < n; j++) {
                    if (A[i][j] > A[i][v] + A[v][j]) {
                        A[i][j] = A[i][v] + A[v][j];
                        path[i][j] = v;
                    }
                }
            }
        }
        return A;
    }

    /**
     * 遞歸打印路徑
     * @param u
     * @param v
     * @param path
     */
    static void printPath(int u, int v, int[][] path) {
        if (path[u][v] == -1) { // 如果等于 -1 。說(shuō)明就是直達(dá)的
            System.out.printf(u + "->" + v + " ");
        } else {
            int mid = path[u][v];
            printPath(u, mid, path);
            printPath(mid, v, path);
        }
    }
}


到了這里,關(guān)于數(shù)據(jù)結(jié)構(gòu)與算法細(xì)節(jié)篇之最短路徑問(wèn)題:Dijkstra和Floyd算法詳細(xì)描述,java語(yǔ)言實(shí)現(xiàn)。的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶(hù)投稿,該文觀(guān)點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包