C++ 我如何使用bellman-ford算法返回所有权重相同的最短路径?
正如标题所说,我正在寻找的是打印“所有最短路径”,这些路径由重量决定 例如: 我们有一个边从0->1->3的图,它的权重为6,但是我们也有路径0->3,它的权重为6,下面的算法只返回第一条路径,我想知道是否可以同时返回两条或所有路径。还有一种更高效/优雅的打印最短路径的方法。我只是以这段代码为例,我的代码非常相似,但只从源点打印到最后一个顶点 <>这里有一个类似的问题,但是我不懂代码,因为我熟悉C++。C++ 我如何使用bellman-ford算法返回所有权重相同的最短路径?,c++,C++,正如标题所说,我正在寻找的是打印“所有最短路径”,这些路径由重量决定 例如: 我们有一个边从0->1->3的图,它的权重为6,但是我们也有路径0->3,它的权重为6,下面的算法只返回第一条路径,我想知道是否可以同时返回两条或所有路径。还有一种更高效/优雅的打印最短路径的方法。我只是以这段代码为例,我的代码非常相似,但只从源点打印到最后一个顶点 这里有一个类似的问题,但是我不懂代码,因为我熟悉C++。 #include <iostream> #include <vector>
#include <iostream>
#include <vector>
#include <iomanip>
#include <climits>
using namespace std;
// Data structure to store graph edges
struct Edge
{
int source, dest, weight;
};
// Recurive Function to print path of given vertex v from source vertex
void printPath(vector<int> const &parent, int v)
{
if (v < 0)
return;
printPath(parent, parent[v]);
cout << v << " ";
}
// Function to run Bellman Ford Algorithm from given source
void BellmanFord(vector<Edge> const &edges, int source, int N)
{
// count number of edges present in the graph
int E = edges.size();
// distance[] and parent[] stores shortest-path (least cost/path)
// information. Initially all vertices except source vertex have
// a weight of infinity and a no parent
vector<int> distance (N, INT_MAX);
distance[source] = 0;
vector<int> parent (N, -1);
int u, v, w, k = N;
// Relaxation step (run V-1 times)
while (--k)
{
for (int j = 0; j < E; j++)
{
// edge from u to v having weight w
u = edges[j].source, v = edges[j].dest;
w = edges[j].weight;
// if the distance to the destination v can be
// shortened by taking the edge u-> v
if (distance[u] != INT_MAX && distance[u] + w < distance[v])
{
// update distance to the new lower value
distance[v] = distance[u] + w;
// set v's parent as u
parent[v] = u;
}
}
}
// Run Relaxation step once more for Nth time to
// check for negative-weight cycles
for (int i = 0; i < E; i++)
{
// edge from u to v having weight w
u = edges[i].source, v = edges[i].dest;
w = edges[i].weight;
// if the distance to the destination u can be
// shortened by taking the edge u-> v
if (distance[u] != INT_MAX && distance[u] + w < distance[v])
{
cout << "Negative Weight Cycle Found!!";
return;
}
}
for (int i = 0; i < N; i++)
{
cout << "Distance of vertex " << i << " from the source is "
<< setw(2) << distance[i] << ". It's path is [ ";
printPath(parent, i); cout << "]" << '\n';
}
}
// main function
int main()
{
// vector of graph edges as per above diagram
vector<Edge> edges =
{
// (x, y, w) -> edge from x to y having weight w
{ 0, 1, 2 }, { 1, 3, 4 }, { 0, 3, 6 }
};
// Set maximum number of nodes in the graph
int N = 5;
// let source be vertex 0
int source = 0;
// run Bellman Ford Algorithm from given source
BellmanFord(edges, source, N);
return 0;
}
#包括
#包括
#包括
#包括
使用名称空间std;
//存储图边的数据结构
结构边
{
整数来源、目的地、重量;
};
//Recrive函数从源顶点打印给定顶点v的路径
无效打印路径(向量常量和父对象,int v)
{
if(v<0)
返回;
打印路径(父,父[v]);
从更抽象的角度来看,你有一些东西可以找到一个最小的东西,你想把它改变成所有其他东西都一样小。(同样的原则也适用于寻找最大的东西。不过,坚持“最小”会使解释更简单。)
许多寻找极端事物的算法在某些部分会问“A比B更极端”。例如,您可能会看到如下代码:
if ( A < B )
smallest = A;
如何将此应用于贝尔曼福特?
幸运的是,代码的关键部分相对容易,因为有注释记录它。更难的部分是更改代码以跟踪多个结果,因为发现较短路径时会更新两条数据。看起来需要扩展的数据是parent
。下面是一个新的声明:
vector< vector<int> > parent (N);
这与一般方法稍有不同,因为没有“else
”。这是相同的逻辑,只是排列有点不同。请注意,当输入第一个if
子句时,距离向量会更新,因此第二个if
子句也会被输入
我认为处理找到的路径是一个单独的问题(不是一个简单的问题),因此我将把它留给您来解决如何更新printPath()
。不过,我将给出一个保留旧输出的版本(只是最短路径中的第一条)这与其说是一个建议,不如说是一个将新数据结构与旧数据结构联系起来的说明
// Recursive function to print the path of (just) the first given vertex from source vertex.
void printPath(vector< vector<int> > const &parent, vector<int> const &vlist)
{
if (vlist.empty())
return;
int v = vlist.front();
printPath(parent, parent[v]);
cout << v << " ";
}
//递归函数,用于从源顶点打印(仅)第一个给定顶点的路径。
无效打印路径(向量<向量>常量和父对象,向量常量和向量列表)
{
if(vlist.empty())
返回;
int v=vlist.front();
打印路径(父,父[v]);
库特
if (distance[u] != INT_MAX) {
// if the distance to the destination v can be
// shortened by taking the edge u-> v
if (distance[u] + w < distance[v])
{
// update distance to the new lower value
distance[v] = distance[u] + w;
// forget the previous parent list.
parent[v].clear();
}
// if u-> v is a way to get the shortest
// distance to the destination v.
if (distance[u] + w == distance[v])
{
// add u as a possible parent for v
parent[v].push_back(u);
}
}
// Recursive function to print the path of (just) the first given vertex from source vertex.
void printPath(vector< vector<int> > const &parent, vector<int> const &vlist)
{
if (vlist.empty())
return;
int v = vlist.front();
printPath(parent, parent[v]);
cout << v << " ";
}