我读了Wikipedia给出的方法,通过修改Floyd Warshall算法,在图中的两个给定点打印短路径b / w。我编写了这个,但它并没有真正给出预期的输出:
将minimumDistanceMatrix[i][j]
中的所有元素初始化为图表中的各个权重,将矩阵shortestPathCalculatorMatrix [i][j]
中的所有元素初始化为-1。
然后:
// 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 ;
}
}
P.S:pathCityList
是一个向量,在调用findShortestPathListBetween
之前假定为空。在此调用结束时,此向量包含其中的所有中间节点。
有人可以指出我可能出错的地方吗?
答案 0 :(得分:8)
更容易(也更直接)不迭代索引而是遍历顶点。此外,每个前任(通常表示为π
,而不是next
),需要指向它的前任,而不是当前的临时顶点。
给出| V |×| V |邻接矩阵dist
用于距离,初始化为无穷大,以及| V |×| V |邻接矩阵next
to to vertters to vertices,
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)
答案 1 :(得分:0)
有点晚了,但是上面的代码还是有缺陷的....不应是next[i][j]=next[k][j]
,但是找到它的正确代码是next[i][j]=next[i][k]
在示例输入中自己尝试一下,您将了解为什么它起作用以及为什么前一个输入错误
答案 2 :(得分:0)
这是下面的实现。 Why don't try a problem on it!享受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");
}
}