首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么我的Tic-tac-toe minimax实现这么慢?

为什么我的Tic-tac-toe minimax实现这么慢?
EN

Stack Overflow用户
提问于 2021-02-28 21:11:30
回答 2查看 187关注 0票数 1

对于Tic-tac-toe,我非常简单的minimax算法以大约每秒500万个节点的速度运行。尽管这足以在0.1秒内找到Tic-tac-toe移动,但它比其他程序要少得多。例如,this video在10:00显示,计算国际象棋走法(复杂得多)的速度约为每秒2000万个节点。This website显示,Stockfish可以在普通PC上以每秒500万个节点的速度运行完整的国际象棋引擎。

代码:

代码语言:javascript
运行
复制
#include <iostream>
#include <chrono>

int board[3][3];
int nodes = 0;

bool isFull()
{
    for (int i = 0; i < 3; i++)
    {
        for (int j = 0; j < 3; j++)
        {
            if (board[i][j] == 0)
            {
                return false;
            }
        }
    }

    return true;
}

bool equals3(int a, int b, int c)
{
    return a == b && b == c && a > 0;
}

int checkWin()
{
    for (int row = 0; row < 3; row++)
    {
        if (equals3(board[row][0], board[row][1], board[row][2]))
        {
            return board[row][0];
        }

        if (equals3(board[0][row], board[1][row], board[2][row]))
        {
            return board[0][row];
        }
    }

    if (equals3(board[0][0], board[1][1], board[2][2]))
    {
        return board[0][0];
    }

    if (equals3(board[0][2], board[1][1], board[2][0]))
    {
        return board[0][2];
    }

    return 0;
}

int negaMax(int turn)
{
    nodes++;

    if (isFull())
    {
        return 0;
    }

    int win = checkWin();
    if (win != 0)
    {
        return (win == turn) ? 1 : -1;
    }

    int bestScore = -1;

    for (int x = 0; x < 3; x++)
    {
        for (int y = 0; y < 3; y++)
        {
            if (board[x][y] == 0)
            {
                board[x][y] = turn;
                int score = -negaMax(3 - turn);
                board[x][y] = 0;

                if (score > bestScore)
                {
                    bestScore = score;
                }
            }
        }
    }

    return bestScore;
}

int main()
{
    auto start = std::chrono::system_clock::now();

    negaMax(1);

    auto end = std::chrono::system_clock::now();
    std::chrono::duration<double> timePassed = end - start;
    
    std::cout << "Nodes searched: " << nodes << "\n";
    std::cout << "Time passed: " << timePassed.count() << "\n";
    std::cout << "NPS: " << nodes / timePassed.count() << "\n";
}

我不确定我如何才能进一步改进这个程序,并且在我的国际象棋走法一代中显示出速度的不足。

EN

回答 2

Stack Overflow用户

发布于 2021-02-28 21:30:13

因为对于Minimax算法,您应该使用Alpha Beta剪枝(它不考虑不必要的子树:Alpha-beta pruning - Wikipedia)。然而,'minimax‘函数(可能在代码中称为negaMax )应该在最大化或最小化时分别在PC回合和玩家回合中分离。

票数 0
EN

Stack Overflow用户

发布于 2021-03-01 00:23:49

不使用整数数组来表示宽值,而是考虑使用int8_t,其中每个二进制值表示一个状态,然后使用位操作来操作或查找电路板的状态。当遍历数百万个节点时,递归函数中嵌套的for循环和其他操作将受到影响。

使用alpha beta剪枝和哈希树记录以前的搜索值可以显著提高搜索速度。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66409442

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档