图-最短路径
? ??最短路徑:對(duì)于網(wǎng)圖來(lái)說(shuō),最短路徑是指兩個(gè)頂點(diǎn)之間經(jīng)過(guò)的邊上權(quán)值之和最少的路徑,并且我們稱路徑上的第一個(gè)頂點(diǎn)式源點(diǎn),最后一個(gè)頂點(diǎn)是終點(diǎn)。以下圖為例,
? ???尋找v0到v8的最短距離。
?
? ?對(duì)應(yīng)解決思路:現(xiàn)在比較成熟的有Dijkstra(迪杰斯特拉)算法和Flord算法算法。
??Dijkstra(迪杰斯特拉)算法
? ? ?Dijkstra求源節(jié)點(diǎn)S到終結(jié)點(diǎn)D的最短距離的過(guò)程中,循環(huán)過(guò)程中每次確定一個(gè)源節(jié)點(diǎn)到其它節(jié)點(diǎn)T的最短距離。該距離確定后,遍歷判斷該節(jié)點(diǎn)T到其它節(jié)點(diǎn)的距離是否比現(xiàn)在S到其它節(jié)點(diǎn)距離短,更短的話則修改為相應(yīng)長(zhǎng)度,并將對(duì)應(yīng)的路徑記錄。。這種求最短路徑的方式與圖最小生成樹(shù)算法之Kruskal(克魯斯卡爾)算法有異曲同工之妙。該算法的時(shí)間復(fù)雜度度是O(N^2),N是節(jié)點(diǎn)的個(gè)數(shù)。
? ?代碼如下:
int dist[MAXNUM]; int prevT[MAXNUM]; int final[MAXNUM]; int MIN;int G[9][9]={0,1, 5, MAXINT ,MAXINT, MAXINT, MAXINT, MAXINT, MAXINT,//對(duì)應(yīng)的權(quán)值矩陣 1, 0, 3, 7, 5, MAXINT ,MAXINT, MAXINT ,MAXINT, 5 ,3, 0, MAXINT ,1 ,7, MAXINT ,MAXINT ,MAXINT, MAXINT, 7, MAXINT ,0, 2, MAXINT, 3 ,MAXINT, MAXINT, MAXINT ,5, 1, 2, 0, 3 ,6, 9, MAXINT, MAXINT, MAXINT ,7, MAXINT, 3, 0, MAXINT, 5, MAXINT, MAXINT ,MAXINT ,MAXINT, 3, 6, MAXINT, 0 ,2 ,7, MAXINT, MAXINT ,MAXINT, MAXINT, 9 ,5 ,2, 0, 4, MAXINT, MAXINT ,MAXINT, MAXINT, MAXINT, MAXINT ,7, 4, 0}; void Short_Dijkstra() {//初始化dist和prevTint min_num;for(int i=0;i<MAXNUM;i++){final[i]=0;//標(biāo)記是否是最短路徑dist[i]=G[0][i];//對(duì)應(yīng)權(quán)值prevT[i]=0;}final[0]=1;//對(duì)v0本身就是最短的dist[0]=G[0][0];for(int i=1;i<MAXNUM;i++)//每次遍歷v0到某個(gè)頂點(diǎn)最短距離 {MIN=MAXINT;//最小值min_num=0;for(int j=1;j<MAXNUM;j++){if(!final[j] && dist[j]<MIN){min_num=j;MIN=dist[j];//最小值 }}final[min_num]=1;//找到最小值for(int k=0;k<MAXNUM;k++){if(!final[k] && (G[min_num][k]+dist[min_num]<dist[k])) //在已有的點(diǎn)上找到距離V0更短的距離 {prevT[k]=min_num;//記錄經(jīng)過(guò)的前驅(qū)點(diǎn)dist[k]=G[min_num][k]+dist[min_num];//更新距離 }}} }
Flord算法
? ??Floyd算法是一個(gè)經(jīng)典的動(dòng)態(tài)規(guī)劃算法,它適用于尋找各個(gè)頂點(diǎn)之間的最短距離。從任意節(jié)點(diǎn)i到任意節(jié)點(diǎn)j的最短路徑不外乎2種可能,1是直接從點(diǎn)i到點(diǎn)j,這種方法最直接,但是距離比一定最短。2是從i經(jīng)過(guò)若干個(gè)節(jié)點(diǎn)k到j(luò)。所以,我們假設(shè)Dis(i,j)為節(jié)點(diǎn)i到節(jié)點(diǎn)j的最短路徑的距離,對(duì)于每一個(gè)節(jié)點(diǎn)k,我們檢查Dis(i,k) + Dis(k,j) < Dis(i,j)是否成立,如果成立,證明從i到k再到j(luò)的路徑比i直接到j(luò)的路徑短,我們便設(shè)置Dis(i,j) = Dis(i,k) + Dis(k,j),同時(shí)記錄我們走過(guò)的路徑。這樣一來(lái),當(dāng)我們遍歷完所有節(jié)點(diǎn)k,Dis(i,j)中記錄的便是i到j(luò)的最短路徑的距離。算法時(shí)間復(fù)雜度:O(n3)。
? 代碼如下
? ?
void Short_Dijkstra() {//初始化dist和prevTTint min_num;for(int i=0;i<MAXNUM;i++){final[i]=0;dist[i]=G[0][i];prevT[i]=0;}final[0]=1;//對(duì)v0本身就是最短的dist[0]=G[0][0];for(int i=1;i<MAXNUM;i++)//每次遍歷v0到某個(gè)頂點(diǎn)最短距離 {MIN=MAXINT;//最小值min_num=0;for(int j=1;j<MAXNUM;j++){if(!final[j] && dist[j]<MIN){min_num=j;MIN=dist[j];//最小值 }}final[min_num]=1;//找到最小值for(int k=0;k<MAXNUM;k++){if(!final[k] && (G[min_num][k]+dist[min_num]<dist[k])) //在已有的點(diǎn)上找到距離V0更短的距離 {prevT[k]=min_num;//記錄經(jīng)過(guò)的前驅(qū)點(diǎn)dist[k]=G[min_num][k]+dist[min_num];//更新距離 }}} }? 圖這兩種算法最核心的思想就是:利用已有的最短的距離路徑,通過(guò)這路徑來(lái)不斷擴(kuò)充,最終實(shí)現(xiàn)從原點(diǎn)S到終點(diǎn)D的尋找過(guò)程。
? ?
轉(zhuǎn)載于:https://www.cnblogs.com/zhanjxcom/p/5665879.html
總結(jié)
- 上一篇: 请求接口获取到的数据其中出现null值,
- 下一篇: 移动端资源