【问题标题】:Create Tree Given Component Nodes and Operators给定组件节点和运算符创建树
【发布时间】:2018-11-26 03:43:14
【问题描述】:

对于树形数据结构来说还是很陌生的。我得到了 2 个变量 rulesoperators。它们中的每一个都是字符串列表。例如:

op = ['&',"|","&"]
rules = ['a','b','c','d']

len(op) 必须始终等于 len(rules)-1,因为 op 始终连接规则或另一个 op

所以在上面,一个可能的树是:

     "|"
   /      \
"&"        "&"
 |  \      |   \
 "a" "b"  "c"  "d"

另一种可能是

         "&"
       /     \
     "|"      "d"
   /      \
"&"        "c"
 |  \     
 "a" "b"  

一棵无效的树:

"c"
 |   \
"|"  "d"

上面的树是无效的,因为上面的另一个运算符不能是规则。

现在随着规则和运算符数量的增加,树的组合将会无穷无尽。我的问题是是否可以随机生成上述树?有这个算法吗?更具体地说,如果您知道节点和叶子必须是什么,有没有办法随机创建二叉树?

谢谢

【问题讨论】:

  • 如果你知道节点和叶子必须是什么,那么随机性从何而来?
  • 在问题中提到的树结构中

标签: python algorithm tree binary-tree


【解决方案1】:

我能想到这个:

1- 打乱你的规则:例如['a','b','c','d'] -> ['c','a','b','d'] (或者如果您可以重复和“丢失”规则,只需随机选择,例如具有所需长度的['c','d','b','b','d']

2- 使列表中的每个规则成为“单例”树(即只是一片叶子),例如'a' -> Tree('a', None, None)

3- 在range(len(rules)-1) 中选择一个随机索引i

4- 从op 中选择一个随机运算符oper(此处相同,或者随机播放op,然后从列表中一个一个地获取元素,或者每次都独立选择一个随机运算符,具体取决于您想要什么... )

5- 将rules[i:i+2] 的两个元素替换为新的单个元素Tree(oper, rules[i], rules[i+1])

6- 从第 3 步重复直到len(rules) == 1

7- 你现在有一个随机树

【讨论】:

  • 我听不懂 5.
  • rules = [r_0, r_1, ... , r_(i-1), r_(i), r_(i+1), r_(i+2), ...] 变为rules = [r_0, r_1, ... , r_(i-1), Tree(oper, r_(i), r_(i+1)), r_(i+2), ...] (注意在这个阶段rules 已经只包含树对象,所有r_j 都是树...)
  • 我的另一个问题是,您是否有办法生成在评估时会给出有界结果的树。那是我面临的一个问题,不确定如何解决。换句话说,考虑上面的运算符取值 ['-','+','*','/'] 并且规则现在是数字或变量。我如何确保树在解决时产生有界的结果?
  • 生成、评估、检查是否在界限内,否则重复?
【解决方案2】:

这是我的解决方案。我决定将算法分成两部分。首先,我使用运算符生成了一个随机树结构。然后我通过并将终端添加到当前叶节点。

op = ['&',"|","+"]
terminals = ['a','b','c','d']

shuffle(op)
shuffle(terminals)



class tree:
    def __init__(self, l, r, v):
        self.left = l
        self.right = r
        self.value = v


root = tree(None, None, op[0])
op.pop(0)
def createNonTerminals(root):
    if len(op) == 0:
        return
    choice = randint(0,1)
    if choice == 0: #binary
        root.left = tree(None, None, op[0])
        op.pop(0)
        if len(op) > 0:
            root.right = tree(None, None, op[0])
            op.pop(0)
            createNonTerminals(root.right)
            createNonTerminals(root.left)

        else:
            createNonTerminals(root.left)
    else:
        choice = randint(0, 1)
        if choice == 1:
            root.right = tree(None, None, op[0])
            op.pop(0)
            createNonTerminals(root.right)
        else:
            root.left = tree(None, None, op[0])
            op.pop(0)
            createNonTerminals(root.left)

def addNonTerminals(root):
    if root.left == None:
        root.left = tree(None, None, terminals[0])
        terminals.pop(0)
    else:
        addNonTerminals(root.left)
    if root.right == None:
        root.right = tree(None, None, terminals[0])
        terminals.pop(0)
    else:
        addNonTerminals(root.right)  

这里是一些示例输出

['+']
['&', 'd']
['~', 'f']
['a', '-']
['e', '|']
['b', 'c']

['|']
['&', '~']
['+', '-', 'b', 'a']
['d', 'f', 'e', 'c']

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-04-28
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多