Floyd算法之个人见解

Floyd算法之个人见解

  因为最近有一个算法作业要交- -,我看了看题目,大致就是带权值求最短路径。所以我想到了弗洛伊德算法,我就去看了看百度,然后做个总结吧。
  假如我们去旅游,肯定希望少走冤枉路,那么我们就要知道任何两个地方最短的距离。
在这里插入图片描述
  这四个地方,有八条公路可以到达,请注意这些公路是单向的。我们现在需要求任意两个城市之间的最短路程,也就是求任意两个点之间的最短路径。这个问题这也被称为“多源最短路径”问题。
  现在我们需要一个二维数组来储存它,可以创建一个4*4矩阵,比如1号城市到2号城市的路程为2,则设e[1][2]的值为2。2号城市无法到达4号城市,则设置e[2][4]的值为∞。另外此处约定一个城市自己是到自己的也是0,例如e[1][1]为0,具体如下。在这里插入图片描述
  我们知道,如果要缩短两点的距离就只有引入中转点(顶点k)使其路程变短(即a->k->b),有时候可能要两个中转点或者更多的点才会让其路程变得更短,也就是引入k1、k2、k3等等(即a->k1->k2…->k->i…->b),例如上图,原来4->3路程是12,如果经过1之后变成4->1->3那么路程就变成了11了(即e[4][1]+e[1][3]=5+6=11)。所以现在将问题转化成一般情况。

  • 不经过别的中转点
    在这里插入图片描述
  • 经过中转点1
      只经过中转点1应该怎么求呢?只需判断e[i][1]+e[1][j]是否比e[i][j]要小即可,e[i][j]表示的是从i号顶点到j号顶点之间的路程。e[i][1]+e[1][j]表示的是从i号顶点先到1号顶点,再从1号顶点到j号顶点的路程之和。代码实现如下。
for (i = 1; i <= n; i++)
{
    
    
     for (j = 1; j <= n; j++)
      {
    
    
      	  //循环是遍历整个矩阵,判断每个点经过1是否会变小
          if (e[i][j] > e[i][1] + e[1][j])
              e[i][j] = e[i][1] + e[1][j];
      }
}

经过1之后,路程表更新为:
在这里插入图片描述
  通过上图我们可以发现,标白的三个地方的路程经过1到其他点的路程变短了。

  • 经过1、2中转点
      接下来只循序经过1、2会怎么样呢?我们需要在只允许经过1号顶点时任意两点的最短路程的结果下,再判断如果经过2号顶点是否可以使得i号顶点到j号顶点之间的路程变得更短。即判断e[i][2]+e[2][j]是否比e[i][j]要小,代码实现为如下。
//经过1号顶点
for(i=1;i<=n;i++)
{
    
    
	for(j=1;j<=n;j++)
	{
    
    
		if (e[i][j] > e[i][1]+e[1][j])  e[i][j]=e[i][1]+e[1][j];
	}
}

//经过2号顶点
for(i=1;i<=n;i++)
{
    
    
	for(j=1;j<=n;j++)
	{
    
    
		if (e[i][j] > e[i][2]+e[2][j])  e[i][j]=e[i][2]+e[2][j];
	}
}

  在只允许经过1和2号顶点的情况下,任意两点之间的最短路程更新为:
在这里插入图片描述
  我们可以发现之前的4->3经过1(4->1->3)变成了11,现在又经过了2(4->1->2->3)变成了10,

  • 经过1、2、3中转点
      同理,继续在只允许经过1、2和3号顶点进行中转的情况下,求任意两点之间的最短路程。任意两点之间的最短路程更新为:
    在这里插入图片描述
  • 经过所有中转点
      最后允许通过所有顶点作为中转,任意两点之间最终的最短路程为:
    在这里插入图片描述
    整个过程其实可以简化为几行代码:
for(k=0; k<n ; k++){
    
     //简单的说就是更新二维矩阵,将任何一个点经过任何一个中间点之后的路程更新为最短的距离
                            //一句话概括就是:从i号顶点到j号顶点只经过前k号点的最短路程。
        for(i =0; i<n; i++){
    
    
        for(j=0; j<n; j++){
    
    
            if(e[i][j] > (e[i][k] + e[k][j])){
    
     
                e[i][j] = e[i][k] + e[k][j];
            }
        }
    }
    }

  上面就是经过所有的中转点,求的到任意点最短的距离。简单的说就是从i号顶点到j号顶点只经过前k号点的最短路程。

猜你喜欢

转载自blog.csdn.net/qq_45125250/article/details/109791793