Algorithm Floyd Warshall算法,允许最大步长
在求解具有n个节点的有向加权图的最短路径问题时,是否可以修改Floyd-Warshall算法,使每个最短路径的步数不超过m?更准确地说,对于每对节点i和j,您将找到从i到j的最短有向路径,其中包含的节点不超过m个。时间复杂度是否仍然保持O(n3)?是和是Algorithm Floyd Warshall算法,允许最大步长,algorithm,dynamic-programming,shortest-path,floyd-warshall,Algorithm,Dynamic Programming,Shortest Path,Floyd Warshall,在求解具有n个节点的有向加权图的最短路径问题时,是否可以修改Floyd-Warshall算法,使每个最短路径的步数不超过m?更准确地说,对于每对节点i和j,您将找到从i到j的最短有向路径,其中包含的节点不超过m个。时间复杂度是否仍然保持O(n3)?是和是 算法的每次迭代都会添加一个单位长度的搜索路径。因此,如果您将迭代次数限制为m,那么您将找到一条长度最多为m的路径 在m->n的最坏情况下,复杂度将保持O(n^3)。然而,更精确的估计是O(m*n^2) 我相信这可以通过不同的数据结构来实现(一
- 算法的每次迭代都会添加一个单位长度的搜索路径。因此,如果您将迭代次数限制为m,那么您将找到一条长度最多为m的路径
- 在m->n的最坏情况下,复杂度将保持O(n^3)。然而,更精确的估计是O(m*n^2)
#define INFINITY 9999999
struct floydEdge
{
int weight;
int steps;
};
floydEdge matrix[10][10];
int main()
{
//We initialize the matrix
for(int j=0;j<10;j++)
{
for(int k=0;k<10;k++)
{
matrix[j][k].weight=INFINITY;
matrix[j][k].steps=0;
}
}
//We input some weights
for(int j=0;j<10;j++)
{
int a, b;
cin>>a>>b;
cin>>matrix[a][b].weight;
matrix[b][a].weight=matrix[a][b].weight;
matrix[a][b].steps=matrix[b][a].steps=1;
}
//We do the Floyd-Warshall, also checking for the step count as well as the weights
for(int j=0;j<10;j++)
{
for(int k=0;k<10;k++)
{
for(int i=0;i<10;i++)
{
//We check if there is a shorter path between nodes j and k, using the node i. We also check if that path is shorter or equal to 4 steps.
if((matrix[j][k].weight > matrix[j][i].weight + matrix[i][k].weight) && (matrix[j][i].steps+matrix[i][k].steps<=4))
{
matrix[j][k].weight=matrix[k][j].weight=matrix[j][i].weight + matrix[i][k].weight;
matrix[j][k].steps=matrix[k][j].steps=matrix[j][i].steps+matrix[i][k].steps;
}
//If the path is not shorter, we can also check if the path is equal BUT requires less steps than the path we currently have.
else if((matrix[j][k].weight == matrix[j][i].weight + matrix[i][k].weight) && (matrix[j][i].steps+matrix[i][k].steps<matrix[j][k].steps))
{
matrix[j][k].weight=matrix[k][j].weight=matrix[j][i].weight + matrix[i][k].weight;
matrix[j][k].steps=matrix[k][j].steps=matrix[j][i].steps+matrix[i][k].steps;
}
}
}
}
return 0;
}
#定义无限999999
结构floydEdge
{
整数权重;
int步;
};
floydEdge矩阵[10][10];
int main()
{
//我们初始化矩阵
对于(int j=0;j>b;
cin>>矩阵[a][b]。重量;
矩阵[b][a]。权重=矩阵[a][b]。权重;
矩阵[a][b]。步骤=矩阵[b][a]。步骤=1;
}
//我们做Floyd Warshall,同时检查步数和重量
对于(int j=0;j,同时,我发现了一个O(n3logm)算法,用于寻找具有n个节点的图的所有对最短路径(ASPP)问题,使得没有路径包含超过m个节点
给定两个nxn矩阵,比如A=[aij]和B=[bij],它们是nxn矩阵C=[cij]=A×B,由cij=min1定义≤K≤n{aik+bkj}
这与ASPP的关系如下。给定图中距离的加权矩阵E,En是所有对最短路径的矩阵。如果我们添加任何路径包含的节点数不超过m个的约束,那么矩阵Em就是ASPP的解。由于计算功率可以在O(logm)时间内找到,因此这给了我们一个O(n3logm)算法
,在某些特殊情况下,人们可能会发现计算矩阵距离积的更快算法,但简单的算法是O(n3)对我来说已经足够了,因为总时间几乎和Floyd Warshall接近一样快。我可能还没有弄清楚,我如何将迭代次数限制在m?你的意思是将代码的第一行从k=1的更改为n do
到k=1的到m do
?在这种情况下,复杂性会像你所说的那样降低,但只会减少gr的前m个节点在寻找每对节点之间的最短路径时会考虑aph。啊,对不起,我想到的是Bellman-Ford算法,似乎:我想不出一种方法可以在不到O(n^3m^2)的时间内完成。(本质上:使用DP来计算f(i,j,k,w)的每个值),其中此函数表示从i到j的最短路径,仅使用顶点,这对于我需要解决的问题来说速度很慢。最近,使用,我实现了m边所有对最短路径算法,在O(n^3*log(n))时间内最多有m条边。我想看看你的方法--你能把它写下来作为答案吗?(这是允许的,甚至是鼓励的。)我看不出用这种方法如何避免在运行时间中将m作为一个因子,因为每个矩阵乘法需要O(n^3)时间(或者至少O(n^2.某物),并且您可能需要多达m个。即使如此,在我的方法中这仍然可以节省m的因子。实际上,如果您是指O(n^3*log(m))然后我可以潜在地看到它是如何工作的:使用重复的平方运算将最大迭代次数从m降到log m。是这样吗?写一篇文章仍然会很棒:)是的,你是对的!:)当然,我会把它写下来作为答案。我担心这不会一直给出最佳答案:可能是对于某些顶点对j和k,即使最短路径via I需要超过4(!)步骤,还有另一条通过i的路径,它需要4个或更少的步骤,但仍然比避免的j和k之间的所有路径好,例如,假设有6个顶点j=v1、v2、i=v3、v4、v5、k=v6,每个顶点和下一个顶点之间的边为权重2,j和i之间的边为权重5,j和k之间的边为权重12。然后最短的j->k路径经过i,有5条边,总权重为10,但这条边太多,因此您的算法将忽略它和访问i的所有j->k路径,首选最短的i-避免路径,即权重为12的单条边j->k。但这忽略了总权重为11的4条边路径j->i->v4->v5->k。Nice。起初我以为这只会使用精确的m条边计算最短路径,但后来我意识到它使用精确的m条边计算最短路径,其中任意数量的边可能是成本为0的“自边”,因此它实际上使用最多m条边计算所有最短路径:)