10

C# AI プログラムの場合、再帰呼び出しを使用して次の最適な動きを見つけます (30x30 配列を使用して現在のボードの状態を保存します)。私が行う各動きについて、新しいボードの状態から行うことができる可能な動きのどれが最良になるかを確認したい...など、「ゲームの終わり」の位置に到達するまで (それ以上の動きは不可能)状態) またはタイマーがプロセスを停止し、それ以上の再帰呼び出しは行われません (そして、「最適な」既知の位置が返されます)。これは、再帰を使用する必要がある理由 (末尾再帰ではない) を説明するためのものであり、単一の (グローバル) ボード状態を使用することはできず、現在の状態から可能なすべてのボード状態を検索する必要があります。

(ときどき) System.StackOverflowException が発生します。次の再帰呼び出しの前に利用可能なスタック領域を確認する方法はありますか? 次に、現在の状態を「これまでに見つかった最良の位置」として返すだけで、次の再帰呼び出しを行うことはできません。つまり、利用可能なスタックが小さくなりすぎた場合も、基本ケースとしてカウントする必要があります。

もちろん、他のオプションは、各再帰呼び出しを try..catch ブロックに入れ、それを基本ケースとして使用して System.StackOverflowException を処理することでしょうか?

4

5 に答える 5

2

再帰の代わりにキュー + ループ ( Queue<TNode>+ ) を使用して、キューのサイズを制限できます。while (queue.MoveNext())

Or you could count open calls to the method and limit the recursion in that manner. (Count entries and exits and don't enter recursion if entries - exists > maxOpenCalls).

于 2012-09-09T16:00:57.050 に答える
2

本当にその道をたどりたい場合は、EnsureSufficientExecutionstackメソッドを使用できます。

他の人が指摘したように、.NET 2.0 以降では をキャッチできませんがStackOverflowException、MSDN ドキュメントから、以前の方法には次の動作があることがわかっています。

残りのスタック領域が、平均的な .NET Framework 関数を実行するのに十分な大きさであることを確認します。

このメソッドに従ってスタックが十分に大きくない場合、キャッチできるInsufficientExecutionStackException例外がスローされます。

于 2012-09-09T16:03:39.220 に答える
2

実際には、既存のスタックのスペースが不足すると、システムはスタック サイズを動的に拡張します。したがって、スタックのサイズをテストできたとしても、それほど重要ではありません。

http://msdn.microsoft.com/en-us/library/windows/desktop/ms686774(v=vs.85).aspx の詳細

システムは、スタックが予約済みサイズから 1 ページ (スタック オーバーフローを防ぐためのガード ページとして使用される) を引いた値に達するか、またはシステムのメモリが少なくなり操作が停止するまで、必要に応じて予約済みスタック メモリから追加のページをコミットします。失敗する」。

つまり、再帰が発生する前は、スタックは 1 つのサイズです。再帰によってスタック オーバーフローが発生した場合、スタックはそれが発生したときの新しいサイズです。

をキャッチできないため、StackOverflowException終端再帰の代わりに末尾再帰を使用できます。次のリンクでは、終端再帰を末尾再帰に変換する方法について詳しく説明しています。

于 2012-09-09T15:56:20.643 に答える
1

Starting with .NET 2 you CANNOT catch StackOverflowException...

The only way to determine how much of your stack is already used means to use unsafe code which I strongly advise against... better use an explicit heap-based Stack<T>.

于 2012-09-09T16:01:09.633 に答える