简体   繁体   English

是否有一种算法可以在有向根树(树状树)中找到最小成本路径?

[英]Is there an algorithm to find the minimum cost path in a directed rooted tree (arborescence)?

To be more specific : I have a rooted tree which represents the different paths of a matrix from its first element to its last, with only right, down and diagonal down movements allowed.更具体地说:我有一个有根的树,它表示矩阵从第一个元素到最后一个元素的不同路径,只允许向右、向下和对角向下移动。 Hence, every node can have up to 3 children.因此,每个节点最多可以有 3 个子节点。 The tree will have the first element of the matrix as its root and every last node will be the last element of the matrix.树将矩阵的第一个元素作为其根,每个最后一个节点将是矩阵的最后一个元素。 Every node represents a cost.每个节点代表一个成本。

Here's an example of what kind of tree I'm talking about :这是我正在谈论的树类型的示例: 在此处输入图片说明

Here the minimum cost path would be : 1 -> 2 -> 9 or [0,0,2] in "coordinates"这里的最小成本路径是:“坐标”中的1 -> 2 -> 9[0,0,2]

So is there any algorithm that is able to find the minimum cost path (I mean the path not the total cost of the minimum cost path) for this kind of tree ?那么是否有任何算法能够找到这种树的最小成本路径(我的意思是路径而不是最小成本路径的总成本)?
And if yes, is it possible to implement it in a recursive way ?如果是,是否可以以递归方式实现它?

This can be done in O( n ) time, where n is the number of nodes.这可以在 O( n ) 时间内完成,其中n是节点数。 The solution is recursive:解决方案是递归的:

  • The minimum cost path for a leaf node is trivial - it is just the node itself, with the node's own cost.叶节点的最小成本路径是微不足道的——它只是节点本身,具有节点自己的成本。

  • To find the minimum cost path for an internal node, make recursive calls on all its children, and select whichever child node has the lowest cost for its minimum cost path.要找到内部节点的最小成本路径,对其所有子节点进行递归调用,并为其最小成本路径选择成本最低的子节点。 The cost of the path equals the node's own cost plus the cost of the path for that child.路径的成本等于节点自身的成本加上该子节点的路径成本。

To recover the path, simply return both the cost and the path from the function.要恢复路径,只需从函数中返回成本和路径。 The recursive case has to extend the path with the current node.递归情况必须使用当前节点扩展路径。

The total running time is O( n ) because the non-recursive work done for an internal node is proportional to the number of children.总运行时间为 O( n ),因为为内部节点完成的非递归工作与子节点的数量成正比。 The running time cannot be improved on asymptotically, but it could be optimised in practice using a branch-and-bound algorithm which keeps track of the lowest cost path so far, and rejecting paths which exceed it.运行时间不能渐近改进,但可以在实践中使用分支定界算法进行优化,该算法跟踪迄今为止的最低成本路径,并拒绝超过它的路径。


Here's an example in Python:这是 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

Example:例子:

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

Note that the path is returned in reverse order.请注意,路径以相反的顺序返回。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM