如何在C ++中创建树数据结构?

时间:2011-08-01 05:40:43

标签: c++ data-structures tree artificial-intelligence reversi

我正和我的一位朋友一起参加人工智能方法课程,我们已经参加了最后一个项目,该项目正在编写奥赛罗& amp;使用C ++和OpenGL的AI。

到目前为止,我们已经拥有了主板和奥赛罗引擎(我正在使用MVC类型的方法)。但事实证明难以理解的一件事是人工智能。

我们应该编写一个在树上使用Alpha-Beta修剪的AI来快速计算它应该进行的下一步移动。

就游戏而言,Alpha-Beta修剪的概念,以及用于检测哪些方块比其他方块更有价值的算法。

但是,我和我的伙伴还没有参加数据结构课程,因此我们不知道如何在C ++中正确创建树,甚至不知道从哪里开始。

所以我的问题是,Stack Overflow是:我在哪里开始快速(并且有效地)编写和遍历C ++中的Alpha-Beta修剪树而不使用STL 。 (我们的任务规定我们不允许使用STL)。

感谢所有的帮助,谢谢!

1 个答案:

答案 0 :(得分:2)

用于alpha-beta修剪的树通常是隐含的。这是一种防止AI搜索算法浪费时间在糟糕解决方案上的方法。这是来自维基百科的伪代码:

function alphabeta(node, depth, α, β, Player)         
    if  depth = 0 or node is a terminal node
        return the heuristic value of node
    if  Player = MaxPlayer
        for each child of node
            α := max(α, alphabeta(child, depth-1, α, β, not(Player) ))     
            if β ≤ α
                break                             (* Beta cut-off *)
        return α
    else
        for each child of node
            β := min(β, alphabeta(child, depth-1, α, β, not(Player) ))     
            if β ≤ α
                break                             (* Alpha cut-off *)
        return β 
(* Initial call *)
alphabeta(origin, depth, -infinity, +infinity, MaxPlayer)

该函数递归地评估板位置。 “节点”是当前位置,并且它表示“对于节点的每个子节点”,它是您在当前位置生成每个可能移动所产生的新板位置的位置。深度参数控制您想要评估树的前方,分析移动到无限深度可能是不切实际的。


但是,如果你为了教育目的修剪它之前必须构建一个给定深度的树,那么具有可变数量子节点的树的结构非常简单,看起来像这样:

struct Node
{
    Node ** children;
    int     childCount;
    double  value;
};

Node * tree;

此处children是具有childCount成员的Node数组。叶节点将具有childCount=0。要构建树,您可以搜索可用的板位置,如下所示:

Node * CreateTree(Board board, int depth)
{
    Node * node = new Node();
    node.childCount = board.GeAvailableMoveCount();
    node.value      = board.GetValue;
    if (depth > 0 && node.childCount > 0)
    {
        node.children = new Node * [node.childCount];
        for (int i = 0; i != node.childCount; ++i)
            node.children[i] = CreateTree(board.Move(i), depth - 1);
    }
    else
    {
        node.children = NULL;
    }
    return node;
}

void DeleteTree(Node * tree)
{
    for (int i = 0; i != tree.childCount; ++i)
        DeleteTree(tree.children[i]);
    delete [] tree.children; // deleting NULL is OK
    delete tree;
}