Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm Floyd Warshall算法,允许最大步长_Algorithm_Dynamic Programming_Shortest Path_Floyd Warshall - Fatal编程技术网

Algorithm Floyd Warshall算法,允许最大步长

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) 我相信这可以通过不同的数据结构来实现(一

在求解具有n个节点的有向加权图的最短路径问题时,是否可以修改Floyd-Warshall算法,使每个最短路径的步数不超过m?更准确地说,对于每对节点i和j,您将找到从i到j的最短有向路径,其中包含的节点不超过m个。时间复杂度是否仍然保持O(n3)?

是和是

  • 算法的每次迭代都会添加一个单位长度的搜索路径。因此,如果您将迭代次数限制为m,那么您将找到一条长度最多为m的路径
  • 在m->n的最坏情况下,复杂度将保持O(n^3)。然而,更精确的估计是O(m*n^2)

我相信这可以通过不同的数据结构来实现(一种允许您跟踪步骤数的数据结构)

由于Floyd Warshall通常使用连通矩阵(其中矩阵[j][k]表示节点j和k之间的距离),因此我们不必将该矩阵设置为整数,而可以将其设置为具有两个整数的结构:两个节点之间的距离和它们之间的步数

在C++中我写了一些东西来解释我的意思:< /P>
#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条边计算所有最短路径:)