简体   繁体   English

如何在Python中创建树结构?

[英]How can I create a tree structure in Python?

I'm trying to make an AI that plays a game that looks a lot like checkers, the logic is pretty much the same. 我正在尝试使AI能够玩看起来像跳棋的游戏,其逻辑几乎相同。 Anyway I'm looking to use Monte Carlo Tree Search method but I have no idea of how to implement the tree structure. 无论如何,我正在寻找使用蒙特卡洛树搜索方法的方法,但是我不知道如何实现树形结构。 If I'm not wrong the root of my tree should be the initial state or board and the nodes should be all the possible plays. 如果我没记错的话,我的树的根应该是初始状态或板,而节点应该是所有可能的游戏。 I know I have to create a function to calculate the weight of each node and select the best possible play. 我知道我必须创建一个函数来计算每个节点的权重并选择最佳播放。 My problem is, as I said before, that I have no clue as to how I can implement said tree in python. 我的问题是,正如我之前所说,我不知道如何在python中实现所述树。

So far I have my board and two functions that return a list of the legal moves you can make. 到目前为止,我已经有了董事会和两个职能部门,可返回您可以采取的法律行动清单。 The board was created with a 10x10 multidimensional array and to find the possible moves I have two functions that receive the X and Y coordinate of the piece I want to move and check all the available options. 木板是用10x10多维数组创建的,为了找到可能的移动,我有两个功能可以接收要移动的工件的X和Y坐标,并检查所有可用选项。 The reason why I have 2 move functions is because one functions serves for basic movements ie when the space right next to you is adjacent, while the other function checks for "hops", ie when the space right next to you is occupied but the space right next to it is free. 我有2个移动功能的原因是,一个功能用于基本运动,即当您旁边的空间相邻时,另一个功能检查“跳”,即当您旁边的空间被占用但该空间就在它旁边是免费的。

I'll add my code here just in case it makes it easier for you guys to understand what I'm trying to do. 我将在此处添加我的代码,以防万一它使你们更容易理解我正在尝试做的事情。

import numpy as np


matrix = [[1,1,1,1,1,0,0,0,0,0], [1,1,1,1,0,0,0,0,0,0], [1,1,1,0,0,0,0,0,0,0], [1,1,0,0,0,0,0,0,0,0], [1,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,2], [0,0,0,0,0,0,0,0,2,2], [0,0,0,0,0,0,0,2,2,2], [0,0,0,0,0,0,2,2,2,2], [0,0,0,0,0,2,2,2,2,2]]

#new_matrix = np.fliplr(np.flipud(matrix)) 
#new_matrix = new_matrix.tolist() 


print "\n".join(" ".join(str(el) for el in row) for row in matrix)
#print "\n"
#print "\n".join(" ".join(str(el) for el in row) for row in new_matrix)


def basicMove(x,y):
    listMoves = []
    if x > 0 and matrix[x-1][y] == 0: #left
        listMoves.append([x-1,y])
    if x < 9 and matrix[x+1][y] == 0: #right
        listMoves.append([x+1,y])
    if y < 9: #up
        if matrix[x][y+1] == 0:
            listMoves.append([x,y+1])
        if x>0 and matrix[x-1][y+1] == 0: #up left
            listMoves.append([x-1,y+1])
        if x < 9 and matrix[x+1][y+1] == 0: #up right
            listMoves.append([x+1,y+1])
    if y > 0: #down
        if matrix[x][y-1] == 0:
            listMoves.append([x,y-1])
        if x > 0 and matrix[x-1][y-1] == 0: #down left
            listMoves.append([x-1,y-1])
        if x<9 and matrix[x+1][y-1] == 0: #down right
            listMoves.append([x+1,y-1])
    return listMoves

def hopper(x,y):
    listHops = []
    listHops.append(basicMove(x,y)) #Call the basic move function inside the hop function
    if x > 1 and matrix[x-1][y] != 0 and matrix[x-2][y] == 0: #left
        listHops.append([x-2,y])
    if x < 8 and matrix[x+1][y] != 0 and matrix[x+2][y] == 0: #right
        listHops.append([x+2,y])
    if y > 1:
        if matrix[x][y-1] != 0 and matrix[x][y-2] == 0: #down
            listHops.append([x,y-2])
        if x>1 and matrix[x-1][y-1] != 0 and matrix[x-2][y-2] == 0: #down left
            listHops.append([x-2,y-2])
        if x < 8 and matrix[x+1][y+1] != 0 and matrix[x+2][y-2] == 0: #down right
            listHops.append([x+2,y-2])
    if y < 8:
        if matrix[x][y+1] != 0 and matrix[x][y+2] == 0: #up
            listHops.append([x,y+2])
        if x > 1 and matrix[x-1][y+1] != 0 and matrix[x-2][y+2] == 0: #up left
            listHops.append([x-2,y+2])
        if x < 8 and matrix[x+1][y+1] != 0 and matrix[x+2][y+2] == 0: #up right
            listHops.append([x+2,y+2])
    return listHops

hopper(2,1) #Testing the function

One last question, will using Object Oriented Programming make things much more easier/efficient for me? 最后一个问题,使用面向对象编程对我来说会变得更容易/更有效吗? I've been checking some examples of people that implement MCTS for games such as Tic tac toe and Reversi on Python and they all seem to use OOP. 我一直在检查一些为游戏实现MCTS的人的例子,例如在Tic tac toe和Reversi上使用Python,他们似乎都使用OOP。 Thanks for you help. 感谢您的帮助。

Firstly, Yes. 首先,是的。 The root of the tree will be the initial state of the board. 树的根将是板的初始状态。

But, you don't need a function to calculate the weight (or evaluation function), in Monte Carlo Tree Search. 但是,在蒙特卡洛树搜索中,您不需要函数来计算权重(或评估函数)。 Here, similar task is done through function called, "simulate", which randomly plays the game from given state(or node), till the end (until reached an outcome ie, win/draw/loose), and returns that outcome(+1/0/-1). 在这里,类似的任务通过称为“模拟”的函数完成,该函数从给定状态(或节点)随机进行游戏,直到结束(直到达到结果,即获胜/平局/松散),然后返回该结果(+ 1/0 / -1)。 MCTS algorithm uses simulate multiple times, to get a rough estimation about how good or bad, the move in consideration is. MCTS算法使用多次仿真,以粗略估计所考虑的移动的好坏。 Then, it explores deeper (or expands) the best looking move, by running more simulation over that move, to get clearer estimation. 然后,它通过对该移动进行更多的模拟来探索(或扩展)最佳移动,从而获得更清晰的估计。 Concretely, move, with highest value in cumulative results of random plays through that move is selected to expand further. 具体地,选择具有通过该移动的随机播放的累积结果中的最高值的移动以进一步扩展。 Algorithm also keeps track of depth of exploration (so that it doesn't just keep on digging one move and leaves a better move), such that it explores nodes with least regret ( O(logn), which is optimal ). 算法还跟踪探索的深度(因此,它不仅继续挖掘一个动作并留下更好的动作),因此它探索后悔最少的节点(O(logn),最佳)。

And, about using Object Oriented Programming, It can help, if you are good at it, but it can be done without it also (try using nodes as a list, and use sublist of it to store features you want to store in each node) 而且,关于使用面向对象的编程,如果您擅长的话,它可以提供帮助,但是也可以在没有它的情况下完成(尝试将节点作为列表使用,并使用其子列表存储要存储在每个节点中的功能。 )

Resources: 资源:

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

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