关于换位表的困惑(国际象棋编程)

时间:2017-01-19 17:49:05

标签: artificial-intelligence chess

我目前正在使用换位表进行移动排序。使用迭代深化搜索,我将前一次迭代的minimax值存储到下一次迭代的顺序移动。这一切都很好。

这是我的困惑:

如果我在换位表中找到某个位置,那么我将先前计算的得分用于移动排序(从迭代加深的前一次迭代开始)。但是,如果更新此位置的分数(在返回minimax之后),并且在另一个子树中找到位置AGAIN(迭代加深的相同迭代) - 我不想仅将它用于移动排序......我应该能够返回该值,因为现在已经为此迭代计算了值并且该值是绝对的。

这是我的问题:有两个换位表是标准的吗?一个用于前一次迭代,一个用于迭代加深的当前迭代。所以我首先检查表格中的当前迭代,看看是否已经计算了minimax值,然后只返回这个值。如果它不在此表中,我将使用该表进行上一次迭代,以进行移动排序。如果它不是,那么这是我在此搜索中没有见过的新位置。

这种思路是正确的,还是有更有效的方法?

2 个答案:

答案 0 :(得分:2)

通常,您不仅要在表中存储状态的最后找到的minimax值,还要在表中存储状态时在迭代中使用的深度限制。这样,当您稍后在表中查找时,您可以通过将存储在表条目中的深度限制与当前深度限制进行比较来判断它是在上一次迭代中还是在当前迭代中最后更新的。如果它们相等,您知道表条目是在当前迭代中最后更新的,您可以直接使用表中存储的值而无需任何额外搜索

答案 1 :(得分:1)

我同意@Dennis_Soemers。您应该保存深度,甚至可以添加到转置表中的alpha / beta边界。不,你不应该需要两张桌子。

让我们检查桌上的Stockfish源代码。

https://github.com/official-stockfish/Stockfish/blob/master/src/tt.h

/// TTEntry struct is the 10 bytes transposition table entry, defined as below:
///
/// key        16 bit
/// move       16 bit
/// value      16 bit
/// eval value 16 bit
/// generation  6 bit
/// bound type  2 bit
/// depth       8 bit

表的保存功能定义为:

void save(Key k, Value v, Bound b, Depth d, Move m, Value ev, uint8_t g) 

现在,如果您有两个相同的位置,从深度d-1d开始。你可以这样做:

// My hash key is now position + depth
Key my_hash_key = k + d

您可以轻松检查上一次迭代和当前迭代:

Key previous_iter_key = my_position_key + d-1
probe(previous_iter_key ...)

Key current_iter_key = my_position_key + d
probe(current_iter_key ...)