計算無向無權圖中兩點間所有的最短路徑
一、例子
如上圖,節點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 圖(下):最短路徑 圖的最重要的應用之一就是在交通運輸和通訊網路中尋找最短路徑。例如在交通網路中經常會遇到這樣的問題:兩地之間是否有公路可通;在有多條公路可通的情況下,哪