【问题标题】:Is there an algorithm to find the minimum cost path in a directed rooted tree (arborescence)?有没有一种算法可以在有向根树(树状树)中找到最小成本路径?
【发布时间】:2020-04-07 11:10:07
【问题描述】:

更具体地说:我有一个根树,它表示矩阵从第一个元素到最后一个元素的不同路径,只允许向右、向下和对角线向下移动。因此,每个节点最多可以有 3 个子节点。树将以矩阵的第一个元素作为其根,每个最后一个节点将是矩阵的最后一个元素。每个节点代表一个成本。

下面是我所说的树的示例:

这里的最低成本路径是:1 -> 2 -> 9[0,0,2] 在“坐标”中

那么是否有任何算法能够找到这种树的最小成本路径(我的意思是路径不是最小成本路径的总成本)?
如果是的话,是否有可能以递归方式实现它?

【问题讨论】:

    标签: algorithm path tree minimum directed-graph


    【解决方案1】:

    这可以在 O(n) 时间内完成,其中 n 是节点数。解决方案是递归的:

    • 叶节点的最小成本路径是微不足道的 - 它只是节点本身,具有节点自己的成本。

    • 要找到内部节点的最低成本路径,请对其所有子节点进行递归调用,然后选择成本最低的子节点作为其最低成本路径。路径的成本等于节点自身的成本加上该子节点的路径成本。

    要恢复路径,只需从函数中返回成本和路径即可。递归情况必须用当前节点扩展路径。

    总运行时间为 O(n),因为为内部节点完成的非递归工作与子节点的数量成正比。运行时间无法渐近改善,但可以在实践中使用branch-and-bound algorithm 进行优化,该branch-and-bound algorithm 跟踪迄今为止成本最低的路径,并拒绝超过它的路径。


    这是一个 Python 示例:

    class Node:
        def __init__(self, cost, children=()):
            self.cost = cost
            self.children = children
        def __repr__(self):
            return 'Node({})'.format(self.cost)
    
    root = Node(1, (
        Node(2, (
            Node(5, (Node(9),)),
            Node(6, (Node(9),)),
            Node(9),
        )),
        Node(3, (
            Node(8, (Node(9),)),
            Node(9),
        )),
        Node(4, (Node(9),)),
    ))
    
    def min_cost_path(node):
        if not node.children:
            return [node], node.cost
        else:
            # list of (path, cost) pairs
            options = [min_cost_path(c) for c in node.children]
            path, cost = min(options, key=lambda option: option[1])
            path.append(node)
            return path, cost + node.cost
    

    例子:

    >>> path, cost = min_cost_path(root)
    >>> path
    [Node(9), Node(2), Node(1)]
    >>> cost
    12
    

    注意路径是以相反的顺序返回的。

    【讨论】:

    • 难以置信!现在看起来很简单...... Python 的例子很有帮助。非常感谢。
    • 很高兴为您提供帮助。既然你提到这些是矩阵中的路径,我假设成本 9 的节点都代表同一个矩阵单元;在这种情况下,您可以将其建模为有向无环图而不是树,并且无需多次重新计算相同矩阵单元的路径/成本;您可以将结果缓存在节点对象本身中,并返回缓存的结果(如果存在)。这大大减少了大型矩阵的运行时间,其中有许多路径到达相同的单元格。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多