繁体   English   中英

用于极小极大的 Python n 元树

[英]Python n-ary tree for minimax

作为一个编码项目,我希望在我已经实现的基于文本的 Connect4 python 游戏中为用户提供某种人工智能。 我研究了最常用的方法,minimax 是主要使用的算法。

如果我对算法的理解是正确的,我必须实现一个 7 叉树,其中每个节点都有一个棋盘状态和一个玩家可以从该棋盘状态进行的所有可能移动的 7 个子节点。

为了实现这棵树,我决定使用一个 Node 类,它有一个子节点列表和一个当前状态。 该树将只有 3 个级别,因为根据我的理解,没有必要保留整个游戏的完整日志。

节点类很简单:

    class _Node(object):
    def __init__(self, state, children=[]):
        self.state = state
        self.children = children

而 DecisionTree 类是一个将根设置为 None 的构造函数。

但是,我想了解add()方法如何用于这种 n 叉树。 我写的代码是这样的:

    def add(self, state):
    if (self.root == None): 
        self.root = self._Node(state[0]) # state is a singleton list, make that state the root
    else:
        for i in range(len(self.root.children) + 1): # loop over all children of root
            curr = self.root
            while (curr.children != []): # go down in tree until we reach a leaf
                curr = curr.children
            for i in range(len(state)): # add all the new states
                curr.children.append(state[i])

我的问题是 while 循环,它显然不能正常工作。 它从我想要的一个节点变成了一个列表。 我想我必须索引孩子,因此将索引作为参数。 但是,索引 n 元树会变得混乱。 这怎么处理? 一般来说,使用列表是一个坏主意吗?

首先,要小心这个def __init__(..., children=[]):

如果你会以这种方式初始化你的节点children节点,那么像这样的代码......

a = Node(1)
b = Node(2)
print(a.children, b.children)

a.children.append(3)
print(a.children, b.children)
print(a.children is b.children) # they both point to same object in memory.

将产生这个输出:

[] []
[3] [3]
True

发生这种情况是因为您在构造函数中提供了空列表值,并且该默认值在所有实例之间共享。 换句话说,在用这个[]默认子值初始化几个节点后,不同节点的子节点将指向内存中的同一个列表。

正确的方法是这样做:

class Node(object):
    def __init__(self, state, children=None):
        self.state = state
        self.children = children or []

尝试先解决这个问题,看看是否有帮助。

现在关于主要问题。 我认为,您可以在此处使用列表,但使用 while 循环遍历树不是jedi-path 我们可以在这里使用递归。

一般来说,我不明白为什么你需要 root,但要穿越树并添加值,你可以执行以下操作:

class Node(object):
    def __init__(self, state, children=None):
        self.state = state
        self.children = children or []

    def add(self, state):
        if self.children:
            for node in self.children: # loop over all children of root
                node.add(state)            # add all the new states
        else:
            self.state.extend(state) 

例子:

r = Node([3])
r.children = [Node([2]),Node([4]),Node([5])]
print(r.children[0].state)

r.add([25,14])
print(r.children[2].state)

# output will be
[2]
[5, 25, 14]

暂无
暂无

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

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