αβ法(アルファベータ枝刈り)
αβ法は、ミニマックス法の探索効率を大幅に改善するアルゴリズムです。 「この先を探索しても結果が変わらない」と分かった時点で探索を打ち切る(枝刈り)ことで、 同じ結果をより少ない計算量で得ることができます。
インタラクティブデモ
三目並べを例に、αβ法がどのように枝刈りを行うか見てみましょう。 灰色の破線で表示されるノードが「枝刈り」されたノードです。 ミニマックス法と比較して、どれだけ探索が省略されたか確認できます。
初期盤面を選択
現在の盤面(Xの手番)
αβ法について
αβ法(Alpha-Beta Pruning)は、1958年頃にジョン・マッカーシーらによって開発されたミニマックス法の最適化技術です。 ゲームツリーの探索において、「この先を調べても最終結果に影響しない」と判断できる部分を省略(枝刈り)することで、 計算量を大幅に削減します。
αβ法では、α(アルファ)とβ(ベータ)という2つの値を使って探索の範囲を管理します。 αはMAX側(自分)が「少なくともこれだけは確保できる」という下限値、 βはMIN側(相手)が「これ以上は渡さない」という上限値を表します。 α ≥ β となった時点で、その先の探索は結果に影響しないため打ち切ります。
枝刈りの仕組み
- α値の更新(MAX層): 自分のターンでは、子ノードの評価値のうち最大のものを選びます。 より良い手が見つかるたびにα値を更新し、「少なくともこの値は確保できる」という下限を記録します。
- β値の更新(MIN層): 相手のターンでは、子ノードの評価値のうち最小のものを選びます。 より悪い(相手にとって良い)手が見つかるたびにβ値を更新し、「これ以上は渡さない」という上限を記録します。
- 枝刈り条件(α ≥ β): もしα ≥ β となったら、この先の探索は無意味です。 MAX側は既にα以上を確保でき、MIN側はβ以下に抑えようとしますが、α ≥ β ならMIN側がこの分岐を選ぶことはありません。
- 効率の向上: 最良のケース(完璧な手順で探索)では、計算量をO(b^d)からO(b^(d/2))まで削減できます。 つまり、同じ時間で約2倍の深さまで探索できるようになります。
効果と応用
- 計算量削減: 理想的な場合、探索ノード数を平方根まで削減可能
- 結果は同一: ミニマックス法と全く同じ最善手を見つけます
- 順序依存性: 良い手から先に探索すると、より多くの枝刈りが発生します
- 実用的なAI: チェス、将棋、オセロなどの実用的なゲームAIの基盤技術
- さらなる最適化: 反復深化、トランスポジションテーブルと組み合わせて使用されます
擬似コード
function alphabeta(node, depth, α, β, isMaximizing):
if depth == 0 or node is terminal:
return evaluate(node)
if isMaximizing:
value = -∞
for each child of node:
value = max(value, alphabeta(child, depth-1, α, β, false))
α = max(α, value)
if α >= β:
break // β枝刈り
return value
else:
value = +∞
for each child of node:
value = min(value, alphabeta(child, depth-1, α, β, true))
β = min(β, value)
if α >= β:
break // α枝刈り
return value
// 初期呼び出し
alphabeta(root, depth, -∞, +∞, true)よくある質問
最終的な結果(最善手と評価値)は探索順序に関係なく同じになります。 しかし、探索するノードの数は順序に大きく影響されます。 良い手から先に探索すると、より多くの枝刈りが発生し、効率が向上します。 そのため、実際のゲームAIでは「キラー手法」「履歴ヒューリスティック」などの手順最適化技術が使われます。
αは負の無限大(-∞)、βは正の無限大(+∞)で初期化します。 これは「まだ何も確保していない」「何でも受け入れる」状態を表します。 探索が進むにつれて、αは上昇(より良い下限が見つかる)、βは下降(より厳しい上限が設定される)していきます。 実装上は、整数の最小値・最大値(例:-999999, 999999)を使うことが多いです。
理論上の最大効率を達成するには、各ノードで最善手を最初に探索する必要があります。 実際にはこれは困難ですが、いくつかの工夫で近づけることができます。 「反復深化」で浅い探索の結果を使って手を並べ替える方法、 「キラー手法」で兄弟ノードで良かった手を優先する方法、 「履歴ヒューリスティック」で過去に良かった手を優先する方法などがあります。 これらを組み合わせることで、ランダム順序の約2倍の効率を達成できることが多いです。