Java 使用Dijkstra检测多条最短路径
给定一个加权有向图,如何修改Dijkstra算法来测试给定一对节点之间是否存在多条成本最低的路径 我目前的算法如下:(归功于Weiss)Java 使用Dijkstra检测多条最短路径,java,graph-theory,shortest-path,dijkstra,Java,Graph Theory,Shortest Path,Dijkstra,给定一个加权有向图,如何修改Dijkstra算法来测试给定一对节点之间是否存在多条成本最低的路径 我目前的算法如下:(归功于Weiss) /** *单源加权最短路径算法。(迪杰斯特拉) *使用基于二进制堆的优先级队列 */ 公共无效dijkstra(字符串起始名) { PriorityQueue pq=新的PriorityQueue(); 顶点开始=vertexMap.get(startName); if(start==null) 抛出新的NoTouchElementException(“未找到
/**
*单源加权最短路径算法。(迪杰斯特拉)
*使用基于二进制堆的优先级队列
*/
公共无效dijkstra(字符串起始名)
{
PriorityQueue pq=新的PriorityQueue();
顶点开始=vertexMap.get(startName);
if(start==null)
抛出新的NoTouchElementException(“未找到起始顶点”);
clearAll();
pq.add(新路径(start,0));start.dist=0;
int nodessen=0;
而(!pq.isEmpty()&&nodeseenv.dist+cvw)
{
w、 dist=v.dist+cvw;
w、 prev=v;
pq.add(新路径(w,w.dist));
}
}
}
}
如果您只想找到一条其他成本相等的路径
假设您已经运行了Dijkstra算法一次,以获得最短路径p
。您可以在P
中的每条边上添加一个极小的成本epsilon
,并在修改后的图上再次运行Dijkstra,以获得一个新路径P'
。如果P
和P'
包含相同的边,则可以得出结论P
是唯一的最短路径。否则,我们撤消epsilon
更改并比较P
和P'
的长度。如果长度相等,那么显然P'
是另一条不同的最短路径。否则,P
是唯一的最短路径
如果我们想找到所有的最短路径
这样的算法必然是指数时间。这是因为一个图在两个节点之间可以有成倍多的相等代价路径。例如,考虑图表:
A --> B1 --> C --> D1 --> E ...
\ -> \ ->
-> B2 / -> D2 /
从
A
到E
有4条路径,如果我们假设所有边的成本相等,那么所有这些路径的总成本都相等。通过重复此模式,我们可以以指数形式获得许多成本相等的路径。替换字段prev
,使用集合prevs
链接到上一个顶点,并稍微更改代码:
...
if( w.dist >= v.dist + cvw ) {
if ( w.dist > v.dist + cvw ) {
w.dist = v.dist +cvw;
w.prevs.clear();
}
w.prevs.add(v);
pq.add( new Path( w, w.dist ) );
}
...
您是只想检测多条等成本路径(即返回一个布尔值),还是想列出所有等成本路径?@pkpnd我只需要一个多条最短路径的布尔值指示符,而不是所有实际路径。我认为单一的其他等成本路径方法行不通。请核实。我试过一个例子,但似乎失败了。@user248884您能描述一下失败的情况吗?请看图片。虽然P和P'有相同的边,但它不是唯一的。你只需要在P中的边上添加
epsilon
。因此在第一个图中,如果P是A->B->D,那么边BC和CD不应该添加epsilon。另外,epsilon
应该是一个很小的值,比如0.01,比任何边权重都小。另外,请参阅了解其他方法
...
if( w.dist >= v.dist + cvw ) {
if ( w.dist > v.dist + cvw ) {
w.dist = v.dist +cvw;
w.prevs.clear();
}
w.prevs.add(v);
pq.add( new Path( w, w.dist ) );
}
...