多くの将棋プログラムの探索アルゴリズムでは、深さを探索の 打ち切り条件とするのに対して、激指の探索アルゴリズムでは、 局面の実現確率を打ち切り条件とする。つまり、局面の実現確率 があらかじめ設定されている閾値を下回ったら、葉になる (評価関数を呼ぶ)というわけである。
局面の実現確率とは、その局面が実際に実現する確率である。 一般に、読みの中の局面のほとんどは、実際に実現することはない。 そこで、どれくらい実現しないのか、あるいは実現するのか を確率的に評価したものが、ここでいう「局面の実現確率」である。 つまり、局面の実現確率を探索打ち切りの閾値とすることによって、 実際に実現の可能性の高い、すなわち、「ありそうな」局面を 読むことができる。
いま、ある指し手Mによって局面Aが局面A'に変化するとき、 局面A'の実現確率は次のように計算される。
(局面A'の実現確率)=(局面Aの実現確率)×(指し手Mが指される確率)ここで、合理的で十分に強いプレイヤーを仮定すれば、 指し手Mが最善手であれば必ずその手を指すのだから、 上の式は次のようになる。
(局面A'の実現確率)=(局面Aの実現確率)×(指し手Mが最善手である確率)指し手Mが最善手である確率を求める手法については別の章で述べる。
その他の点については、普通の深さ打ち切りによる探索アルゴリズム と同様である。すなわち、αβ枝刈りを用いたMin-max法となる。 以下に、 実現確率打ち切りによる探索アルゴリズムの基本形を C++ライクなコードで示す。
int search(Shogiban* ban, double probability, double probability_threshold, int alpha, int beta, Move best_move) { // 実現確率がしきい値を下回ったらおしまい if (probability < probability_threshold) return evaluate(ban); // 指し手生成(同時に、それぞれの指し手に、最善手である確率を付与) list<Move> move_list; // STL (Standard Template Library) のリスト generate_moves(ban, move_list); int best_eval = alpha; for (list<Move>::const_iterator i = move_list.begin(); i != move_list.end(); i++) { ban->move(*i); Move dummy; // 再帰呼び出し // 現局面の実現確率に、指し手の確率を掛ける int eval = -search(ban, probability*i->probability, probability_threshold, -beta, -best_eval, dummy); ban->reverse(); if (eval > best_eval) { best_eval = eval; best_move = *i; if (best_eval >= beta) return best_eval; } } return best_eval; }
ここで、局面の実現確率に関して掛け算しかしていない点に注目 すると、log をとることによって、すべて足し算で処理できることがわかる。
例えば、ある局面Aの実現確率が 50% で、指し手Mの確率が 25% だとする。 そうすると、指し手Mによって実現する局面A'の実現確率は、
50% x 25% = 12.5%となるが、これを、log2 をとって計算すると
-1 - 2 = -3というように、足し算で計算することができる。そこで激指では、 確率をそのまま用いるのではなく、確率の log2 をとって符合を反転したものを用いている。それを logp と呼ぶことにすると、ルート局面の logp = 0 から始まり、 指し手によって、logp が増えていき(最善手の確率が高い指し手 ほど、logp の増加が少ない)、logp > logp_threshold で、 探索を打ち切る(評価関数を呼ぶ)という形になる。
ここで、logp を、普通の探索アルゴリズムにおける「深さ」と置き換えてみれば、 なんのことはない、実装上は、普通の深さ打ち切りによる探索アルゴリズムで、 深さの増加分を指し手の種類に応じて可変にしただけ、ということになる。
実は、後で文献を調べていて気が付いたことであるが、チェスの 探索アルゴリズムに、partial depth という手法があり、それでは、 駒を取る手などの active な手を、深さ 0.8 などにする手法が あるという。激指は、実装の形だけみると、partial depth という 手法に非常に近いのではないかと思う。