上次说过速度快慢不代表棋力强弱,这好比携带攻击和防护装备的野战特种兵未必跑得过田径选手。这次,再说能尽快算出绝杀步,也不代表棋力越高;恰恰相反,Pikafish对绝杀可能的搜索是有诸多限制的。略举一例,见最新master分支源码668-676行:
// Step 7. Futility pruning: child node (~40 Elo)
// The depth condition is important for mate finding.
if (!ss->ttPv && depth < 8
&& eval - futility_margin(depth, cutNode && !ss->ttHit, improving, opponentWorsening)
- (ss - 1)->statScore / 210
>= beta
&& eval >= beta && eval < 18675 // smaller than wins.
&& (!ttMove || ttCapture))
return beta > VALUE_MATED_IN_MAX_PLY ? (eval + beta) / 2 : eval;
如上,674| eval < 18675 ,即是说,当评估值小于18675时,就判定为无效剪枝,停止继续搜索。以前,这阈值是18702,现在限制更严了。
Stockfish,是把这个阈值设为动态的,对应的源码如下:
// Step 8. Futility pruning: child node (~40 Elo)
// The depth condition is important for mate finding.
if (!ss->ttPv && depth < 11
&& eval - futility_margin(depth, cutNode && !ss->ttHit, improving, opponentWorsening)
- (ss - 1)->statScore / 254
>= beta
&& eval >= beta && eval < VALUE_TB_WIN_IN_MAX_PLY && (!ttMove || ttCapture))
return beta > VALUE_TB_LOSS_IN_MAX_PLY ? (eval + beta) / 2 : eval;
我也曾经把这阈值设为动态的,经过反复测试,掉Elo,就换回常数了,但不是18675。为什么呢?因为,搜索时间和CPU资源是一定的,通过探索更多可能导致将死的分支,引擎可能会花费更多时间进行搜索,而挤占了在其他非将死分枝搜索的时间和机率。
如果大家只想用来分析残局,可以把阈值改为动态的。