使用改进的弗洛伊德战争打印最短路径黑白给定节点
Printing shortest path b/w given nodes using modified floyd warshall
我阅读了维基百科给出的方法,通过修改弗洛伊德·沃歇尔算法在图表中打印短路径黑白两个给定点。我对此进行了编码,但它并没有真正给出预期的输出:
-
将
minimumDistanceMatrix[i][j]
中的所有元素初始化为图形中的相应权重,将矩阵中的所有元素初始化为 -1shortestPathCalculatorMatrix [i][j]
。 -
然后:
// Find shortest path using Floyd–Warshall algorithm for ( unsigned int k = 0 ; k < getTotalNumberOfCities() ; ++ k) for ( unsigned int i = 0 ; i < getTotalNumberOfCities() ; ++ i) for ( unsigned int j = 0 ; j < getTotalNumberOfCities() ; ++ j) if ( minimumDistanceMatrix[i][k] + minimumDistanceMatrix[k][j] < minimumDistanceMatrix[i][j] ) { minimumDistanceMatrix[i][j] = minimumDistanceMatrix[i][k] + minimumDistanceMatrix[k][j]; shortestPathCalculatorMatrix [i][j] = k; }
-
然后:
void CitiesMap::findShortestPathListBetween(int source , int destination) { if( source == destination || source < 0 || destination < 0) return; if( INFINITY == getShortestPathBetween(source,destination) ) return ; int intermediate = shortestPathCalculatorMatrix[source][destination]; if( -1 == intermediate ) { pathCityList.push_back( destination ); return ; } else { findShortestPathListBetween( source, intermediate ) ; pathCityList.push_back(intermediate); findShortestPathListBetween( intermediate, destination ) ; return ; } }
PS:pathCityList
是一个向量,在调用findShortestPathListBetween
之前假定为空。在此调用结束时,此向量包含所有中间节点。
有人可以指出我可能出错的地方吗?
不迭代索引而是迭代顶点要容易得多(也更直接)。此外,每个前置顶点(通常表示为π
,而不是next
),需要指向它的前置顶点,而不是当前的临时顶点。
给定一个 |V|×|V|邻接矩阵dist
,用于距离,初始化为无穷大,以及 |V|×|V|邻接矩阵next
与指向顶点的指针,
for each vertex v
dist[v, v] ← 0
for each edge (u,v)
dist[u, v] ← w(u,v) // the weight of the edge (u,v)
next[u, v] ← u
for each vertex k
for each vertex i
for each vertex j
if dist[i, k] + dist[k, j] < dist[i, j] then
dist[i, j] ← dist[i, k] + dist[k, j]
next[i, j] ← next[k, j]
请注意,我已将三个嵌套循环更改为迭代顶点而不是索引,并且已修复最后一行以引用前一个节点而不是任何中间节点。
例如,可以在 scipy.sparse.csgraph
中找到上述看起来几乎像伪代码的实现。
路径重建从末尾开始(在下面的代码中j
),跳转到j
的前身(在next[i, j]
),直到到达i
。
function path(i, j)
if i = j then
write(i)
else if next[i, j] = NIL then
write("no path exists")
else
path(i, next[i, j])
write(j)
有点晚了,但上面的代码有缺陷....它不应该是next[i][j]=next[k][j]
但查找它的正确代码是next[i][j]=next[i][k]
在示例输入上自己尝试一下,您将了解为什么这有效以及为什么前一个是错误的
下面是实现。为什么不尝试一个问题呢! 享受CP!!
// g[][] is the graph
// next[i][j] stores vertex next to i in the shortest path between (i,j)
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(g[i][j]==0)g[i][j]=inf; // there is no edge b/w (i,j)
else next[i][j]=j; // if there is an edge b/w i and j then j should be next to i
}
}
for(int k=1;k<=n;k++){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(g[i][j]>g[i][k]+g[k][j]){
g[i][j]=g[i][k]+g[k][j];
next[i][j]=next[i][k]; // we found a vertx k next to i which further decrease the shortest path b/w (i,j) so updated it
}
}
}
}
// for printing path
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
int u=i,v=j;
print(u+" ");
while(u!=v){
u=next[u][v];
print(u+" ");
}
print("n");
}
}
相关文章:
- 内存效率表示最短路径的方法?
- 用于查找网格中最短路径的算法
- 查找最短路径算法
- BFS 打印最短路径
- 使用 Dijkstra 算法跟踪两个节点之间的最短路径
- 使用C++具有两个数字的最短路径算法.(C++)
- 使用迭代深度优先搜索算法的未加权图的最短路径
- 如何仅在 2 个节点之间获取最短路径,给定邻接列表有向图?
- 如何使用贝尔曼-福特算法返回所有具有捆绑重量的最短路径?
- 使用优先级队列查找所有与 Dijkstra 相同的最短路径
- 尝试在图形中查找最短路径时的无限循环
- C++计算有向图中的最短路径
- 使用BFS存储和打印最短路径
- 如何制作由原始图形的最短路径边组成的新图形
- 有没有一种方法可以使用弗洛伊德-沃歇尔算法给出最短路径,其中存在负权重循环而不允许重叠边缘?
- 加权图的开始和结束的最短路径
- 使 c++11 Dijkstra 实现返回最短路径
- 弗洛伊德最短路径算法C++
- Dijkstra 最短路径算法性能 std::p riority_queue VS std::set.
- 使用改进的弗洛伊德战争打印最短路径黑白给定节点