Algorithm 多数树评价
考虑一个深度为h的完整三元树,由一根根连接到三个深度为h-1的完整三元树组成。有n=3^h个叶,每个叶都有一个与之关联的布尔值。每个内部节点(包括根节点)都等于其大多数子节点的值 下面是深度为2的树的示例: 给定树叶输入向量[0,0,1,0,1,0,1,0,1,1],我们希望找到树的根。为了找到根,我们可以计算所有叶和内部节点(即3^h操作)。但我们可能能够计算更少的节点。在上面的示例中,我们可以看到第一个内部节点(最左侧)的值可以在检查其前两个子节点后进行计算。类似地,在depth=1时,前两个节点足以找到树的根 我一直在考虑这个问题,但找不到解决这个问题的好办法Algorithm 多数树评价,algorithm,tree,ternary-tree,Algorithm,Tree,Ternary Tree,考虑一个深度为h的完整三元树,由一根根连接到三个深度为h-1的完整三元树组成。有n=3^h个叶,每个叶都有一个与之关联的布尔值。每个内部节点(包括根节点)都等于其大多数子节点的值 下面是深度为2的树的示例: 给定树叶输入向量[0,0,1,0,1,0,1,0,1,1],我们希望找到树的根。为了找到根,我们可以计算所有叶和内部节点(即3^h操作)。但我们可能能够计算更少的节点。在上面的示例中,我们可以看到第一个内部节点(最左侧)的值可以在检查其前两个子节点后进行计算。类似地,在depth=1时,前
import numpy as np
import random
class node:
def __init__(self):
self.low = None
self.mid = None
self.high = None
def put(self, low, mid, high):
self.low = low
self.mid = mid
self.high = high
return self
class ternary_tree:
def __init__(self, leaves, count= 0):
self.leaves = leaves
self.root = node()
self.value = None
self.count = count
def get_root(self):
self.root.put(self.leaves[0], self.leaves[1], self.leaves[2])
self.value = majority(self.root)
return self.value
def majority(node):
global ops_count
r1, r2, r3 = random.sample([node.low, node.mid, node.high], 3)
if r1 > 0:
ops_count += 1
if r2 > 0:
ops_count += 1
return 1;
elif r3 > 0:
ops_count += 1
return 1;
else:
return 0;
else:
ops_count += 1
if r2 == 0:
ops_count += 1
return 0;
elif r3 == 0:
ops_count += 1
return 0;
else:
return 1;
if __name__ == "__main__":
h = 2 # depth of the tree
my_leaves = [random.randint(0,1) for i in range(0, 3**h)] #input vector
ops_count = 0 #Counting the number of steps
nb_trees = len(my_leaves) // 3
my_trees = [ternary_tree(leaves=my_leaves[i:i+3]) for i in range(0, nb_trees)]
new_leaves = []
t1, t2, t3 = random.sample(my_trees, 3)
new_leaves.append(t1.get_root())
new_leaves.append(t2.get_root())
if new_leaves[0] == new_leaves[1]:
new_leaves.append(new_leaves[0])
else:
new_leaves.append(t3.get_root())
ternary_tree(leaves=new_leaves).get_root()
我认为代码可以完成这项工作,但它不是最优的,因为它仍然检查所有内部节点,并且不跳过冗余节点。我认为正确的方法是使用递归算法,比如二叉搜索树,但我无法将BST与多数树求值联系起来
如果你能告诉我如何解决这个问题,我将不胜感激。谢谢
这个例子来自这里:。事实上,递归将是找到根值的方法。我真的不认为有必要创建树数据结构:当所有叶值的值作为列表输入时,我们就真的有了合适格式的所有信息 以下是当只给出叶值列表时,
多数
函数的外观:
import random
def majority(leaves):
counter = 0
def recur(start, size):
nonlocal counter
if size == 1:
counter += 1 # about to access a leaf's value
return leaves[start]
size //= 3
# Randomly choose which child we will leave as "plan B" in case
# two others give opposite values
last = random.randint(0, 2)
# Get the values of the two other children, using recursion
val1 = recur(start + ((last+1)%3)*size, size)
val2 = recur(start + ((last+2)%3)*size, size)
# If equal, we do not need to retrieve the remaining child's value
if val1 == val2:
return val1
# Too bad,... we need the value of the third child to break the tie
return recur(start + last*size, size)
rootval = recur(0, len(leaves))
return rootval, counter
你可以这样称呼它:
h = 2
leaves = [random.randint(0,1) for i in range(0, 3**h)]
rootval, counter = majority(leaves)
print("The leaves are {}".format(leaves))
print("Accessed {} leaves to find that root's value is {}".format(counter, rootval))
事实上,递归将是找到根值的方法。我真的不认为有必要创建树数据结构:当所有叶值的值作为列表输入时,我们就真的有了合适格式的所有信息 以下是当只给出叶值列表时,
多数
函数的外观:
import random
def majority(leaves):
counter = 0
def recur(start, size):
nonlocal counter
if size == 1:
counter += 1 # about to access a leaf's value
return leaves[start]
size //= 3
# Randomly choose which child we will leave as "plan B" in case
# two others give opposite values
last = random.randint(0, 2)
# Get the values of the two other children, using recursion
val1 = recur(start + ((last+1)%3)*size, size)
val2 = recur(start + ((last+2)%3)*size, size)
# If equal, we do not need to retrieve the remaining child's value
if val1 == val2:
return val1
# Too bad,... we need the value of the third child to break the tie
return recur(start + last*size, size)
rootval = recur(0, len(leaves))
return rootval, counter
你可以这样称呼它:
h = 2
leaves = [random.randint(0,1) for i in range(0, 3**h)]
rootval, counter = majority(leaves)
print("The leaves are {}".format(leaves))
print("Accessed {} leaves to find that root's value is {}".format(counter, rootval))
需要实际创建树数据结构吗?不需要。需要实际创建树数据结构吗?不需要。谢谢!我必须在我的递归思维上多做一些工作。现在我看到了你的解决方案,看起来很简单。我会继续练习的。非常感谢!我必须在我的递归思维上多做一些工作。现在我看到了你的解决方案,看起来很简单。我会继续练习。