árbol una recursivos recursivo recursividad recursiva que programacion procesos proceso procedimiento nivel funcion estructura elementos ejercicios conforman c# recursion stack artificial-intelligence stack-overflow

c# - una - que elementos conforman un proceso recursivo



¿Hay alguna manera de verificar el tamaño de pila disponible antes de la llamada recursiva?(DO#) (4)

Para un programa C # AI utilizo una llamada recursiva para encontrar el mejor movimiento siguiente (usando una Matriz 30x30 para almacenar el estado actual de la placa). Por cada movimiento que haga, quiero ver cuál de los movimientos posibles que puedo hacer desde el nuevo estado de la tabla será el mejor ... y así sucesivamente hasta que llegue a una posición de "fin del juego" (no hay más movimientos posibles en ese estado) o un temporizador detiene el proceso y no se realizan más llamadas recursivas (y se devuelve la "mejor" posición conocida). Esto solo para explicar por qué debo usar recursividad (no es recursividad de cola) y no puedo usar un solo estado de placa (global), pero debo buscar todos los estados de tabla posibles desde el estado actual.

(A veces) Obtengo una System.StackOverflowException. ¿Hay alguna manera de verificar el espacio de pila disponible antes de la próxima llamada recursiva? Entonces podría simplemente devolver el estado actual como "la mejor posición encontrada hasta el momento" y no hacer la próxima llamada recursiva. Es decir, cuando la pila disponible se vuelva demasiado pequeña, también debería contar como caso base.

La otra opción, por supuesto, puede ser simplemente poner cada llamada recursiva en un bloque try..catch y manejar la excepción System.StackOverflowException utilizándola como caso base.


Comenzando con .NET 2 NO PUEDE atrapar Exception ...

La única manera de determinar qué cantidad de tu pila ya se está utilizando es utilizar un código inseguro que desaconsejo encarecidamente ... mejor utilizar una Stack<T> explícita basada en el montón.


En realidad, el sistema ampliará el tamaño de la pila dinámicamente, en caso de que se quede sin espacio en la pila existente. Entonces, incluso si pudieras probar el tamaño de la pila, en realidad no importaría.

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

El sistema confirma las páginas adicionales de la memoria de la pila reservada a medida que son necesarias, hasta que la pila alcanza el tamaño reservado menos una página (que se usa como página de protección para evitar el desbordamiento de la pila) o el sistema tiene tan poca memoria que la operación falla ".

Lo que está diciendo que, antes de que ocurra la recursión, la pila es de un tamaño; y si la recursión causa un desbordamiento de pila, la pila tiene un nuevo tamaño cuando eso sucedió.

Como no puede detectar la Exception , en lugar de la recursión de la terminal, puede usar la recursividad final. El siguiente enlace proporciona algunos buenos detalles sobre la conversión de la recusión de la terminal en la reclusión de la cola: http://www.thomaslevesque.com/2011/09/02/tail-recursion-in-c/


Puede usar una cola + loop ( Queue<TNode> + while (queue.MoveNext()) ) en lugar de la recursión y limitar el tamaño de la cola.

O puede contar las llamadas abiertas al método y limitar la recursión de esa manera. (Contar entradas y salidas y no ingresar recursividad si las entradas - existe> maxOpenCalls).


Si realmente desea seguir ese camino, puede usar el método EnsureSufficientExecutionstack .

Como otros señalaron, a partir de .NET 2.0 no se puede detectar una Exception ; sin embargo, de la documentación de MSDN se sabe que el método anterior tiene el siguiente comportamiento:

Asegura que el espacio restante de la pila sea lo suficientemente grande como para ejecutar la función promedio de .NET Framework.

Cuando la pila no es lo suficientemente grande de acuerdo con este método, arrojará una excepción InsufficientExecutionStackException que puede atrapar .