Algorithm 如何准确地使用;“历史启发式”;在α-β-极小极大中?

Algorithm 如何准确地使用;“历史启发式”;在α-β-极小极大中?,algorithm,tree,hashmap,minimax,alpha-beta-pruning,Algorithm,Tree,Hashmap,Minimax,Alpha Beta Pruning,我正在做一个国际象棋的人工智能 到目前为止,我已经成功实现了Alpha-Beta剪枝Minimax算法,如下所示(来自维基百科): 由于这花费了太多的时间复杂性(一棵一棵地遍历所有的树),我遇到了一个叫做 原始文件中的算法: int AlphaBeta(pos, d, alpha, beta) { if (d=0 || game is over) return Eval (pos); // evaluate leaf position from current p

我正在做一个国际象棋的人工智能

到目前为止,我已经成功实现了Alpha-Beta剪枝Minimax算法,如下所示(来自维基百科):

由于这花费了太多的时间复杂性(一棵一棵地遍历所有的树),我遇到了一个叫做

原始文件中的算法:

int AlphaBeta(pos, d, alpha, beta) 
{ 
    if (d=0 || game is over) 
        return Eval (pos);  // evaluate leaf position from current player’s standpoint 

    score = - INFINITY;     // preset return value 
    moves = Generate(pos);  // generate successor moves 

    for i=1 to sizeof(moves) do                // rating all moves 
        rating[i] = HistoryTable[ moves[i] ]; 
    Sort( moves, rating );                     // sorting moves according to their history scores 

    for i =1 to sizeof(moves) do { // look over all moves 
        Make(moves[i]); // execute current move 
        cur = - AlphaBeta(pos, d-1, -beta, -alpha); //call other player

        if (cur > score) {
            score = cur; 
            bestMove = moves[i];      // update best move if necessary 
        } 

        if (score > alpha) alpha = score;    //adjust the search window 
            Undo(moves[i]);                  // retract current move 

        if (alpha >= beta) goto done;        // cut off 
     } 

     done: 
     // update history score 
     HistoryTable[bestMove] = HistoryTable[bestMove] + Weight(d); 

     return score; 
} 
因此,基本上,我们的想法是为之前的“移动”跟踪哈希表或字典

现在我不明白这个“移动”在这里意味着什么。 我不确定它是指单个动作还是每次动作后的整体状态

例如,在国际象棋中,这个哈希表的“键”应该是什么

  • 个人移动,如(女王到位置(0,1))或(骑士到位置(5,5))

  • 还是棋盘在个人移动后的整体状态


  • 如果是1,我想在将“移动”记录到我的历史记录表中时,没有考虑其他块的位置?

    您可以使用换位表,以避免多次评估同一块板。换位意味着你可以通过按不同的顺序进行移动来达到相同的棋盘状态。天真的例子:

    1. e4 e5 2. Nf3 Nc6
    1. e4 Nc6 2. Nf3 e5
    
    这些游戏的结果是相同的位置,但达成的方式不同

    一种常见的方法称为Zobrist哈希,用于哈希国际象棋位置:


    根据我的经验,与其他技术相比,历史启发式产生的好处微不足道,不值得作为基本的搜索例程。这与使用转置表不同。如果后者是您想要实现的,我仍然建议您不要这样做。还有许多其他技术可以用更少的努力产生好的结果。事实上,一个高效且正确的转置表是国际象棋引擎中最难编码的部分之一


    首先尝试修剪和移动排序启发式,其中大多数是一到几行代码。我在中详细介绍了这些技术,其中还提供了您可以预期的性能增益估计

    我认为在线提供的原始论文(Jonathan Schaeffer的历史启发式和Alpha-Beta搜索增强实践)清楚地回答了这个问题。在本文中,作者将移动定义为棋盘上的两个索引(从正方形到),使用64x64表(实际上,我认为他使用了位移位和单索引数组)来包含移动历史

    作者比较了所有可用的移动排序方法,确定hh是最好的。如果当前的最佳实践已经建立了一种改进的移动排序形式(超越hh+换位表),我还想知道它是什么

    例如,在国际象棋中,这个哈希表的“键”应该是什么

    • 个人移动,如(女王到位置(0,1))或(骑士到位置(5,5))
    • 还是棋盘在个人移动后的整体状态
    关键是一个单独的移动,在将“移动”记录到历史表中时,不考虑其他工件的位置

    历史记录表(也称为蝴蝶板)的传统形式如下:

    score history_table[side_to_move][from_square][to_square];
    
    例如,如果移动
    e2-e4
    产生截止,则元素:

    history_table[white][e2][e4]
    
    (以某种方式)增加(与移动位置无关)

    与示例代码一样,历史启发式使用这些计数器进行移动排序。其他启发式方法可以利用历史记录表(例如,延迟移动减少)

    认为:

    • 通常历史启发式不适用于没有移动顺序知识的纯阿尔法-贝塔(在国际象棋中,只有“安静”的移动通过历史启发式进行排序)
    • 历史记录表有多种可选形式(常用的是
      历史记录表[piece][to_square]

    历史启发法实际上与换位表不同。前者更容易实现,但对现代搜索例程产生的好处微乎其微。此答案与主题无关,OP专门询问历史启发式,而不是换位表或任何其他改进。这不回答OP的任何问题。这应该是评论,而不是回答。
    history_table[white][e2][e4]