【发布时间】:2022-01-13 13:57:34
【问题描述】:
假设我们有一棵树,每个节点可以有多个孩子,而孩子可以有更多的孩子等等。
以这棵树为例:
- Node 1
- Node 1.1
- Node 1.2
- Node 1.2.1
- Node 1.2.1.1
- Node 1.2.1.2
- Node 1.2.2
- Node 1.3
- Node 1.3.1
节点 1 的深度 = 0(根)
节点 1.1、1.2、1.3 的深度 = 1 等等
对于每个节点,我想计算它可以达到的最大深度。 例如,最大节点 1。深度为 3(树的深度与节点 1.2.1.1 一样深)。而节点 1.3 最大深度 = 1(子树达到节点 1.3.1 的深度)
现在我可以做的是创建一个函数,它接受一个子树并计算到最深的节点,然后返回深度值。但这需要为每个节点调用该函数,这对我来说似乎非常低效。
我想一次性创建树并计算最大深度。
我保持代码非常简单,因为我的函数包含许多其他操作(例如在我从头开始构建树时生成新的子节点,但为简单起见,我省略了这些部分)。 但基本上,我是这样遍历树的:
def create_behavior_tree(depth, max_depth, behavior_tree)
for child in behavior_tree.children:
if depth > max_depth:
max_depth = depth
if len(child) > 0: # Expanding node
max_depth = create_behavior_tree(depth + 1, max_depth, child)
child.max_depth = max_depth # problem: stores the values in "reverse"
else: # Single node without children
child.max_depth = depth
create_behavior_tree(1, 0, Tree)
但是,当我这样做时,我无法达到外部节点的最新 max_depth 值,只能在最里面的节点内达到(因为这是递归)。 所以这将计算:节点 1 最大深度 = 0,节点 1.2 最大深度 = 1,节点 1.2.1 最大深度 = 2 等等。实际上是相反的。
那么,也许我需要在这里使用全局变量?
EDIT - 我的函数的更详细版本
def create_behavior_tree(depth, behavior_tree, children, max_tree_depth, node_count):
if depth <= max_tree_depth:
for child in children:
# add behavior node
if type(child) == Behaviour:
behavior_tree.add_children([child])
node_count += 1 # counting total nodes in tree
# add composite node
if type(child) == Composite:
# replace by behavior node (reached max tree depth)
if depth == max_tree_depth:
node = create_behaviour_node()
behavior_tree.add_children([node])
node_count += 1
else:
behavior_tree.add_children([child])
node_count += 1
# further expand behavior tree
children = create_random_children(size=3)
_, node_count = create_behavior_tree(depth + 1, node, children, max_tree_depth, node_count)
return behavior_tree, node_count
random_children = create_random_children(size=3) # Create 3 random children
root = py_trees.composites.Selector("Selector")
create_behavior_tree(1, root, random_children, 5, 0)
【问题讨论】:
-
没有全局变量!编写一个以节点为参数并返回最大值的递归函数。该节点下的深度。如果没有子节点,它应该返回 0,否则在子节点上递归调用函数的结果的 1 + max。
-
@MarkLavin 这是我最初的想法。但是,当我创建树(通过递归)时,它已经遍历了每个节点。难道不能在那个过程中一次获得这些最大值吗?
-
@ggorlen 我编辑了我的帖子。它基于 0(因此如果一个节点没有子节点,则最大深度应为 0)
标签: python algorithm recursion tree behavior-tree