兩點間最短路徑及所有路徑

2021-06-09 14:25:40 字數 1558 閱讀 1571

private setnodes;

private map> links;

private mapweights;

nodes用於儲存所有節點,不重複;links為鄰接表;weights為邊上的權值。

1、兩點間最短路徑(dijkstra演算法)

實現**為:

public path shortestpath(int a_node, int b_node)

cost.put(a_node, new path(new link(a_node, a_node), new weight(0.0f)));

//每次迭代qnodes集中被選中的節點

int unode;

while (!qnodes.isempty())

}return cost.get(b_node);

}

其中extractmin函式從qnodes集合中選取從源點出發代價最小的點。relax函式使用到了鬆弛(relaxation)技術。對於每個頂點v ∈ v,都設定乙個屬性d[v],用來描述從源點s到v的最短路徑上權值的上界,稱為

最短路徑估計(shortest-path estimate)。在鬆弛一條邊(u,v)的過程中,要測試是否可以通過u,對迄今找到的到v的最短路徑進行改進;如果可以,就更新。一次鬆弛操作可以減小最短路徑估計的值。(摘自《演算法導論》)

如果只要找出源點到特定點的最短路徑,可以提前跳出迴圈,如**中所示。

2、兩點間所有路徑

實現**如下:

public linkedlistallpath(int a_node, int b_node, weight max)

//初始化變數

stack.add(a_node);

weight = new weight();//初始化為0

states.put(a_node, 1);

cur_node = -1; //定義為第乙個臨接節點的前乙個

while (!stack.isempty())

//找到一條路徑

if (top_node == b_node)

else

else}}

return apath;

}

找出所有路徑採用的是遍歷的方法,以「深度優先」演算法為基礎。從源點出發,先到源點的第乙個鄰接點n00,再到n00的第乙個鄰接點n10,再到n10的第乙個鄰接點n20...當遍歷到目標點時表明找到一條路徑。上述**以核心資料結構為乙個棧,主要步驟:

①源點先入棧,當棧頂為終點時,即找到一條路徑;

②棧頂元素n1出棧,新的棧頂元素為n2,從n2的所有鄰接點中,以n1為起點,選取下乙個n3入棧;

③為避免迴路,已入棧元素要記錄,選取新入棧頂點時應跳過已入棧的頂點

④當棧為空時,遍歷完成。

這裡我用了兩個特殊的標記:乙個值為-1,另乙個值為integer.max_value。前者代表遍歷某個頂點所有鄰接點的開始位置,後者為結束位置。

詳細的演算法描述可以參考中國海洋大學熊建設、梁磊的**《兩點間所有路徑的遍歷演算法》。

兩點間多條最短路徑

最短路徑的求法可能都知道,弗洛伊德和迪克斯特拉。這兩種方法都是求一條最短路徑,如果你想求多條最短路徑那就只能選擇其他方法了。網上已經有幾種演算法可以求多條最短路徑,最常見的就是刪邊法 迪克斯特拉。就是用狄克斯特拉求出一條最短路徑然後把最短路徑上的邊一條一條的刪除然後再求最短路徑。這個方法比較容易想但...

使用DFS求任意兩點間所有路徑

演算法具體原理就不講了,無非是當要返回到前乙個結點時將該結點重新設定為未訪問。void dfs int start,int end path.pop back 刪除最後乙個節點 vis start false 終點重新設定為未訪問 return vis start true 將當前結點設定為已訪問 ...

求解迷宮問題的所有路徑及最短路徑程式

路障 路障路障 路障路障 路障路障 入口 路障路障路障 路障 路障路障 路障路障路障路障 出口 路障路障 路障路障 路障路障 路障如上圖,要求輸出迷宮的所有路徑,並求出最短路徑長度及最短路徑。入口座標設為 1,1 出口座標設為 4,4 親,接下來 include define m 4 行數 defi...