Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.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 正确性证明:图论中树的直径算法_Algorithm_Tree_Graph Theory_Proof Of Correctness - Fatal编程技术网

Algorithm 正确性证明:图论中树的直径算法

Algorithm 正确性证明:图论中树的直径算法,algorithm,tree,graph-theory,proof-of-correctness,Algorithm,Tree,Graph Theory,Proof Of Correctness,为了找到一棵树的直径,我可以从树上取任何节点,执行BFS以找到离它最远的节点,然后在该节点上执行BFS。距离第二个BFS的最大距离将产生直径 不过,我不知道如何证明这一点?我曾尝试在节点数量上使用归纳法,但这种情况太多了 任何想法都将不胜感激……让我们将第一个BFS发现的端点称为x。关键的一步是证明在第一步中找到的x总是“有效的”——也就是说,它总是在某条最长路径的一端。(请注意,通常可以有多条同样长的路径。)如果我们能够确定这一点,那么很容易看到根在x的BFS将找到距离x尽可能远的某个节点,因

为了找到一棵树的直径,我可以从树上取任何节点,执行BFS以找到离它最远的节点,然后在该节点上执行BFS。距离第二个BFS的最大距离将产生直径

不过,我不知道如何证明这一点?我曾尝试在节点数量上使用归纳法,但这种情况太多了


任何想法都将不胜感激……

让我们将第一个BFS发现的端点称为x。关键的一步是证明在第一步中找到的x总是“有效的”——也就是说,它总是在某条最长路径的一端。(请注意,通常可以有多条同样长的路径。)如果我们能够确定这一点,那么很容易看到根在x的BFS将找到距离x尽可能远的某个节点,因此该节点必须是一条总的最长路径

提示:假设(相反)在两个顶点u和v之间有一条较长的路径,这两个顶点都不是x

请注意,在u和v之间的唯一路径上,必须有一些最高(最接近根)顶点h。有两种可能性:要么h在从BFS根到x的路径上,要么不是。通过将u-v路径中的某些路径段替换为x路径,说明在这两种情况下,u-v路径的长度至少可以与x路径的长度相同

[编辑]实际上,可能根本不需要单独治疗这两个病例。但我经常发现将一个配置分解成几个(甚至许多)情况,并分别处理每个情况更容易。这里,h位于从BFS根到x的路径上的情况更容易处理,并为另一种情况提供了线索

[EDIT 2]稍后再回到这里,我认为现在需要考虑的两种情况是:(i)u-v路径与从根到x的路径相交(在某个顶点y处,不一定在u-v路径的最高点h处);(ii)它没有。我们仍然需要h来证明每个案例。

我会解决的。设
s,t
为最大距离对。设
u
为任意顶点。我们有一个类似的示意图

    u
    |
    |
    |
    x
   / \
  /   \
 /     \
s       t ,
其中,
x
s,t,u
的连接点(即位于这些顶点之间的三条路径上的唯一顶点)

假设
v
是距离
u
最大的顶点。如果示意图现在看起来像

    u
    |
    |
    |
    x   v
   / \ /
  /   *
 /     \
s       t ,
    u
    |
    *---v
    |
    x
   / \
  /   \
 /     \
s       t .
然后

现在,


d(u,s)这里有另一种看待它的方式:

假设G=(VE)是一个非空的有限树,其顶点集V和边集E

考虑以下算法:

  • 让计数=0。让E中的所有边最初都不着色。让C最初等于V
  • 考虑V的子集V,该子集包含恰好有一条未着色边的所有顶点:
    • 如果V”为空,则让d=count*2并停止
    • 如果V'正好包含两个元素,则将它们的相互(未着色)边涂成绿色,让d=count*2+1,然后停止
    • 否则,V”至少包含三个顶点;进行如下工作:
  • 按一递增计数
  • C中删除没有未着色边的所有顶点
  • 对于具有两条或多条未着色边的V中的每个顶点,将其每个绿色边重新着色为红色(某些顶点可能没有此类边)
  • 对于V'中的每个顶点,将其未着色边染成绿色
  • 返回到步骤(2)
  • 这基本上是将图形从叶子向内着色,用绿色标记到叶子的最大距离的路径,用红色标记那些距离较短的路径。同时,C的节点,即到一片叶子的最大距离较短的中心节点,被削掉,直到C只包含到一片叶子的最大距离最大的一个或两个节点

    通过构造,从叶顶点到其最近中心顶点(仅穿过绿色边)的所有简单路径的长度(计数)相同,而从叶顶点到其最近中心顶点(至少穿过一条红色边)的所有其他简单路径的长度较短。此外,可以证明:

    • 该算法总是在给定的条件下终止,将G的每一条边都涂成红色或绿色,并将C保留一个或两个元素
    • 在算法终止时,d是G的直径,以边为单位测量
    • 给定v中的顶点v,从v开始的G中的最大长度简单路径正是那些包含中心的所有顶点、终止于叶子并仅在中心和远端端点之间穿过绿色边的路径。这些从v穿过中心,到离中心最远的一片叶子

    现在考虑你的算法,这可能是更实际的,鉴于上述。从任何顶点v开始,该顶点正好有一条简单路径p,以中心顶点结束,并包含中心的所有顶点(因为G是一棵树,如果C中有两个顶点,则它们共享一条边)。可以看出,以v为一个端点的G中的最大简单路径都具有p的并集形式,从中心到叶的简单路径仅穿过绿色边

    我们的目的的关键点是,另一个端点的传入边必须是绿色的。因此,当我们搜索从那里开始的最长路径时,我们可以访问那些只穿过绿色边缘的路径
        u
        |
        *---v
        |
        x
       / \
      /   \
     /     \
    s       t .
    
    d(u, s) <= d(u, v) <= d(u, x) + d(x, v)
    d(u, t) <= d(u, v) <= d(u, x) + d(x, v)
    
    d(s, t)  = d(s, x) + d(x, t)
             = d(u, s) + d(u, t) - 2 d(u, x)
            <= 2 d(x, v)
    
    2 d(s, t) <= d(s, t) + 2 d(x, v)
               = d(s, x) + d(x, v) + d(v, x) + d(x, t)
               = d(v, s) + d(v, t),