私はチェスエンジンを書こうとしています。Min-Maxingが機能します。今、私はアルファベータプルーニングを実装したかったのですが、それについて読んだり、ビデオを見たりしても、どこかで深刻な誤解を抱いているに違いありません。
Min-Maxingの場合、完全な検索ツリーを構築し、最も深いノードonlyを評価します。次に上に行き、他のノードを評価せずにスコアを「運びます」。比較したのは持ち運びのスコアだけです。
ABPの場合は、完全な検索ツリー(?!)も作成し、最深のノードのみを評価します。次に上に行き、スコアを「運びます」。しかし、今回はノードのプルーニングを頻繁に実行できます。つまり、それほど頻繁にmin-maxを実行する必要がなく、最も深い深度でallノードを評価する必要もありません。
事柄は次のとおりです。ノードを評価する必要がある時間に制限されず、メモリ(サイズとアクセス速度も)に制限されます私はまだ何百万ものツリーを構築する必要があるためnodes、その後それをプルーニングします。
createブランチを作成する必要もないように、ABPは何とか早く発生するはずであると想定しましたが、比較のために常に最も深いノードを評価する必要があるため、機能しません(したがって、ツリーを完全に構築する必要があります)。
私はここでバカのように感じています、何を逃しますか?
Min-Max検索(ABPの有無にかかわらず)は、メモリ内の「完全な検索ツリーを構築する」を想定していません。通常、これは 深さ優先検索 ツリートラバーサルとして実装されます。これは、が完全な検索ツリーをトラバースしますが、完全に保存するわけではありません。実際、各時点で、メモリ内に必要なレベルごとに1つのノードしかないため、メモリ使用量は実際には非常に低くなっています。すべての子ノードは、「オンザフライ」で再帰的に生成され、不要になったときに破棄できます。
たとえば、DFSがレベル「深さ-1」のノードに到達し、すべての子ノードがノードを離れるとします。これで、最大スコアは次の疑似コードによって計算されます。
maxscore=-1
for each child node C of "current node":
score = evaluate(C)
maxscore=max(maxscore,score)
return maxscore
ご覧のように、一度に必要な子ノードCは1つだけです。一度評価されてmaxscore
と比較されると、もう必要ありません。
Alpha-Beta-PruningによってMin-Maxを拡張する場合、必要なノードに違いはありません。 ABPは、maxscore
の中間値が直上の再帰レベルからminscore
に達したときに停止することにより、示されている例のループサイクルの数を減らすだけです。
現在のノードの子ノードが事前に作成され、maxscore
が計算される前に事前にソートされるこのアルゴリズムのバリエーションでも、完全な検索ツリーにメモリは必要ありません。メモリのみが必要です。の順に
O("searchdepth" x "maximum number of childs one node can have")
これは、完全な検索ツリーが持つノードの数の一部です。