我遇到了涉及项目树的编程问题。 问题本身只是一个较大问题的子问题(但我不会在这里发布,因为它不是真正相关的)。任何问题都是:
我正在尝试遍历树中的每个路径并计算相关值。
例如,这种情况就像在这棵树中一样:
a
b b
现在我得到的结果是乘法如下:
leave1 = a * b
leave2 = a *(1-b)
leave3 =(1-a)* b
leave4 =(1-a)*(1-b)
所以树上一层低的树叶基本上就是结果(注意它们在现实中并不存在,只是概念上的。)
现在,我想以递归方式执行此操作,但存在一些问题: 在遍历期间生成a和b的值,但是例如b的值应该仅生成一次。所有值都是0或1。 如果获取节点A的左子节点,则在乘法中使用值A.使用值1-A的正确路径。
此外,树总是完美的,即完整和平衡。
现在我拥有了(我在python中编程,但是对于这个问题我一般都对这个算法感兴趣):
def f(n):
if n == 1:
return [1]
generate value #(a, b or whatever one it is)
g = f(n/2)
h = scalarmultiply(value,g)
return h.append(g - h)
请注意,g和h是列表。
这段代码由我的一位教授给出了可能的帮助,但我认为这不符合我的要求。至少,它不会给我一个列表h的结果,每个路径都有结果。特别是,我认为它不区分b
和1-b
。我看到这个错了,我该怎么做?
我在编程方面不是很有经验,所以如果可以,请尝试解释一下: - )
答案 0 :(得分:0)
尝试这样的事情:
def f(element_count):
if element_count == 1: #<-------------------------------A
return [1,] #at the root node - it has to be 1 otherwise this is pointless
current_value = get_the_value_however_you_need_to()#<----B
result_so_far = f(element_count/2) #<-------------------C
result = []
for i in result_so_far:#<--------------------------------D
result.append(i*current_value)
result.append(i*(1-current_value))
result.append((1-i)*current_value)
result.append((1-i)*(1-current_value))
return result
以下是它的工作原理:
假设你想使用三层金字塔。然后element_count将是第三层上的元素数量,因此您可以调用f(4)
。 A处的条件失败,因此我们继续B生成下一个值。现在在C,我们打电话给f(2)
。
f(2)
中的流程类似,f(2)
调用f(1)
和f(1)
将[1,]
返回f(2)
。
现在我们开始回到树的最宽处......
我不确定你的讲师在功能结束时会得到什么。 for循环执行你解释的乘法并建立一个列表然后返回
答案 1 :(得分:0)
如果我理解正确,你想建立一个像这样的二叉树:
A
/ \
/ \
/ \
B C
/ \ / \
D E F G
其中较低级别节点的布尔值(1
,0
或它们的Python等价物,True
和False
)是根据其父级和祖父母使用以下规则:
D = A and B
E = A and not B
F = not A and C
G = not A and not C
也就是说,每个节点的右后代都会根据它的倒数来计算它们的值。您进一步声明,树由单个根值(a
)定义,另一个值用于根的两个子节点(b
)。
这是一个计算这种树的任何节点值的函数。树位置由整数索引定义,其方式与二进制堆通常相同,节点N
的父节点为N//2
,其子节点为2*N
和{{1} (根节点为2*N+1
)。它使用memoization字典来避免重复重新计算相同的值。
1
你可以通过注意祖父母的价值在计算父母的价值之后总是在备忘录词典中来略微改善表现,但是我把它留下来以便代码更清晰。
如果你需要有效地计算来自同一个树的许多值(而不仅仅是一个),你可能想在某个地方保留一个永久的备忘录字典,也许作为全局字典中的值,由def tree_value(n, a, b, memo=None):
if memo is None:
memo = {1:a, 2:b, 3:b} # this initialization covers our base cases
if n not in memo: # if our value is unknown, compute it
parent, parent_dir = divmod(n, 2)
parent_val = tree_value(parent, a, b, memo) # recurse
grandparent, grandparent_dir = divmod(parent, 2)
grandparent_val = tree_value(grandparent, a, b, memo) # recurse again
if parent_dir: # we're a right child, so invert our parent's value
parent_val = not parent_val
if grandparent_dir: # our parent is grandparent's right child, so invert
grandparent_val = not grandparent_val
memo[n] = parent_val and grandparent_val
return memo[n]
键入元组。