图论入门(七)最小生成树

转载自https://blog.csdn.net/saltriver/article/details/72568556

最小生成树:

       一个正在进行信息化建设的国家级贫困县,需要在下属9个乡镇之间架设光纤网络。为减少建设难度,光纤网主要沿着这9个乡镇之间互连的公路进行铺设。这9个乡镇之间的公路网以及相互之间的距离(单位:km)如下图所示:

       在这个实际应用中,我们的目的,是要寻求一种连接图中所有节点的、成本最低的方式。本质上,再抽象一层,这是个组合优化问题,可以使用一些智能优化算法来解决。而在这个实例上,我们寻求使用更简单的图论方式解决。

        要包含图中所有的顶点n,同时代价最少,第一个想到的自然是减少边的数量,而要连接所有n个顶点,显然至少需要n-1条边。而我们知道一颗树(tree)就是n个顶点,n-1条边。所以,这里引申出图论中的一个新概念:生成树(spanning tree)。含有图中全部n个顶点,以及包含图中某些n-1条边的一颗树是该图的生成树。有几个情况需要注意:

  • 图本身必须是无向连通图; 
    如果是非连通图,那就不存在生成树的概念。我们知道树中任意2点都是连通的。如果是有向图,那也没有这个概念。
  • 生成树不止一种; 
    生成树的n-1条边可以在图的边集合中选择,当然不止一种情况。
  • 每个生成树代价不同。 
    一般使用生成树中边的权重值总和代表每个生成树的代价。 
    而我们的工作就是要找到所有生成树中代价最小的,这就是最小生成树(minimum spanning tree)问题。

那么,我们构建最小生成树的时候,要从哪里着手呢?

首先,我们从边出发,先找到最短的边e-i。

        假设生成树不包含最短边e_i,无论移除其他边中的哪条边,重新构成新的生成树都比最先的生成树代价小,因为哪条边的代价都比边e-i的代价要大。也就是说,任何不包含最短边的生成树结构都可以被做的更小。所以,最小生成树一定包含最短边。(后面的文章我们将看到,这也是最小生成树算法Kruskal的基本思想)。

其次,我们从顶点出发。

       我们以顶点b为例,根据生成树的定义,顶点b与其它顶点肯定是连通的。而顶点b有2条边,即边a-b,边b-d。这意味着最小生成树必然包含这2条边中的一个。而边b-d比a-b要短,因此选择b-d是否更合理? 我们用反证法证明下,假设选择较长的边a-b是更好的选择,即最小生成树包含a-b这条边。我们把边b-d也加入这个生成树,形成了一个环。在这个环中,如果移除边a-b,那么得到的新生成树代价比以前的要小,这与假设的选择较长边更好相矛盾。所以在b点选择较短的边才有可能生成最小生成树。(后面的文章我们将看到,这也是最小生成树算法Prim的基本思想)。