国产精品久久久aaaa,日日干夜夜操天天插,亚洲乱熟女香蕉一区二区三区少妇,99精品国产高清一区二区三区,国产成人精品一区二区色戒,久久久国产精品成人免费,亚洲精品毛片久久久久,99久久婷婷国产综合精品电影,国产一区二区三区任你鲁

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Floyd如何求圖的最短路徑

算法與數據結構 ? 來源:bigsai ? 作者:大賽 ? 2021-10-09 14:38 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

前言

圖論中,在尋路最短路徑中除了Dijkstra算法以外,還有Floyd算法也是非常經典,然而兩種算法還是有區別的,Floyd主要計算多源最短路徑

在單源正權值最短路徑,我們會用Dijkstra算法來求最短路徑,并且算法的思想很簡單—貪心算法:每次確定最短路徑的一個點然后維護(更新)這個點周圍點的距離加入預選隊列,等待下一次的拋出確定。雖然思想很簡單,實現起來是非常復雜的,我們需要鄰接矩陣(表)儲存長度,需要優先隊列(或者每次都比較)維護一個預選點的集合。還要用一個boolean數組標記是否已經確定、還要……

總之,Dijkstra算法的思想上是很容易接受的,但是實現上其實是非常麻煩的。但是單源最短路徑解算暫時還沒有有效的辦法,復雜度也為O(n2)

而在n點圖中想求多源最短路徑,如果從Dijkstra算法的角度上,需要將Dijkstra執行n次才能獲得所有點之間的最短路徑,不過執行n次Dijkstra算法即可,復雜度為O(n3)。但是這樣感覺很臃腫,代碼量巨大,占用很多空間內存。有沒有啥方法能夠稍微變變口味呢?

答案是有的,今天就帶大家一起了解一下牛逼轟轟的Floyed算法。

算法介紹

什么是Floyed算法?

Floyd算法又稱為插點法,是一種利用動態規劃的思想尋找給定的加權圖中多源點之間最短路徑的算法,與Dijkstra算法類似。該算法名稱以創始人之一、1978年圖靈獎獲得者、斯坦福大學計算機科學系教授羅伯特·弗洛伊德命名。

簡單的來說,算法的主要思想是動態規劃(dp),而求最短路徑需要不斷松弛(熟悉spfa算法的可能熟悉松弛)。

而算法的具體思想為:

1 .鄰接矩陣(二維數組)dist儲存路徑,數組中的值開始表示點點之間初始直接路徑,最終是點點之間的最小路徑,有兩點需要注意的,第一是如果沒有直接相連的兩點那么默認為一個很大的值(不要因為計算溢出成負數),第二是自己和自己的距離要為0。

2 .從第1個到第n個點依次加入松弛計算,每個點加入進行試探枚舉是否有路徑長度被更改(自己能否更新路徑)。順序加入(k枚舉)松弛的點時候,需要遍歷圖中每一個點對(i,j雙重循環),判斷每一個點對距離是否因為加入的點而發生最小距離變化,如果發生改變(變小),那么兩點(i,j)距離就更改。

2 .重復上述直到最后插點試探完成。

其中第2步的狀態轉移方程為:

dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j])

其中dp[a][b]的意思可以理解為點a到點b的最短路徑,所以dp[i][k]的意思可以理解為i到k的最短路徑dp[k][j]的意思為k到j的最短路徑.

咱們圖解一個案例,初始情況每個點只知道和自己直接相連的點的距離,而其他間接相連的點還不知道距離,比如A-B=2,A-C=3但是B-C在不經過計算的情況是不知道長度的。

03956320-21de-11ec-82a8-dac502259ad0.png

加入第一個節點A進行更新計算,大家可以發現,由于A的加入,使得本來不連通的B,C點對和B,D點對變得聯通,并且加入A后距離為當前最小,同時你可以發現加入A其中也使得C-D多一條聯通路徑(6+3),但是C-D聯通的話距離為9遠遠大于本來的(C,D)聯通路徑2,所以這條不進行更新。

03fc0972-21de-11ec-82a8-dac502259ad0.png

咱們繼續加入第二個節點B,這個點執行和前面A相同操作進行。對一些點進行更新。因為和B相連的點比較多,可以產生很多新的路徑,這里給大家列舉一下并做一個說明,這里新路徑我統一用1表示,原來長度用0表示。

AF1=AB+BF=6+2=8 < AF0(∞) 進行更新

AE1=AB+BE=2+4=6 < AE0(∞) 進行更新

CE1=CB+BE=5+5=9 < CE0(∞) 進行更新

CF1=CB+BF=5+6=11

EF1=EB+BF=4+6=10

當然,也有一些新的路徑大于已有路徑不進行更新,例如:

AC1=AB+BC=2+5=7>AC0(3)不更新

AD1=AB+BD=2+8=10>AD0(6)不更新

……

更多路徑這里就不一一列舉了。

04156728-21de-11ec-82a8-dac502259ad0.png

后序加入C、D、E、F都是進行相同的操作,最終全部加完沒有路徑可以更新就結束停止。實際上這個時候圖中的連線就比較多了。這些連線都是代表當前的最短路徑。這也和我們的需求貼合,我們最終要的是所有節點的最短路徑。每個節點最終都應該有5條指向不同節點的邊!矩陣對應邊值就是點點之間最短路徑。

至于算法的模擬兩部核心已經告訴大家了,大家可以自行模擬剩下的。

程序實現

而對于程序而言,這個插入的過程相當簡單。核心代碼只有四行!這個寫法適合有向圖和無向圖,無向圖的算法優化后面會說。
代碼如下

publicclassfloyd{
staticintmax=66666;//別Intege.max兩個相加越界為負
publicstaticvoidmain(String[]args){
intdist[][]={
{0,2,3,6,max,max},
{2,0,max,max,4,6},
{3,max,0,2,max,max},
{6,max,2,0,1,3},
{max,4,max,1,0,max},
{max,6,max,3,max,0}};//地圖
//6個
for(intk=0;k6;k++)//加入第k個節點進行計算
{
for(inti=0;i6;i++)//每加入一個點都要枚舉圖看看有沒有可以被更新的
{
for(intj=0;j6;j++)
{
dist[i][j]=Math.min(dist[i][j],dist[i][k]+dist[k][j]);
}
}
}
//輸出
for(inti=0;i6;i++){
System.out.print("節點"+(i+1)+"的最短路徑");
for(intj=0;j6;j++){
System.out.print(dist[i][j]+"");
}
System.out.println();
}
}
}

執行結果為:

046ca16e-21de-11ec-82a8-dac502259ad0.png

可以自行計算,圖和上篇的Dijkstra用的圖是一致的,大家可以自行比對,結果一致,說明咱么的結果成功的。

當然,在你學習的過程中,可以在每加入一個節點插入完成后,打印鄰接矩陣的結果,看看前兩部和筆者的是否相同(有助于理解),如果相同,則說明正確!

對于加入點更新你可能還是有點疑惑其中的過程,那咱么就用一個局部來演示一下幫助你進一步理解Floyd算法,看其中AB最短距離變化情況祝你理解:

048f261c-21de-11ec-82a8-dac502259ad0.png

小試牛刀

自己會沒會?刷一道題就可以知道了,剛好力扣1334是一道Floyd算法解決的問題。

題目描述為

有 n 個城市,按從 0 到 n-1 編號。給你一個邊數組 edges,其中 edges[i] = [fromi, toi, weighti] 代表 fromi 和 toi 兩個城市之間的雙向加權邊,距離閾值是一個整數 distanceThreshold。

返回能通過某些路徑到達其他城市數目最少、且路徑距離 最大 為 distanceThreshold 的城市。如果有多個這樣的城市,則返回編號最大的城市。

注意,連接城市 i 和 j 的路徑的距離等于沿該路徑的所有邊的權重之和。

示例1:

04f14626-21de-11ec-82a8-dac502259ad0.png

輸入:n = 4, edges = [[0,1,3],[1,2,1],[1,3,4],[2,3,1]], distanceThreshold = 4
輸出:3
解釋:城市分布圖如上。
每個城市閾值距離 distanceThreshold = 4 內的鄰居城市分別是:
城市 0 -> [城市 1, 城市 2]
城市 1 -> [城市 0, 城市 2, 城市 3]
城市 2 -> [城市 0, 城市 1, 城市 3]
城市 3 -> [城市 1, 城市 2]
城市 0 和 3 在閾值距離 4 以內都有 2 個鄰居城市,但是我們必須返回城市 3,因為它的編號最大。

示例2:

050456d0-21de-11ec-82a8-dac502259ad0.png

輸入:n = 5, edges = [[0,1,2],[0,4,8],[1,2,3],[1,4,2],[2,3,1],[3,4,1]], distanceThreshold = 2
輸出:0
解釋:城市分布圖如上。
每個城市閾值距離 distanceThreshold = 2 內的鄰居城市分別是:
城市 0 -> [城市 1]
城市 1 -> [城市 0, 城市 4]
城市 2 -> [城市 3, 城市 4]
城市 3 -> [城市 2, 城市 4]
城市 4 -> [城市 1, 城市 2, 城市 3]
城市 0 在閾值距離 2 以內只有 1 個鄰居城市。

提示:

2 <= n <= 100
1 <= edges.length <= n * (n - 1) / 2
edges[i].length == 3
0 <= fromi < toi < n
1 <= weighti, distanceThreshold <= 10^4
所有 (fromi, toi) 都是不同的。

思路分析:

拿到一道題,首先就是要理解題意,而這道題的意思借助案例也是非常能夠理解,其實就是判斷在distanceThreshold范圍內找到能夠到達的最少點的編號,如果多個取最大即可。正常求到達最多情景比較多這里求的是最少的,但是思路都是一樣的。

這道題如果使用搜索,那復雜度就太高了啊,很明顯要使用多源最短路徑Floyd算法,具體思路為;

1 .先使用Floyd算法求出點點之間的最短距離,時間復雜度O(n3)

2 . 統計每個點與其他點距離在distanceThreshold之內的點數量,統計的同時看看是不是小于等于已知最少個數的,如果是,那么保存更新。

3 .返回最終的結果。

實現代碼:

classSolution{
publicintfindTheCity(intn,int[][]edges,intdistanceThreshold){
intdist[][]=newint[n][n];
for(inti=0;ifor(intj=0;j//保證數據比最大二倍大(兩相加不能比它大),并且不能溢出,不要Int最大相加為負會出錯
dist[i][j]=1000000;
}
dist[i][i]=0;
}
for(intarr[]:edges){
dist[arr[0]][arr[1]]=arr[2];
dist[arr[1]][arr[0]]=arr[2];
}
for(intk=0;kfor(inti=0;ifor(intj=0;jintmin=Integer.MAX_VALUE;
intminIndex=0;
intpathNum[]=newint[n];//存儲距離
for(inti=0;ifor(intj=0;jif(dist[i][j]<=distanceThreshold){
????????????????????pathNum[i]++;
????????????????}
????????????}
????????????if(pathNum[i]<=min)?{
????????????????min?=?pathNum[i];
????????????????minIndex=i;
????????????}
????????}
????????returnminIndex;

}
}

那么想一下優化空間:Floyd算法還有優化空間嘛?

有的,這個是個無向圖,也就是加入點的時候枚舉其實會有一個重復的操作過程(例如枚舉AC和CA是效果一致的),所以我們在Floyd算法的實現過程中過濾掉重復的操作,具體代碼為:

classSolution{
publicintfindTheCity(intn,int[][]edges,intdistanceThreshold){
intdist[][]=newint[n][n];//存儲距離
for(inti=0;ifor(intj=0;j1000000;
}
dist[i][i]=0;
}
for(intarr[]:edges){
dist[arr[0]][arr[1]]=arr[2];
dist[arr[1]][arr[0]]=arr[2];
}
for(intk=0;kfor(inti=0;ifor(intj=i+1;j//去掉重復的計算
dist[i][j]=Math.min(dist[i][j],dist[i][k]+dist[k][j]);
dist[j][i]=dist[i][j];
}
}
}
intmin=Integer.MAX_VALUE;
intminIndex=0;
intpathNum[]=newint[n];//
for(inti=0;ifor(intj=0;jif(dist[i][j]<=distanceThreshold){
????????????????????pathNum[i]++;
????????????????}
????????????}
????????????if(pathNum[i]<=min)?{
????????????????min?=?pathNum[i];
????????????????minIndex=i;
????????????}
????????}
????????returnminIndex;

}
}

尾聲

對于Floyd算法,如果初次接觸不一定能夠理解這個松弛的過程。

Floyd像什么呢,最終最短路徑大部分都是通過計算得到而存儲下來直接使用的,我覺得它和MySQL視圖有點像的,視圖是一個虛表在實表上計算獲得的,但是計算之后各個數據就可以直接使用,Floyd是在原本的路徑圖中通過一個動態規劃的策略計算出來點點之間的最短路徑。

FloydDijkstra是經典的最短路徑算法,兩者有相似也有不同。在復雜度上,Dijkstra算法時間復雜度是O(n2),Floyd算法時間復雜度是O(n3);在功能上,Dijkstra是求單源最短路徑,并且路徑權值不能為負,而Floyd是求多源最短路徑,可以有負權值;算法實現上,Dijkstra 是一種貪心算法實現起來較復雜,Floyd基于動態規劃實現簡單;兩個作者DijkstraFloyd都是牛逼轟轟的大人物,都是圖靈獎的獲得者。

除了Floyd算法,堆排序算法heapSort也是Floyd大佬發明的,屬實佩服!

Floyd算法,俗稱插點法,不就一個點一個點插進去更新用到被插點距離嘛!

好啦,Floyd算法就介紹到這里,如果對你有幫助,請動動小手點個贊吧!蟹蟹。

編輯:jq
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 代碼
    +關注

    關注

    30

    文章

    4968

    瀏覽量

    73974
  • Floyd
    +關注

    關注

    0

    文章

    2

    瀏覽量

    1039

原文標題:Floyd是咋求圖的最短路徑?

文章出處:【微信號:TheAlgorithm,微信公眾號:算法與數據結構】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    pcba板短路怎么快速檢出原因

    (焊錫橋接、殘留助焊劑)、大電流路徑(電源模塊、濾波電容、功率電感周圍燒焦痕跡)、高密度區域(BGA封裝、細間距器件下方焊接不良)。 典型案例 :電容極性反接導致短路時,目視可發現電容爆裂痕跡。 萬用表通斷測試 正常阻抗 :電源對地阻抗
    的頭像 發表于 03-05 11:09 ?113次閱讀

    從設計階段排查預防PCB短路

    在PCB設計與制造領域中,短路故障無疑是工程師和制造商最頭疼的“頭號殺手”。然而PCB設計導致的短路究竟如何產生?短路是否能在設計階段被檢測出來?設計時如何系統性預防?本文告訴你答案。 一、探本
    發表于 01-23 13:55

    單片機Io口檢測到高電平的最短時間是多少?

    請教一下大神單片機Io口檢測到高電平的最短時間是多少?
    發表于 01-14 08:20

    西格電力直供微電網設計③:短路電流計算與設備選型實例

    在直供微電網設計中,短路電流計算與設備選型是決定系統 “安全運行” 與 “成本可控” 的關鍵環節 。本文結合某 10kV 園區直供微電網實例,從理論建模、實例計算、設備選型到工程落地避坑,完整拆解實操路徑
    的頭像 發表于 10-23 11:31 ?1394次閱讀
    西格電力直供微電網設計③:<b class='flag-5'>短路</b>電流計算與設備選型實例

    AI百舸爭流時代,華為如何幫助行業破浪前行?

    基于ACT三步走,華為幫助企業找到實現智能化的最短路徑
    的頭像 發表于 09-29 17:06 ?749次閱讀
    AI百舸爭流時代,華為如何幫助行業破浪前行?

    單模光纖最短傳輸距離是多少米

    單模光纖的最短傳輸距離通常為2.0米,這一距離的設定主要基于光波信號在傳輸過程中的物理特性,具體原因如下: 光波折射與干擾:光纖模塊在傳輸光信號時,無法完全接收所有光波,部分光波會折射回傳。這些回傳
    的頭像 發表于 09-29 09:53 ?871次閱讀

    光纜會短路

    光纜不會短路,其工作原理和結構特性決定了它與傳統電纜在短路問題上的本質區別。以下是具體分析: 1. 光纜的傳輸介質是光,而非電 傳統電纜:通過金屬導線(如銅、鋁)傳輸電信號,電流在導體中流動。若導體
    的頭像 發表于 08-13 10:50 ?713次閱讀
    光纜會<b class='flag-5'>短路</b>嗎

    IGBT短路振蕩的機制分析

    絕緣柵雙極型晶體管(IGBT)在電機驅動和電器控制等多種工業領域中廣泛應用。IGBT在具有更低的開關損耗的同時,還要同時具備一定的抗短路能力。短路時,如果發生短路振蕩(SCOs)現象,IGBT的抗
    的頭像 發表于 08-07 17:09 ?3842次閱讀
    IGBT<b class='flag-5'>短路</b>振蕩的機制分析

    IGBT元件的短路和過電壓保護

    沒有附加保護裝置的 10μs 短路 SOA 操作。
    的頭像 發表于 07-23 14:49 ?3746次閱讀
    IGBT元件的<b class='flag-5'>短路</b>和過電壓保護

    從焊接到設計:PCBA短路全鏈路解決方案

    一站式 PCBA加工 廠家今天為大家講講PCBA生產中的短路現象常見原因有哪些?排除PCBA生產中短路現象的方法和步驟。PCBA生產過程中,短路是常見卻又令人頭疼的問題。一旦發生短路
    的頭像 發表于 07-11 09:35 ?2532次閱讀

    關于電動機“相間短路”與“對地短路”的問題

    電動機作為現代工業的核心動力設備,其運行穩定性直接關系到生產效率和設備安全。在電機故障中,“相間短路”和“對地短路”是最常見的兩類電氣故障,其成因復雜且危害性大。本文將深入分析這兩種短路現象的機理
    的頭像 發表于 07-01 11:08 ?4113次閱讀

    液晶像素短路防護模組及液晶線路激光修復

    引言 在液晶顯示技術中,液晶像素短路問題嚴重影響顯示質量與產品良率。為解決這一難題,液晶像素短路防護模組應運而生,同時液晶線路激光修復技術也成為修復短路等缺陷的關鍵手段,二者對提升液晶顯示產品
    的頭像 發表于 05-15 09:32 ?697次閱讀
    液晶像素<b class='flag-5'>短路</b>防護模組及液晶線路激光修復

    貼片電容短路的原因探析

    貼片電容作為現代電子設備中不可或缺的元件,廣泛應用于各類電路中,發揮著濾波、儲能、耦合和去耦等關鍵作用。然而,在使用過程中,貼片電容有時會出現短路故障,這不僅會影響電路的正常工作,甚至可能導致整個
    的頭像 發表于 03-19 15:28 ?3376次閱讀
    貼片電容<b class='flag-5'>短路</b>的原因探析

    何時選擇OSPF作為路由協議

    在構建網絡時,選擇合適的路由協議對于確保網絡的高效性和穩定性至關重要。OSPF(開放最短路徑優先)是一種廣泛使用的內部網關協議,特別適合于大型、復雜或多路徑的網絡環境。本文將探討何時選擇OSPF作為路由協議,并分析其優勢和其他路由協議的對比。
    的頭像 發表于 03-18 09:14 ?1086次閱讀
    何時選擇OSPF作為路由協議

    短路保護和過載保護有什么區別?

    短路保護和過載保護是電氣系統中兩種重要的保護措施,它們在確保設備安全、穩定運行方面起著至關重要的作用。盡管兩者都涉及到電流的異常增大,但它們的工作原理、應用場景以及實現方式存在顯著的差異。本文將從
    的頭像 發表于 03-10 12:07 ?4837次閱讀