1. 程式人生 > >計算無向無權圖中兩點間所有的最短路徑

計算無向無權圖中兩點間所有的最短路徑

 

一、例子

如上圖,節點0到節點5的最短路徑長度為3,有兩條最短路徑:

路徑1:0 — 1 — 4— 5

路徑2:0 — 1 — 2— 5

二、相關名稱

tempLadder:             儲存當前正在計算的路徑
canditStack:              儲存備選結點的棧
shortestLength:        最短路徑長度
startNode:                開始節點
endNode:                 終止節點
allShortestPath:    儲存startNod與endNode之間的所有的最短路徑。


三、約束條件:
1、如果節點node_a在路徑tempLadder中,從startNode起,node_a之前的各節點與node_a的距離分別是i,i-1,i-2....1,node_a與終結點的距離為shortestLength-i。


2、遍歷與node_a相鄰的各個節點,如果結點node_i已經在當前路徑tempLadder或者在canditStack中,或者與endNode的距離大於node_a與endNode的距離,則應該過濾掉node_i。

四:演算法過程:
step1、使用floyd計算結點間的最短距離


step2、輸入起點和終點的結點序號


step3、計算起點到終點間的所有最短距離


step3.1
 將startNode加入到tempLadder中,再將所有與startNode距離為1,與終結點距離為shortestLength-1的結點加入canditStack中,然後進入step3.2。


step3.2
當canditStack為空時,進入step4。

當canditStack不為空時,從canditStack中取出棧頂元素node,然後進入step3.3。

step3.3

如果node滿足條件1,則加入到tempLadder中,如果node與endNode距離為1,則同時將tempLadder加入到allShortestPath,tempLadder進行出棧,然後進入step3.4。

如果node不滿足條件1,tempLadder出棧,直到node滿足條件1為止,然後將node壓入tempLadder中,然後進入step3.4。

step3.4

遍歷與node距離為1的節點,如果滿足條件2,則過濾掉,否則,加入到canditStack中,進入step3.2。

step4

演算法終止。

五、程式

////////////////////////allshortpath.h////////////////////////////////
#ifndef H_FLOYD
#define H_FLOYD


#include <vector>


using namespace std;


#define MAX 1000
#define NODECOUNT 6  //結點數


typedef char VexType;


struct GraphMatrix
{
int n; //圖的頂點個數
VexType *vexs;//頂點資訊
int arcs[NODECOUNT][NODECOUNT];//邊資訊
};


struct ShortPath
{
int a[NODECOUNT][NODECOUNT];
int nextvex[NODECOUNT][NODECOUNT];
};


void floyd(GraphMatrix * pgraph, ShortPath * ppath);


void show_GraphMatirx(GraphMatrix * pgraph, int nodeCount);


void show_path(ShortPath * ppath, int nodeCount);


int shortestPath_2Nodes(int startNode, int endNode, ShortPath *ppath);


//判斷結點是否已經存在當前路徑中
int inVector(int nodeNum, vector<int> & tempvector, ShortPath *ppath);


int isPostNode(int nodeNum, int endNode, vector<int> & tempvector, ShortPath *ppath);


vector<vector<int>> getAllShortestPath(int startNode, int endNode, ShortPath *ppath, int nodeCount);


#endif


/////////////////////////////////////////allshortpath.cpp//////////////////////////////////////////////
#include <stdio.h>
#include <malloc.h>
#include <iostream>
#include <string>


#include "allshortpath.h"


void floyd(GraphMatrix * pgraph, ShortPath * ppath)
{
int i,j,k;
for ( i=0; i<pgraph->n; i++ )
{
for ( j=0; j<pgraph->n; j++ )
{
ppath->a[i][j] = pgraph->arcs[i][j];
}
}


for ( k=0; k<pgraph->n; k++ )
{
for ( i=0; i<pgraph->n; i++ )
{
for ( j=0; j<pgraph->n; j++ )
{
if ( (ppath->a[i][k]>=MAX)||(ppath->a[k][j]>=MAX) )
continue;


if ( ppath->a[i][j] > (ppath->a[i][k] + ppath->a[k][j]) )
{
ppath->a[i][j] = ppath->a[i][k] + ppath->a[k][j];
}
}
}
}
}


void show_GraphMatirx(GraphMatrix *pgraph, int nodeCount)
{
int i,j;


for ( i=0; i<nodeCount; i++ )
{
for ( j=0; j<nodeCount; j++ )
{
printf("%5d  ",pgraph->arcs[i][j]);
}
printf("\n");
}
printf("\n");
}


void show_path(ShortPath *ppath, int nodeCount)
{
int i, j;


for ( i=0; i<nodeCount; i++ )
{
for ( j=0; j<nodeCount; j++ )
{
printf("%5d ", ppath->a[i][j]);
}
printf("\n");
}
printf("\n");
}


int shortestPath_2Nodes(int startNode, int endNode, ShortPath *ppath)
{
int distance = ppath->a[startNode][endNode];
return distance;
}


vector<vector<int>> getAllShortestPath(int startNode, int endNode, ShortPath *ppath, int nodeCount)
{
int nodeNum = 0;
int tempFromStack;
int tempFromLadder;
int shortestLength;


vector<int> canditNodeStack;
vector<int> tempLadder;
vector<vector<int>> resultvector;


if ( startNode == endNode )
{
return resultvector;
}

tempLadder.push_back(startNode);
if ( ppath->a[startNode][endNode] == 1 )
{
tempLadder.push_back(endNode);
resultvector.push_back(tempLadder);
return resultvector;
}

shortestLength = shortestPath_2Nodes(startNode, endNode, ppath);


for ( nodeNum = 0; nodeNum < nodeCount; nodeNum++ )
{
if ( shortestPath_2Nodes(nodeNum, startNode, ppath) == 1 )
{
canditNodeStack.push_back(nodeNum);
}
}


while ( canditNodeStack.size() > 0 )
{
tempFromStack = canditNodeStack.back(); 
canditNodeStack.pop_back();

int d_temp_end = shortestPath_2Nodes(tempFromStack, endNode, ppath);

if ( d_temp_end == 0 && tempLadder.size() == shortestLength )
{
tempLadder.push_back(tempFromStack);
resultvector.push_back(tempLadder);
tempLadder.pop_back();
}
else
{
if ( isPostNode(tempFromStack, endNode, tempLadder, ppath) == 1 )
{
if ( tempLadder.size() <= shortestLength )
{
tempLadder.push_back(tempFromStack);
}
}
else
{
while ( tempLadder.size() > 0 && tempLadder.back() != startNode )
{
tempLadder.pop_back();


if ( isPostNode(tempFromStack, endNode, tempLadder, ppath) == 1 )
{
tempLadder.push_back(tempFromStack);
break;
}


}
}
}


for ( nodeNum = 0; nodeNum < nodeCount; nodeNum++ )
{
int i2 = shortestPath_2Nodes(tempFromStack, nodeNum, ppath); 
int i3 = shortestPath_2Nodes(endNode, nodeNum, ppath);
if ( i2 == 1 && d_temp_end > i3 && !inVector(nodeNum, canditNodeStack, ppath) && !inVector(nodeNum, tempLadder, ppath))
{
canditNodeStack.push_back(nodeNum);
}
}
}


return resultvector;


}


int inVector(int nodeNum, vector<int> & tempvector, ShortPath *ppath)
{
int exist = 0;
vector<int>::iterator it;
for ( it=tempvector.begin(); it!=tempvector.end(); it++ )
{


if(shortestPath_2Nodes(*it, nodeNum, ppath)==0)
{
exist = 1;
break;
}
}


return exist;


}


int isPostNode(int nodeNum, int endNode, vector<int> & tempvector, ShortPath *ppath)
{
if ( nodeNum == tempvector.back() )
{
return 0;
}


int flag = 1;
int d_temp_end = shortestPath_2Nodes(nodeNum, endNode, ppath);
int d_back_end = shortestPath_2Nodes(tempvector.back(), endNode, ppath);


if ( d_temp_end >= d_back_end )
{
return 0;
}


for ( int i = tempvector.size() - 1; i >= 0; i-- )
{
if ( shortestPath_2Nodes(nodeNum, tempvector.at(i), ppath) != (tempvector.size() - i) )
{
flag = 0;
}


}


return flag;


}


////////////////////////main.cpp////////////////////////////////////
#include <set>
#include <iostream>
#include <vector>


#include "allshortpath.h"


using namespace std;


void CalAllShortestPath()
{
int i=0;
int j=0;


GraphMatrix *pgraph = (GraphMatrix *)malloc(sizeof(struct GraphMatrix));
ShortPath   *ppath  = (ShortPath *)malloc(sizeof(struct ShortPath));


if ( pgraph==NULL || ppath==NULL )
{
return;
}


pgraph->n = NODECOUNT;


////////////////////初始化無向無權圖的鄰接矩陣///////////////////////////
int arcs[NODECOUNT][NODECOUNT]={0,1,MAX,MAX,MAX,MAX,  1,0,1,MAX,1,MAX,  MAX,1,0,1,MAX,1,  MAX,MAX,1,0,1,MAX,  MAX,1,MAX,1,0,1,  MAX,MAX,1,MAX,1,0};
//int arcs[POINTNUM][POINTNUM]={0,1,1,MAX,1,MAX,MAX,MAX,  1,0,1,1,MAX,MAX,MAX,MAX,  1,1,0,1,MAX,MAX,MAX,MAX,  MAX,1,1,0,MAX,1,MAX,MAX,  1,MAX,MAX,MAX,0,MAX,1,1,  MAX,MAX,MAX,1,MAX,0,1,1, MAX,MAX,MAX,MAX,1,1,0,1, MAX,MAX,MAX,MAX,1,1,1,0};

for ( i = 0; i < NODECOUNT; i++ )
{
for ( j = 0; j < NODECOUNT; j++ )
{
pgraph->arcs[i][j] = arcs[i][j];
}
}


show_GraphMatirx(pgraph, NODECOUNT);


floyd(pgraph, ppath);


show_path(ppath, NODECOUNT);
int startNode = 5;
int endNod = 0;
vector<vector<int>> result = getAllShortestPath(startNode, endNod, ppath, NODECOUNT);
vector<int> eachone;
vector<int>::iterator eachI;
set<int>::iterator it;
vector<vector<int>>::iterator resultIt;


for ( resultIt=result.begin(); resultIt!=result.end(); resultIt++ )
{
eachone = *resultIt;


for ( eachI=eachone.begin(); eachI!=eachone.end(); eachI++ )
{
cout<<*eachI<<" ";
}


cout<<endl;
}


}


int main()
{
CalAllShortestPath();

system("pause");


return 0;
}


相關推薦

計算無權兩點所有路徑

  一、例子 如上圖,節點0到節點5的最短路徑長度為3,有兩條最短路徑: 路徑1:0 — 1 — 4— 5 路徑2:0 — 1 — 2— 5 二、相關名稱 tempLadder:             儲存當前正在計算的路徑 canditStack:          

連通兩點所有路徑的演算法

http://bbs.csdn.net/topics/360001583 之前在csdn就這個問題發帖求教過,過了幾天沒看到回覆就沒再關心。後來自己設計了一個演算法,在公司的專案中實踐了一下,效果還可以,貼出來供大家參考。演算法要求:1. 在一個無向連通圖中求出兩個給

通過按層遍歷求等權兩點路徑

/** * * @param a * Person a * @param b * Person b * @return a與b之間的距離,返回 0 如果a=b,返

12.帶權有任意兩點路徑

其實它的程式碼理解起來真的挺難的我覺得!!! 昨天看了一下午感覺晦澀難懂,還是matlab好用,直接呼叫函式就可以了!!! 不過這裡還是得跟大家介紹一下: 1.問題的理解: 像這種帶權的有向圖,每一行都表示該行標號對應列標號的有向權值,本身到本身的數值為0,沒辦法

《演算法導論》筆記 第24章 24.2 有的單源路徑

【筆記】 對dag進行拓撲排序對每個頂點鬆弛從該點出發的所有邊。 【練習】 24.2-1 以頂點r為源點,執行DAG。 略 24.2-2 對|V|-1處理仍正確。 最後一個點的鬆弛不會對之前的點有影響,因此處理正確。 24.2-3 權值賦給頂點應如何計算。 2

頂點之間的所有路徑

思路一: DFS,遇到終點之後進行記錄 輔助儲存: std::vector<int> tempPath; std::vector<std::vector<int>> totalPath; 實現: //查詢無向

AOJ GRL_1_C: All Pairs Shortest Path (Floyd-Warshall算法求任意兩點路徑)(Bellman-Ford算法判斷負圈)

self logs var inf sel main rain test rect 題目鏈接:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_1_C All Pairs Shortest

floyd演算法(求任意兩點路徑)

floyd演算法用於求任意兩點間的最短路徑,時間複雜度為O(n^3)。 通過多次呼叫 Digkstar 演算法同樣能解決這個問題,時間複雜度同樣為O(n^3),但floyd更簡潔,利於程式設計。 fl

的Dijkstra演算法(求任意一對頂點路徑)迪傑斯特拉演算法

public class Main{ public static int dijkstra(int[][] w1,int start,int end) { boolean[] isLable = new boolean[w1[0].length];//是否標上所有的號 i

Matalab程式碼 實現 Dijkstra求 有之間,任意兩點之間的路徑

<span style="font-family: Arial, Helvetica, sans-serif;">%% Dijkstra </span>function minWeightMatrix=shortestPath(G,nodeNum)

相關演算法(二):無權的廣度優先遍歷(BFS)-非遞迴版本

核心 採用鄰接表作為圖資料的儲存結構 對訪問過的節點進行記錄,文中採用HashSet實現 採用佇列存放未訪問的子節點,不斷更新佇列 BFS採用佇列實現很簡單,採用遞迴反而更復雜了 本文建立的圖結構如

利用graphviz來實現視覺化(求路徑

1.首先下載graphviz,並安裝。 2.將輸入的邊儲存起來。 3.將最短路徑求出,並存儲每個頂點的前驅。 4.在程式中將建邊的程式碼寫入一個dot檔案中。 5.將dot檔案轉化為.png形式。 6.利用system函式開啟.png。 程式碼如下: #include &

經典演算法之Floyd演算法(求任意一對頂點路徑

/************************ author's email:[email protected] date:2018.1.30 *********************

經典演算法之Dijkstra演算法(求任意一對頂點路徑

/************************ author's email:[email protected] date:2018.1.30 ************************/ /* 迪傑斯特拉演算法思想: 設有兩個頂點集合S和T,集合S中

資料結構——第四章:06求兩點之間的路徑

1.求兩點之間的最短路徑: (1)求從某個源點到其餘各點的最短路徑:Dijstra(迪傑斯特拉)演算法; (2)求每一對頂點之間的最短路徑:Floyd(弗洛伊德)演算法。 2.Dijstra演算法的基本思想:依據最短路徑的長度遞增的次序求得各條路徑。其中,從源點到頂點v的最短路徑是所有最短路徑中長度最短

資料結構 求單源路徑實現 純程式碼

如下有向圖 求出單源起點A到所有其他節點的最短路徑 完整程式碼: #include <stdio.h> #include <memory.h> //圖論的迪傑斯特拉演算法 #define FINITY 200 #define M 20 //單源點頂點到其他

Python-通過Dijkstra計算兩點之間的路徑

文章是基於http://blog.csdn.net/playboyno/article/details/7832437的實現程式碼進行修改,最終實現計算兩點之間的最短路徑並把經過的點記錄下來。 1.圖和連結中的一樣。 2.程式碼 ''' file: py_Dijkstr

Codeforces Round #261(Div 2) E Pashmak and Graph(嚴格遞增的路徑、思維)

題目連結 題意 給一個n個點和m條帶權值的有向邊的圖。保證無自環和重邊。在圖中找到最長的一條有向路徑,使得路徑中的邊權是嚴格遞增的,求路徑的最大長度(路徑中邊的數量)。 資料範圍:2≤n≤

構建有帶權用鄰接矩陣求路徑

#include <bits/stdc++.h> #include <limits> using namespace std; int main() { int tu[1

資料結構基礎之(下):路徑

轉自:http://www.cnblogs.com/edisonchou/p/4691020.html   圖(下):最短路徑 圖的最重要的應用之一就是在交通運輸和通訊網路中尋找最短路徑。例如在交通網路中經常會遇到這樣的問題:兩地之間是否有公路可通;在有多條公路可通的情況下,哪