Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.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_Graph_Graph Theory_Dynamic Programming_Graph Algorithm - Fatal编程技术网

Algorithm 如何在线性时间内找到树中最短的简单路径?

Algorithm 如何在线性时间内找到树中最短的简单路径?,algorithm,graph,graph-theory,dynamic-programming,graph-algorithm,Algorithm,Graph,Graph Theory,Dynamic Programming,Graph Algorithm,这是Vazirani的算法书中的一个问题 这个问题的输入是一个边上有整数权重的树T。权重可能为负数, 零,或正。给出了求T中最短简单路径的线性时间算法 路径是路径中边的权重之和。如果没有重复顶点,则路径很简单。注 路径的端点不受约束 提示:这与在树中查找最大独立集的问题非常相似 如何在线性时间内解决这个问题 这是我的算法,但我想知道它是否是线性时间,因为它与深度优先没有什么不同: 遍历树(深度优先) 保留索引(节点) 添加值 直到树的尽头 比较总和并打印路径和总和 这个问题与此类似,但没有确定的

这是Vazirani的算法书中的一个问题

这个问题的输入是一个边上有整数权重的树T。权重可能为负数, 零,或正。给出了求T中最短简单路径的线性时间算法 路径是路径中边的权重之和。如果没有重复顶点,则路径很简单。注 路径的端点不受约束

提示:这与在树中查找最大独立集的问题非常相似

如何在线性时间内解决这个问题

这是我的算法,但我想知道它是否是线性时间,因为它与深度优先没有什么不同:

  • 遍历树(深度优先)
  • 保留索引(节点)
  • 添加值
  • 直到树的尽头
  • 比较总和并打印路径和总和

  • 这个问题与此类似,但没有确定的答案。

    这个问题几乎等同于,可以通过动态规划以类似的方式解决

    我们将使用DF搜索计算以下数组:

    dw1[i] = minimum sum achievable by only using node i and its descendants.
    pw1[i] = predecessor of node i in the path found for dw1[i].
    dw2[i] = second minimum sum achevable by only using node i and its descendants,
             a path that is edge-disjoint relative to the path found for dw1[i].
    
    如果可以计算这些值,则取
    min(dw1[k],dw1[k]+dw2[k])
    所有
    k
    。这是因为您的路径将采用以下基本形状之一:

      k              k
      |     or     /   \
      |           /     \
      | 
    
    所有这些都包含在我们的金额中

    计算dw1

    从根节点运行DFS。在DFS中,跟踪当前节点及其父节点。在每个节点上,假设其子节点是
    d1、d2、。。。dk
    。然后
    dw1[i]=min(min{dw1[d1]+成本[i,d1],dw1[d2]+成本[i,d2],…,dw1[dk]+成本[i,dk]},min{cost[i,dk]}
    。为叶节点设置
    dw1[i]=0
    。不要忘记用所选的前置程序更新
    pw1[i]

    计算dw2

    从根节点运行DFS。对
    dw1
    执行相同的操作,除了从节点
    i
    转到其子节点
    k
    时,如果
    pw1[i]!=k
    。但是,您可以为所有子级递归调用该函数。它在伪代码中看起来像这样:

    df(node, father)
        dw2[node] = inf
        for all children k of node
            df(k, node)
    
            if pw1[node] != k
                dw2[node] = min(dw2[node], dw1[k] + cost[node, k], cost[node, k])
    

    瓦齐拉尼近似书?我不明白这个问题,树上的每一条边都是路径,最小的边都是最短路径,你们能用这个来澄清我吗,或者用谷歌搜索一下问题的确切名称吗?你是说寻找最短路径树吗?或者树根?@Saeed-最小的边不一定是最短的路径,因为你可以有负的权重。那么空路径呢?它是最短的,不是吗?对于路径应该包含什么,您没有提出任何要求。这没有意义。@Tomas的空路径的权重为零。由一条负权重边组成的路径更短。提示说,这个问题与在树中找到最大的独立集有关。对这意味着什么有什么想法吗?看起来很有希望,但我有一些建议:(1)在“计算dw1”下,当你说“后代”时,我相信你指的是“孩子”(“后代”通常递归地指所有孩子和孩子的孩子);(2)
    dw1[i]
    dw2[i]
    up[i]
    的计算应在
    min{…}
    操作中包含0,以允许路径终止于此(例如,不包含负长度边的树将返回0分);(3) 我相信您对dw2[I]的计算应该排除最佳前沿。。。。。。仅从顶点
    i
    ,但较低级别应包括最佳边(询问是否需要澄清);(4)
    up[i]
    计算可以通过注意每个路径都有两种类型中的一种来简化:要么是“直下”路径,要么是包含“最上角”(顶点v使v的父节点不在路径中)——通过考虑
    dw1[v]+dw2[v]
    ,可以找到在某些顶点v包含最上角的任何路径,因此,
    up[i]
    只需计算返回根目录的直线路径上的成本(即,
    up[i]
    将是以
    i
    结尾的“直线路径”的最低成本)。@j_random\u hacker-我刚刚意识到,当你写下评论并将其删除时:)。是否需要将
    dw2[k]
    置于最低限度?它永远不会小于
    dw1[k]
    。不久前,我解决了一个问题,它会询问诸如
    包含q的最短路径是什么?
    ,因此我开始使用
    up
    。但要知道这里不需要它。@becko:恐怕我看不出有什么联系。。。我知道树中的独立集可以用一种大致相似的方法求解,方法是为每个具有DFS的节点计算2个值:在使用节点I的以节点I为根的子树中最大独立集的大小,以及在不使用节点I的以节点I为根的子树中最大独立集的大小。分别称之为x(i)和y(i)。然后你可以通过为i的每个子j取1+和(y(j))来计算x(i),也可以通过为i的每个子j取和(x(j))来计算y(i)。@becko:刚刚注意到一个错误!对于i的每个子j,y(i)应该是总和(max(x(j),y(j)),因为我们只想允许,而不是要求子元素包含在独立集中。