【问题标题】:Chess Quiescence Search ist too extensive国际象棋静止搜索过于广泛
【发布时间】:2015-06-30 18:24:02
【问题描述】:

上个月,我一直在用 c# 创建一个简单的国际象棋引擎,并取得了一些不错的进展。它使用的是简单的 Alpha-Beta 算法。

为了纠正地平线效应,我尝试实现静止搜索(并在它起作用之前失败了几次)。引擎的力量似乎从那以后安静了一点,但速度非常慢!

以前,我可以在大约 160 秒内搜索到 6 层深度(处于游戏中期的某个位置),而在静态搜索中,计算机需要大约 80 秒才能移动到搜索深度 3!

暴力节点计数器在深度 3 处约为 20000 个节点,而静态节点计数器高达 2000 万!

由于这是我的第一个国际象棋引擎,我真的不知道这些数字是否正常,或者我是否可能在我的静止算法中犯了错误。如果有经验的人能告诉我 BF 节点/静止节点的通常比率是多少,我将不胜感激。

顺便说一句,看看: (只要searchdepth为0,BF树就会调用这个方法)

public static int QuiescentValue(chessBoard Board, int Alpha, int Beta)
    {
        QuiescentNodes++;

        int MinMax = Board.WhoseMove; // 1 = maximierend, -1 = minimierend
        int Counter = 0;
        int maxCount;


        int tempValue = 0;
        int currentAlpha = Alpha;
        int currentBeta = Beta;
        int QuietWorth = chEvaluation.Evaluate(Board);

        if(MinMax == 1) //Max
        {
            if (QuietWorth >= currentBeta)
                return currentBeta;
            if (QuietWorth > currentAlpha)
                currentAlpha = QuietWorth;
        }

        else            //Min
        {
            if (QuietWorth <= currentAlpha)
                return currentAlpha;
            if (QuietWorth < currentBeta)
                currentBeta = QuietWorth;
        }




        List<chMove> HitMoves = GetAllHitMoves(Board);
        maxCount = HitMoves.Count;

        if(maxCount == 0)
            return chEvaluation.Evaluate(Board);


        chessBoard tempBoard;

        while (Counter < maxCount)
        {
            tempBoard = new chessBoard(Board);
            tempBoard.Move(HitMoves[Counter]);
            tempValue = QuiescentValue(tempBoard, currentAlpha, currentBeta);

            if (MinMax == 1) //maximierend
            {
                if (tempValue >= currentBeta)
                {
                    return currentBeta;
                }

                if (tempValue > currentAlpha)
                {
                    currentAlpha = tempValue;
                }

            }

            else            //minimierend
            {
                if (tempValue <= currentAlpha)
                {
                    return currentAlpha;
                }
                if (tempValue < currentBeta)
                {
                    currentBeta = tempValue;
                }
            }

            Counter++;
        }

        if (MinMax == 1)
            return currentAlpha;
        else
            return currentBeta;

    }

【问题讨论】:

  • 你看this SO question了吗?
  • 有一条评论不是针对静态搜索的:对于象棋这样的游戏,修改同一个棋盘然后撤消移动通常比复制棋盘快得多每个探针的整个电路板。
  • @DeadZone:我确实看过链接的帖子,但问题似乎是这个人在静止搜索中产生了所有动作(我没有)。
  • @Internal Server Error: 感谢您的建议,以后可能会有所帮助。现在,我认为是否复制 Board 并不重要,因为我认为我每秒可以复制 Board 大约 25 000 000 次(而我的整个引擎目前正在搜索 720 000 个节点/秒。

标签: c# algorithm chess alpha-beta-pruning


【解决方案1】:

我不熟悉英文术语 - HitMove 是你从棋盘上删除一块的动作吗?

在这种情况下,在我看来,您使用GetAllHitMoves 来获取静止搜索的“嘈杂”移动列表,然后对这些移动进行比通常的 3 层或 6 层更进一步的评估。虽然这被称为递归,所以只要有可能的 HitMoves 剩余,您就会一遍又一遍地评估它。限制您的静止搜索应该可以解决您的性能问题。

至于选择静止搜索的限制 - wiki 声明:

现代国际象棋引擎可能搜索某些移动的深度比最小值高 2 到 3 倍。

【讨论】:

  • 谢谢,这似乎是我一直在寻找的。我将静止搜索限制为 4 层,搜索突然又变得更快了!到时候我会标记你的答案。
  • 编辑:你能告诉我有限的静止搜索对搜索结果的影响有多大吗? ty
  • 在哪方面?通过设置静止搜索的限制,您显然可以再次在静止层限制附近产生某种水平效应。但是,除非您评估每一个可能的举动(接近您之前所做的),否则您将无法避免这种情况。
  • 关于性能的另一个注意事项 - 您是每回合都重新评估整个棋盘,还是将计算存储在某个地方,这样您只需要从每个节点再评估一次移动?如果你存储你的结果,你也许可以增加层深,同时将运行时间保持在大约 2-3 分钟(或者只是减少很多时间)。
  • @H W: 1) 是的,我有点担心从搜索限制中返回的地平线效应。但这似乎还没有发生。 2)我猜你有哈希表/转置表,以便对移动进行排序?这绝对是接下来的步骤之一,但我将不得不进一步研究它。不过感谢您的建议。
猜你喜欢
  • 2016-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-17
  • 1970-01-01
  • 2021-09-05
  • 2014-03-02
  • 2013-05-24
相关资源
最近更新 更多