路徑演算法
Ⅰ 求一個最優路徑演算法的思路
同意樓上,最長路徑是NPC問題,不存在多項式演算法。
證明是簡單的:
1、最長無環路問題的判定版本是「給定有向圖D和整數k,問D中是否存在長度大於或等於k的無環路」(這一表述對有權圖和無權圖都有效)。
2、將Hamilton路問題規約到最長無環路問題(的判定版本)是顯然的:輸入一個n頂點的有向圖D,直接問:有向圖D中是否存在長度大於等於n-1的無環路?
簡言之,對任意n頂點的有向圖D,假如能夠D中的找到最長無環路P,那麼就能立即知道D中是否存在Hamilton路(只需看P的長度是否為n-1即可),從而最長無環路問題是NPC。
小規模就直接DFS吧。大規模的時候DFS剪枝。不過確實不好做呀。
有向無圈圖的話可以用dijstra貪心,或者簡單用folyed演算法就可以了(把最小化變為最大化)。
有圈的話您……或者能縮圈么?可以考慮。總之比較復雜。
Ⅱ 圖論中,求歐拉路徑的演算法有哪些
首先要根據歐拉路徑的存在條件來判斷一個圖是否存在歐拉路徑,判斷條件為如下3條
對於一個無向圖,如果它每個點的度都是偶數,那麼它存在一條歐拉迴路;
如果有且僅有2個點的度為奇數,那麼它存在一條歐拉路;
如果超過2個點的度為奇數,那麼它就不存在歐拉路了。
然後可以用Fleury演算法求歐拉路徑,可以參照
http://www.cnblogs.com/Lyush/archive/2013/04/22/3036659.html
Ⅲ 關鍵路徑演算法的時間復雜度
所謂關鍵路徑,就是從工程開始到工程結束所用時間最長的路徑。這是因為,在途中的每一個階段開始之前,都要保證此前的准備工作都已完成,要不然後續工程會無法完成,在尋找路徑時,只能一條路徑一條路徑的比較。本題結果是
Ⅳ 求最優路徑的演算法
以下是C寫的廣度優先的最短路徑窮舉法,希望對你有所幫助.
#include <iostream>
#include <string>
#include <vector>
#include <map>
using namespace std;
#define SIGHTS 4 //自定義景點個數為4,以後可以擴充
class Sight //景點類信息,以後可以擴充
{
public:
Sight(string name, string sd) { sname = name; sight_detial = sd; }
string Sight_Name() { return sname; }
string Sight_detial() { return sight_detial; }
protected:
string sname; //景點名稱
string sight_detial; //景點備注
};
struct SI
{
string sname; //景點名稱
int index; //景點編碼
};
SI SightInfo[SIGHTS];
map<int, string>results; //距離與路徑的映射結構體,可以動態擴充
vector<Sight> sights; //VECTOR向量保存景點信息,目前的作用只是保存
//但是其強大的功能完全可以應付以後的功能擴充
int MinDistanct = 50000; //假定最小距離為一個很大的值
string Sight_Names = "楓林園蛟橋園青山園麥廬園 "; //目標字元串
string Best_Path; //保存最佳路徑的STRING字元串
int DISTANCE[4][4] = { //查找表,用於儲存接點之間距離的信息
0, 1500, 2500, 2400,
1500, 0, 800, 0,
2500, 800, 0, 200,
2400, 0, 200, 0
};
bool connect[4][4] = { //查找表,用於儲存接點之間連通的信息
0, 1, 1, 1,
1, 0, 1, 0,
1, 1, 0, 1,
1, 0, 1, 0
};
void InitSights()
{ //初始化景點的各類信息
SightInfo[0].index=0;
SightInfo[0].sname = "麥廬園";
SightInfo[1].index=1;
SightInfo[1].sname = "楓林園";
SightInfo[2].index=2;
SightInfo[2].sname = "蛟橋園";
SightInfo[3].index=3;
SightInfo[3].sname = "青山園";
Sight s1("楓林園",
"楓林園以計算機系的理工科學生為主,是江西財經大學的唯一一個計算機學院");
sights.push_back(s1);
Sight s2("蛟橋園",
"蛟橋園是江西財經大學的會計、貿易等財務教學為主的教學樓群,為本部");
sights.push_back(s2);
Sight s3("青山園",
"青山園是江西財經大學的會計、貿易等財務教學為主的學生的宿舍群");
sights.push_back(s3);
Sight s4("麥廬園",
"麥廬園是江西財經大學的外語、藝術等人文科學為主的學習園地");
sights.push_back(s4);
}
void Find_Ways(string start, string end, int DIST, string path, int depth)
{ //遞歸調用,逐層尋找可連通的路徑,並以該路徑繼續重復循環查找,根據分析可以
//知道,所有最優解即最短路徑所經過的接點數目必定小於N,於是採用廣度優先遍歷,
//設置count為循環深度,當count大於SIGHTS時退出循環
int count = 1;
int i,j;
int start1 = 0,end1 = 0;
int distanct = 0, storeDist = 0;
string temp, target, pathway, storePath; //臨時儲存體,用於恢復遞歸調用後會
//改變的數據,以便之後無差別使用
count += depth;
if(count > SIGHTS)
return;
distanct += DIST; //距離累加
if(path=="") //第一次時,pathway初始化為第一個接點名稱
{
pathway = start;
pathway += "=>";
}
if(path!="")
pathway = path;
storeDist = distanct; //填充臨時儲存值
storePath = pathway;
for(i = 0; i < SIGHTS; ++i) //通過遍歷,查找景點名稱對應的編號
{
if(start == SightInfo[i].sname)
start1 = SightInfo[i].index;
if(end == SightInfo[i].sname)
end1 = SightInfo[i].index;
}
for(i = 0; i < SIGHTS; i++) //演算法核心步驟
{
if(connect[start1][i] != 0)
{
if(i==end1) //如果找到了一條路徑,則保存之
{
distanct += DISTANCE[start1][end1];
for(j = 0; j < SIGHTS; ++j)
{
if(end1==SightInfo[j].index)
target = SightInfo[j].sname;
}
pathway += target;
results.insert(make_pair(distanct, pathway)); //保存結果路徑信息
distanct = storeDist; //恢復數據供下次使用
pathway = storePath;
}
else //分支路徑
{
for(j = 0; j < SIGHTS; ++j)
{
if(i==SightInfo[j].index)
temp = SightInfo[j].sname;
}
pathway += temp;
pathway += "=>";
distanct += DISTANCE[start1][i];
Find_Ways(temp, end, distanct, pathway, count); //以該連通的分支
//路徑繼續遞歸調用,查找子層路徑信息。
distanct = storeDist; //恢復數據
pathway = storePath;
}
}
}
}
void Find_Best_Way()
{ //該函數建立在上述函數執行完畢之後,在map映射結構中通過對比每條路徑的長度,來
//選擇最優解
map<int, string>::iterator itor = results.begin();
while(itor!=results.end()) //尋找最小值
{
// cout<<"distanct = "<<itor->first<<endl;
if(itor->first < MinDistanct)
MinDistanct = itor->first;
itor++;
}
itor = results.begin();
while(itor!=results.end()) //尋找最小值所對應的整個路徑字元串
{
if(itor->first == MinDistanct)
Best_Path = itor->second;
itor++;
}
}
int main(int argc, char *argv[])
{
int choice;
size_t t1=0,t2=0;
string source, termination;
InitSights();
do{
cout<<"////////////////////////////////////////////////////////\n"
<<"**** 請輸入您所需要的服務號碼: ********\n"
<<"**** 1.楓林園介紹 ********\n"
<<"**** 2.蛟橋園介紹 ********\n"
<<"**** 3.青山園介紹 ********\n"
<<"**** 4.麥廬園介紹 ********\n"
<<"**** 5.查詢地圖路徑 ********\n"
<<"**** 6.退出查詢系統 ********\n"
<<"////////////////////////////////////////////////////////\n"
<<endl;
cin>>choice;
switch(choice)
{
case 1:
cout<<sights[0].Sight_Name()<<endl
<<sights[0].Sight_detial()<<endl;
break;
case 2:
cout<<sights[1].Sight_Name()<<endl
<<sights[1].Sight_detial()<<endl;
break;
case 3:
cout<<sights[2].Sight_Name()<<endl
<<sights[2].Sight_detial()<<endl;
break;
case 4:
cout<<sights[3].Sight_Name()<<endl
<<sights[3].Sight_detial()<<endl;
break;
case 5:
flag1:
cout<<"請輸入路徑的起點"<<endl;
cin>>source;
cout<<"請輸入路徑的終點"<<endl;
cin>>termination;
if((t1=Sight_Names.find(source,t1))==string::npos || (t2=Sight_Names.find(termination,t2))==string::npos)
{ //檢查輸入的數據是否含有非法字元
cerr<<"輸入的路徑結點不存在,請重新輸入:"<<endl;
goto flag1;
}
Find_Ways(source, termination, 0, "",0); //尋找所有可能解
Find_Best_Way(); //在所有可能解中找到最優解
cout<<"最佳路徑是:"<< Best_Path <<endl
<<"最小路程為(米):"<< MinDistanct<<endl;
t1 = 0; //恢復字元串下標,以支持下次查詢
t2 = 0;
break;
case 6:
break;
default:
cerr<<"您的選擇超出了范圍,請重新輸入:"<<endl;
break;
}
}while(choice!=6);
system("pause");
return 0;
}
Ⅳ 求路徑演算法
到達每個點之前只可能在左右下相鄰的點,因此只要把左右下的最短路徑的距離加上到達當前點的邊的距離,保留個最小的就可以了,所以說思路和經典最短路徑一樣。(屬於動態規劃演算法,這是經典的演算法設計思想)
關鍵是算的順序。對於只允許向上向右的情況,先算哪個都行,只要保證算之前左邊和下邊節點之前算過吧並且是正確的就行。
最下邊第一層最好算,和只能向右上的情況一樣。
之後一層一層地算就可以,因為多出來向左走並不會影響下面的層計算出來的最短路徑。
關鍵是同層是怎麼算,應該從左向右算。
PS:上面的演算法只是對網格的一個特例,可以一般化。
PSS:如果對演算法感興趣,推薦《演算法導論》,只要理解力足夠,基本不需要事先學微積分之類的課。總之,推薦!但考慮到你會提出這樣的問題,直接無視吧。
Ⅵ 求有向圖兩點間是否存在路徑的「演算法思想」
從一個點進行深度優先搜索 看能不能到另外一個點
Ⅶ 一個矩陣從一點到另外一點的所有路徑的演算法
我去ebay面試的題目 和LZ有點區別 從(0,0)到(3,3) 只能往上和往右走 求所有路徑
回家做了一個小時 用java做的
不能用遞歸 如果矩陣大了 遞歸會棧溢出
如果是這個題目 回去給你發代碼
Ⅷ 百度地圖的路徑搜索演算法
這個還是要問程序猿,現在比較流行A*演算法,至於網路是否開發出了新的演算法不得而知,畢竟沒有完全相同的程序。
給你看一篇文獻:
地圖中最短路徑的搜索演算法研究
學生:李小坤 導師:董巒
摘要:目前為止, 國內外大量專家學者對「最短路徑問題」進行了深入的研究。本文通過理論分析, 結合實際應用,從各個方面較系統的比較廣度優先搜索演算法(BFS)、深度優先搜索演算法(DFS)、A* 演算法的優缺點。
關鍵詞:最短路徑演算法;廣度優先演算法;深度優先演算法;A*演算法;
The shortest path of map's search algorithm
Abstract:So far, a large number of domestic and foreign experts and scholars on the" shortest path problem" in-depth study. In this paper, through theoretical analysis and practical application, comprise with the breadth-first search algorithm ( BFS ), depth-first search algorithm ( DFS ) and the A * algorithms from any aspects of systematic.
Key words: shortest path algorithm; breadth-first algorithm; algorithm; A * algorithm;
前言:
最短路徑問題是地理信息系統(GIS)網路分析的重要內容之一,而且在圖論中也有著重要的意義。實際生活中許多問題都與「最短路徑問題」有關, 比如: 網路路由選擇, 集成電路設計、布線問題、電子導航、交通旅遊等。本文應用深度優先演算法,廣度優先演算法和A*演算法,對一具體問題進行討論和分析,比較三種算的的優缺點。
在地圖中最短路徑的搜索演算法研究中,每種演算法的優劣的比較原則主要遵循以下三點:[1]
(1)演算法的完全性:提出一個問題,該問題存在答案,該演算法能夠保證找到相應的答案。演算法的完全性強是演算法性能優秀的指標之一。
(2)演算法的時間復雜性: 提出一個問題,該演算法需要多長時間可以找到相應的答案。演算法速度的快慢是演算法優劣的重要體現。
(3)演算法的空間復雜性:演算法在執行搜索問題答案的同時,需要多少存儲空間。演算法佔用資源越少,演算法的性能越好。
地圖中最短路徑的搜索演算法:
1、廣度優先演算法
廣度優先演算法(Breadth-First-Search),又稱作寬度優先搜索,或橫向優先搜索,是最簡便的圖的搜索演算法之一,這一演算法也是很多重要的圖的演算法的原型,Dijkstra單源最短路徑演算法和Prim最小生成樹演算法都採用了和寬度優先搜索類似的思想。廣度優先演算法其別名又叫BFS,屬於一種盲目搜尋法,目的是系統地展開並檢查圖中的所有節點,以找尋結果。換句話說,它並不考慮結果的可能位址,徹底地搜索整張圖,直到找到結果為止。BFS並不使用經驗法則演算法。
廣度優先搜索演算法偽代碼如下:[2-3]
BFS(v)//廣度優先搜索G,從頂點v開始執行
//所有已搜索的頂點i都標記為Visited(i)=1.
//Visited的初始分量值全為0
Visited(v)=1;
Q=[];//將Q初始化為只含有一個元素v的隊列
while Q not null do
u=DelHead(Q);
for 鄰接於u的所有頂點w do
if Visited(w)=0 then
AddQ(w,Q); //將w放於隊列Q之尾
Visited(w)=1;
endif
endfor
endwhile
end BFS
這里調用了兩個函數:AddQ(w,Q)是將w放於隊列Q之尾;DelHead(Q)是從隊列Q取第一個頂點,並將其從Q中刪除。重復DelHead(Q)過程,直到隊列Q空為止。
完全性:廣度優先搜索演算法具有完全性。這意指無論圖形的種類如何,只要目標存在,則BFS一定會找到。然而,若目標不存在,且圖為無限大,則BFS將不收斂(不會結束)。
時間復雜度:最差情形下,BFS必須尋找所有到可能節點的所有路徑,因此其時間復雜度為,其中|V|是節點的數目,而 |E| 是圖中邊的數目。
空間復雜度:因為所有節點都必須被儲存,因此BFS的空間復雜度為,其中|V|是節點的數目,而|E|是圖中邊的數目。另一種說法稱BFS的空間復雜度為O(B),其中B是最大分支系數,而M是樹的最長路徑長度。由於對空間的大量需求,因此BFS並不適合解非常大的問題。[4-5]
2、深度優先演算法
深度優先搜索演算法(Depth First Search)英文縮寫為DFS,屬於一種回溯演算法,正如演算法名稱那樣,深度優先搜索所遵循的搜索策略是盡可能「深」地搜索圖。[6]其過程簡要來說是沿著頂點的鄰點一直搜索下去,直到當前被搜索的頂點不再有未被訪問的鄰點為止,此時,從當前輩搜索的頂點原路返回到在它之前被搜索的訪問的頂點,並以此頂點作為當前被搜索頂點。繼續這樣的過程,直至不能執行為止。
深度優先搜索演算法的偽代碼如下:[7]
DFS(v) //訪問由v到達的所有頂點
Visited(v)=1;
for鄰接於v的每個頂點w do
if Visited(w)=0 then
DFS(w);
endif
endfor
end DFS
作為搜索演算法的一種,DFS對於尋找一個解的NP(包括NPC)問題作用很大。但是,搜索演算法畢竟是時間復雜度是O(n!)的階乘級演算法,它的效率比較低,在數據規模變大時,這種演算法就顯得力不從心了。[8]關於深度優先搜索的效率問題,有多種解決方法。最具有通用性的是剪枝,也就是去除沒有用的搜索分支。有可行性剪枝和最優性剪枝兩種。
BFS:對於解決最短或最少問題特別有效,而且尋找深度小,但缺點是內存耗費量大(需要開大量的數組單元用來存儲狀態)。
DFS:對於解決遍歷和求所有問題有效,對於問題搜索深度小的時候處理速度迅速,然而在深度很大的情況下效率不高。
3、A*演算法
1968年的一篇論文,「P. E. Hart, N. J. Nilsson, and B. Raphael. A formal basis for the heuristic determination of minimum cost paths in graphs. IEEE Trans. Syst. Sci. and Cybernetics, SSC-4(2):100-107, 1968」。[9]從此,一種精巧、高效的演算法——A*演算法問世了,並在相關領域得到了廣泛的應用。A* 演算法其實是在寬度優先搜索的基礎上引入了一個估價函數,每次並不是把所有可擴展的結點展開,而是利用估價函數對所有未展開的結點進行估價, 從而找出最應該被展開的結點,將其展開,直到找到目標節點為止。
A*演算法主要搜索過程偽代碼如下:[10]
創建兩個表,OPEN表保存所有已生成而未考察的節點,CLOSED表中記錄已訪問過的節點。
算起點的估價值;
將起點放入OPEN表;
while(OPEN!=NULL) //從OPEN表中取估價值f最小的節點n;
if(n節點==目標節點) break;
endif
for(當前節點n 的每個子節點X)
算X的估價值;
if(X in OPEN)
if(X的估價值小於OPEN表的估價值)
把n設置為X的父親;
更新OPEN表中的估價值; //取最小路徑的估價值;
endif
endif
if(X inCLOSE)
if( X的估價值小於CLOSE表的估價值)
把n設置為X的父親;
更新CLOSE表中的估價值;
把X節點放入OPEN //取最小路徑的估價值
endif
endif
if(X not inboth)
把n設置為X的父親;
求X的估價值;
並將X插入OPEN表中; //還沒有排序
endif
end for
將n節點插入CLOSE表中;
按照估價值將OPEN表中的節點排序; //實際上是比較OPEN表內節點f的大小,從最小路徑的節點向下進行。
end while(OPEN!=NULL)
保存路徑,即 從終點開始,每個節點沿著父節點移動直至起點,這就是你的路徑;
A *演算法分析:
DFS和BFS在展開子結點時均屬於盲目型搜索,也就是說,它不會選擇哪個結點在下一次搜索中更優而去跳轉到該結點進行下一步的搜索。在運氣不好的情形中,均需要試探完整個解集空間, 顯然,只能適用於問題規模不大的搜索問題中。而A*演算法與DFS和BFS這類盲目型搜索最大的不同,就在於當前搜索結點往下選擇下一步結點時,可以通過一個啟發函數來進行選擇,選擇代價最少的結點作為下一步搜索結點而跳轉其上。[11]A *演算法就是利用對問題的了解和對問題求解過程的了解, 尋求某種有利於問題求解的啟發信息, 從而利用這些啟發信息去搜索最優路徑.它不用遍歷整個地圖, 而是每一步搜索都根據啟發函數朝著某個方向搜索.當地圖很大很復雜時, 它的計算復雜度大大優於D ijks tr a演算法, 是一種搜索速度非常快、效率非常高的演算法.但是, 相應的A*演算法也有它的缺點.啟發性信息是人為加入的, 有很大的主觀性, 直接取決於操作者的經驗, 對於不同的情形要用不同的啟發信息和啟發函數, 且他們的選取難度比較大,很大程度上找不到最優路徑。
總結:
本文描述了最短路徑演算法的一些步驟,總結了每個演算法的一些優缺點,以及演算法之間的一些關系。對於BFS還是DFS,它們雖然好用,但由於時間和空間的局限性,以至於它們只能解決規模不大的問題,而最短或最少問題應該選用BFS,遍歷和求所有問題時候則應該選用DFS。至於A*演算法,它是一種啟發式搜索演算法,也是一種最好優先的演算法,它適合於小規模、大規模以及超大規模的問題,但啟發式搜索演算法具有很大的主觀性,它的優劣取決於編程者的經驗,以及選用的啟發式函數,所以用A*演算法編寫一個優秀的程序,難度相應是比較大的。每種演算法都有自己的優缺點,對於不同的問題選擇合理的演算法,才是最好的方法。
參考文獻:
[1]陳聖群,滕忠堅,洪親,陳清華.四種最短路徑演算法實例分析[J].電腦知識與技術(學術交流),2007(16):1030-1032
[2]劉樹林,尹玉妹.圖的最短路徑演算法及其在網路中的應用[J].軟體導刊,2011(07):51-53
[3]劉文海,徐榮聰.幾種最短路徑的演算法及比較[J].福建電腦,2008(02):9-12
[4]鄧春燕.兩種最短路徑演算法的比較[J].電腦知識與技術,2008(12):511-513
[5]王蘇男,宋偉,姜文生.最短路徑演算法的比較[J].系統工程與電子技術,1994(05):43-49
[6]徐鳳生,李天志.所有最短路徑的求解演算法[J].計算機工程與科學,2006(12):83-84
[7]李臣波,劉潤濤.一種基於Dijkstra的最短路徑演算法[J].哈爾濱理工大學學報,2008(03):35-37
[8]徐鳳生.求最短路徑的新演算法[J].計算機工程與科學,2006(02).
[9] YanchunShen . An improved Graph-based Depth-First algorithm and Dijkstra algorithm program of police patrol [J] . 2010 International Conference on Electrical Engineering and Automatic Control , 2010(3) : 73-77
[10]部亞松.VC++實現基於Dijkstra演算法的最短路徑[J].科技信息(科學教研),2008(18):36-37
[11] 楊長保,王開義,馬生忠.一種最短路徑分析優化演算法的實現[J]. 吉林大學學報(信息科學版),2002(02):70-74
Ⅸ C++ 演算法,路徑,多謝
僅供參考 了
#include "stdio.h"
#define maxver 10
#define maxright 100
int G[maxver][maxver],record=0,touched[maxver][maxver];
int circle=0;
int FindCircle(int,int,int,int);
int main()
{
int path[maxver][2],used[maxver][maxver];
int i=0,j=0,k=0,t,min=maxright,exsit=0;
int v1,v2,num,temp,status=0;
restart:
printf("Please enter the number of vertex(s) in the graph:\n");
scanf("%d",&num);
if (num>maxver||num<0)
{
printf("Error!Please reinput!\n");
goto restart;
}
for (j=0;j<num;j++)
for (k=0;k<num;k++)
{
if (j==k)
{
G[j][k]=maxright;
used[j][k]=1;
touched[j][k]=0;
}
else
if (j<k)
{
re:
printf("Please input the right between vertex %d and vertex %d,if no edge exists please input -1:\n",j+1,k+1);
scanf("%d",&temp);
if (temp>=maxright||temp<-1)
{
printf("Invalid input!\n");
goto re;
}
if (temp==-1)
temp=maxright;
G[j][k]=G[k][j]=temp;
used[j][k]=used[k][j]=0;
touched[j][k]=touched[k][j]=0;
}
}
for (j=0;j<num;j++)
{
path[j][0]=0;
path[j][1]=0;
}
for (j=0;j<num;j++)
{
status=0;
for (k=0;k<num;k++)
if (G[j][k]<maxright)
{
status=1;
break;
}
if (status==0)
break;
}
for (i=0;i<num-1&&status;i++)
{
for (j=0;j<num;j++)
for (k=0;k<num;k++)
if (G[j][k]<min&&!used[j][k])
{
v1=j;
v2=k;
min=G[j][k];
}
if (!used[v1][v2])
{
used[v1][v2]=1;
used[v2][v1]=1;
touched[v1][v2]=1;
touched[v2][v1]=1;
path[0]=v1;
path[1]=v2;
for (t=0;t<record;t++)
FindCircle(path[t][0],path[t][0],num,path[t][0]);
if (circle)
{
/*if a circle exsits,roll back*/
circle=0;
i--;
exsit=0;
touched[v1][v2]=0;
touched[v2][v1]=0;
min=maxright;
}
else
{
record++;
min=maxright;
}
}
}
if (!status)
printf("We cannot deal with it because the graph is not connected!\n");
else
{ for (i=0;i<num-1;i++)
printf("Path %d:vertex %d to vertex %d\n",i+1,path[0]+1,path[1]+1);
}
return 1;
}
int FindCircle(int start,int begin,int times,int pre)
{
/* to judge whether a circle is proced*/
int i;
for (i=0;i<times;i++)
if (touched[begin]==1)
{
if (i==start&&pre!=start)
{
circle=1;
return 1;
break;
}
else
if (pre!=i)
FindCircle(start,i,times,begin);
else
continue;
}
return 1;
}
Ⅹ 路徑分析的最優路徑分析方法
1.道路預處理
進行道路數據錄入時,往往在道路的交叉接合處出現重疊或相離的情況,不宜計算機處理。因此,需要對原始數據進行預處理,使道路接合符合處理要求。進行預處理時,取每條線段的首末節點坐標為圓心,以給定的閾值為半徑作圓域,判斷其他線段是否與圓域相交,如果相交,則相交的各個線對象共用一個節點號。
2.道路自動斷鏈
對道路進行預處理之後即可獲得比較理想的數據,在此基礎上再進行道路的自動斷鏈。步驟如下:
(1)取出所有線段記錄數n,從第一條線段開始;
(2)找出所有與之相交的線段並求出交點數m;
(3)將m個交點和該線段節點在判斷無重合後進行排序;
(4)根據交點數量,該線段被分成m+1段;
(5)第一段在原始位置不變,後m段從記錄尾開始遞增;
(6)重復(2)~(5),循環至n。
3.節點匹配
拓撲關系需使用統一的節點。節點匹配方法是按記錄順序將所有線段的始末點加上相應節點號,坐標相同的節點共用一個節點號,與前面所有線段首末點都不相同的節點按自然順序遞增1。
4.迪傑克斯特拉(Dijkstra)演算法
經典的圖論與計算機演算法的有效結合,使得新的最短路徑演算法不斷涌現。目前提出的最短路徑演算法中,使用最多、計算速度比較快,又比較適合於計算兩點之間的最短路徑問題的數學模型就是經典的Dijkstra演算法。
該演算法是典型的單源最短路徑演算法,由Dijkstra EW於1959年提出,適用於所有弧的權均為非負的情況,主要特點是以起始點為中心向外層層擴展,直到擴展到終點為止。該演算法的基本思想是:認為兩節點間最佳路徑要麼是直接相連,要麼是通過其他已找到的與起始點的最佳路徑的節點中轉點。定出起始點P0後,定能找出一個與之直接相連且路徑長度最短的節點,設為P1,P0到P1就是它們間的最佳路徑。
Dijkstra演算法的基本流程如下:首先將網路中所有節點分成兩組,一組包含了已經確定屬於最短路徑中點的集合,記為S(該集合在初始狀態只有一個源節點,以後每求得一條最短路徑,就將其加入到集合S中,直到全部頂點都加入到S中,演算法就結束了);另一組是尚未確定最短路徑的節點的集合,記為V,按照最短路徑長度遞增的次序依次把第二組的頂點加入到第一組中,在加入的過程中總保持從源點到S中各頂點的最短路徑長度不大於從源點到V中任何頂點的最短路徑長度。此外,每個頂點對應一個距離,S中的頂點距離就是從源點到此頂點的最短路徑長度,V中的頂點距離是從源點到此頂點只包括S中的頂點為中間頂點的當前最短路徑長度。