SlideShare una empresa de Scribd logo
BUSQUEDA POR BACKTRACKING

Introduccion:

         Backtracking:Dentro de las técnicas de diseño de algoritmos, el método de Vuelta Atrás
         (del inglés Backtracking) es uno de los de más amplia utilización, en el sentido de que
         puede aplicarse en la resolución de un gran número de problemas, muy especialmente en
         aquellos de optimización. En ocasiones se ven enfrentados a problemas de optimización
         que solo pueden ser resueltos a través de un estudio exhaustivo de un conjunto conocido
         a priori de posibles soluciones, en las que se trata de encontrar una o todas las soluciones
         y por tanto también la óptima. Para llevar a cabo este estudio exhaustivo, el diseño Vuelta
         Atrás proporciona una manera sistemática de generar todas las posibles soluciones
         siempre que dichas soluciones sean susceptibles de resolverse en etapas.


Objetivo:

Investigar y desarrollar el método de búsqueda por Backtracking (vuelta a tras), para
comprender el método de búsqueda.

Marco Teorico:

Técnica de Backtracking

En su forma básica la Vuelta Atrás se asemeja a un recorrido en profundidad dentro de un árbol
cuya existencia sólo es implícita, y que se denomina árbol de expansión. Este árbol es
conceptual, en donde cada nodo de nivel k representa una parte de la solución y está formado por
k etapas que se suponen ya realizadas. Sus hijos son las prolongaciones posibles al añadir una
nueva etapa. Para examinar el conjunto de posibles soluciones es suficiente recorrer este árbol
construyendo soluciones parciales a medida que se avanza en el recorrido. En este recorrido
pueden suceder dos cosas. La primera es que tenga éxito si, procediendo de esta manera, se llega
a una solución (una hoja del árbol). Si lo único que buscábamos era una solución al problema, el
algoritmo finaliza aquí; ahora bien, si lo que se busca eran todas las soluciones o la mejor de
entre todas ellas, el algoritmo seguirá explorando el árbol en búsqueda de soluciones
alternativas.Por otra parte, el recorrido no tiene éxito si en alguna etapa la solución parcial
construida hasta el momento no se puede completar; s encuentran en lo que llamamos nodos
fracaso. En tal caso, el algoritmo vuelve atrás (y de ahí su nombre) en su recorrido eliminando
los elementos que se hubieran añadido en cada etapa a partir de ese nodo. Si en este retroceso, si
existe uno o más caminos aún no explorados que puedan conducir a solución, el recorrido del
árbol continúa por ellos.

Algoritmo Genético

El algoritmo genérico del backtracking es el siguiente:

Inicio
IniciarOpciones;
 Repetir
SeleccionarNuevaOpcion;
  Si Aceptable entonces
  Inicio
AnotarOpcion;
   Si SolucionIncompleta entonces
Backtracking(etapa_siguiente);
     Si NOT éxito entonces
CancelarAnotacion;
End
   Else /*Solución Completa*/
Éxito = true;
   End
  End
Until(Exito) OR (UltimaOpcion)
End Backtracking.

En este esquema se puede observar que están presentes tres elementos principales. En primer
lugar hay una generación de descendientes, en donde para cada nodo generamos sus
descendientes con posibilidad de solución. A este paso se le denomina expansión, ramificación o
bifurcación. A continuación, y para cada uno de estos descendientes, debe de aplicar lo que se
denomina prueba de fracaso (segundo elemento). Finalmente, caso de que sea aceptable este
nodo, aplicaran la prueba de solución (tercer elemento) que comprueba si el nodo que es posible
solución efectivamente lo es. Tal vez lo más difícil de ver en este esquema es donde se realiza la
vuelta atrás, y para ello han de pensar en la propia recursión y su mecanismo de funcionamiento,
que es la que permite ir recorriendo el árbol en profundidad. Cuando se desea encontrar todas las
soluciones habrá que alterar ligeramente el esquema dado, de forma que una vez conseguida una
solución se continúe buscando hasta agotar todas las posibilidades. Queda por tanto el siguiente
esquema general para este caso:

Algoritmo BacktrackingTodaslasSoluciones(etapa)

Inicio
IniciarOpciones;
 Repetir
SeleccionarNuevaOpcion;
   Si Aceptable entonces
AnotarOpcion;
       Si SolucionIncompleta entonces
BactrackingTodaslasSoluciones(etapa_siguiente);
Else
ComuncicarSolucion;
End;
CancelarAnotacion;
End;
Until(UltimaOpcion); EndBacktrackingTodaslasSoluciones;

Eficiencia y complejidad del método

Gran parte de la eficiencia (siempre relativa) de un algoritmo de Vuelta Atrás proviene de
considerar el menor conjunto de nodos que puedan llegar a ser soluciones, aunque siempre
asegurar de que el árbol “podado” siga conteniendo todas las soluciones. Por otra parte debe
tener cuidado a la hora de decidir el tipo de condiciones (restricciones) que comprueban en cada
nodo a fin de detectar nodos fracaso. Evidentemente el análisis de estas restricciones permite
ahorrar tiempo, al delimitar el tamaño del árbol a explorar. Sin embargo esta evaluación requiere
a su vez tiempo extra, de manera que aquellas restricciones que vayan a detectar pocos nodos
fracaso no serán normalmente interesantes. No obstante, y como norma de actuación general,
podrías decir que las restricciones sencillas son siempre apropiadas, mientras que las más
sofisticadas que requieren más tiempo en su cálculo deberían reservarse para situaciones en las
que el árbol que se genera sea muy grande.

Usualmente los algoritmos Vuelta Atrás(backtracking) son de complejidad exponencial por la
forma en la que se busca la solución mediante el recorrido en profundidad del árbol. De esta
forma estos algoritmos van a ser de un orden de complejidad al menos del número de nodos del
árbol que se generen y este número, si no se utilizan restricciones, es de orden de zⁿ donde z son
las posibles opciones que existen en cada etapa, y n el número de etapas que es necesario
recorrer hasta construir la solución (esto es, la profundidad del árbol o la longitud de la n-tupla
solución). El uso de restricciones, tanto implícitas como explícitas, trata de reducir este número
tanto como sea posible, pero sin embargo en muchos casos no son suficientes para conseguir
algoritmos “tratables”, es decir, que sus tiempos de ejecución sean de orden de complejidad
razonable. Para aquellos problemas en donde se busca una solución y no todas, es donde entra en
juego la posibilidad de considerar distintas formas de ir generando los nodos del árbol. Y como
la búsqueda que realiza la Vuelta Atrás es siempre en profundidad, para lograr esto sólo debe de
ir variando el orden en el que se generan los descendientes de un nodo, de manera que trate de
ser lo más apropiado a nuestra estrategia.
El problema de las N reinas
Implementacion
    - Distinta columna:
Todos los xi diferentes.
    - Distinta diagonal:
Las reinas (i,j) y (k,l) estan
en la misma diagonal sii-j=k-l o bien i+j=k+l,
lo que se puede resumir en|j-l| = |k-i|.
En terminos de los xi, tendremos |xk-xi|=|k-i|. 100

// Comprobar si la reina de la fila k está bien colocada
// (si no está en la misma columna ni en la misma diagonal
// que cualquiera de las reinas de las filas anteriores)
// Eficiencia: O(k-1).
bool comprobar (int reinas[], int n, int k)
{
inti;
for (i=0; i<k; i++)
if ( ( reinas[i]==reinas[k] )
|| ( abs(k-i) == abs(reinas[k]-reinas[i]) ) )
return false;
return true;
}

Implementacion recursiva
mostrando todas las soluciones
// Inicialmente, k=0 y reinas[i]=-1.
voidNReinas (int reinas[], int n, int k)
{
if (k==n) { // Solución (no quedan reinas por colocar)
print(reinas,n);
} else { // Aún quedan reinas por colocar (k<n)
for (reinas[k]=0; reinas[k]<n; reinas[k]++)
if (comprobar(reinas,n,k))
NReinas (reinas, n, k+1);
}}

mostrando solo la primera solucion
boolNReinas (int reinas[], int n, int k)
{
bool ok = false;
if (k==n) { // Caso base: No quedan reinas por colocar
ok = true;
} else { // Aún quedan reinas por colocar (k<n)
while ((reinas[k]<n-1) && !ok) {
reinas[k]++;
if (comprobar(reinas,n,k))
ok = NReinas (reinas, n, k+1);
}}
return ok; // La solución está en reinas[] cuando ok==true
}

Implementacion iterativa
mostrando todas las soluciones
voidNReinas (int reinas[], int n)
{
int k=0; // Fila actual = k
for (inti=0; i<n; i++) reinas[i]=-1; // Configuracióninicial
while (k>=0) {
reinas[k]++; // Colocar reina k en la siguiente columna…
while ((reinas[k]<n) && !comprobar(reinas,n,k))
reinas[k]++;
if (k<n) { // Reina colocada
if (k==n-1) { print(reinas,n); // Solución
} else { k++; reinas[k] = -1; } // Siguiente reina
} else { k--; }
}}
Conclusion:

Bibliografia:

http://www.ecured.cu/index.php/Backtracking
http://www.lcc.uma.es/~av/Libro/CAP6.pdf

Más contenido relacionado

La actualidad más candente

Backtracking
BacktrackingBacktracking
Backtracking
Antonio Cantillo
 
Tipos de Colas en Programación en C++ - Presentación
Tipos de Colas en Programación en C++ - PresentaciónTipos de Colas en Programación en C++ - Presentación
Tipos de Colas en Programación en C++ - Presentación
Fernando Solis
 
Búsqueda no informada - Búsqueda bidireccional
Búsqueda no informada - Búsqueda  bidireccionalBúsqueda no informada - Búsqueda  bidireccional
Búsqueda no informada - Búsqueda bidireccional
Laura Del Pino Díaz
 
Mis practicas de karel
Mis practicas de karelMis practicas de karel
Mis practicas de karel
Hammet Young Gomez
 
Listas (java)
Listas (java)Listas (java)
Listas (java)
CARLOS HERNANDEZ
 
Producto medio para generar números aleatorios.
Producto medio para generar números aleatorios.Producto medio para generar números aleatorios.
Producto medio para generar números aleatorios.
Leopoldo N. Chavez
 
Manipulacion de la pila!!
Manipulacion de la pila!!Manipulacion de la pila!!
Manipulacion de la pila!!
romo91
 
Diapositivas
DiapositivasDiapositivas
Diapositivas
pensamientos
 
Arbol de costo_minimo
Arbol de costo_minimoArbol de costo_minimo
Arbol de costo_minimo
Frank Resurrection
 
Sistemas Operativos - Semáforos
Sistemas Operativos - SemáforosSistemas Operativos - Semáforos
Sistemas Operativos - Semáforos
Juan Rojas
 
3. algoritmos de ordenamiento interno
3. algoritmos de ordenamiento interno3. algoritmos de ordenamiento interno
3. algoritmos de ordenamiento interno
Fernando Solis
 
Shell exposición
Shell exposiciónShell exposición
Shell exposición
Fercho Junca
 
Introduccion a la poo
Introduccion a la pooIntroduccion a la poo
Introduccion a la poo
Boris Salleg
 
Queues
Queues Queues
Queues
nidhisatija1
 
Punteros y Arreglos
Punteros y ArreglosPunteros y Arreglos
Punteros y Arreglos
Matías Magni
 
Ejercicios de búsqueda a Ciegas y Búsqueda informada
Ejercicios de búsqueda a Ciegas y Búsqueda informadaEjercicios de búsqueda a Ciegas y Búsqueda informada
Ejercicios de búsqueda a Ciegas y Búsqueda informada
Héctor Estigarribia
 
Método de Búsqueda Hash
Método de Búsqueda HashMétodo de Búsqueda Hash
Método de Búsqueda Hash
Blanca Parra
 
Programación 3: Grafos, representación y operaciones
Programación 3: Grafos, representación y operacionesProgramación 3: Grafos, representación y operaciones
Programación 3: Grafos, representación y operaciones
Angel Vázquez Patiño
 
Pilas en Java
Pilas en JavaPilas en Java
Pilas en Java
VICTOR VIERA BALANTA
 
Analizador léxico
Analizador léxicoAnalizador léxico
Analizador léxico
Silvestre Sosa
 

La actualidad más candente (20)

Backtracking
BacktrackingBacktracking
Backtracking
 
Tipos de Colas en Programación en C++ - Presentación
Tipos de Colas en Programación en C++ - PresentaciónTipos de Colas en Programación en C++ - Presentación
Tipos de Colas en Programación en C++ - Presentación
 
Búsqueda no informada - Búsqueda bidireccional
Búsqueda no informada - Búsqueda  bidireccionalBúsqueda no informada - Búsqueda  bidireccional
Búsqueda no informada - Búsqueda bidireccional
 
Mis practicas de karel
Mis practicas de karelMis practicas de karel
Mis practicas de karel
 
Listas (java)
Listas (java)Listas (java)
Listas (java)
 
Producto medio para generar números aleatorios.
Producto medio para generar números aleatorios.Producto medio para generar números aleatorios.
Producto medio para generar números aleatorios.
 
Manipulacion de la pila!!
Manipulacion de la pila!!Manipulacion de la pila!!
Manipulacion de la pila!!
 
Diapositivas
DiapositivasDiapositivas
Diapositivas
 
Arbol de costo_minimo
Arbol de costo_minimoArbol de costo_minimo
Arbol de costo_minimo
 
Sistemas Operativos - Semáforos
Sistemas Operativos - SemáforosSistemas Operativos - Semáforos
Sistemas Operativos - Semáforos
 
3. algoritmos de ordenamiento interno
3. algoritmos de ordenamiento interno3. algoritmos de ordenamiento interno
3. algoritmos de ordenamiento interno
 
Shell exposición
Shell exposiciónShell exposición
Shell exposición
 
Introduccion a la poo
Introduccion a la pooIntroduccion a la poo
Introduccion a la poo
 
Queues
Queues Queues
Queues
 
Punteros y Arreglos
Punteros y ArreglosPunteros y Arreglos
Punteros y Arreglos
 
Ejercicios de búsqueda a Ciegas y Búsqueda informada
Ejercicios de búsqueda a Ciegas y Búsqueda informadaEjercicios de búsqueda a Ciegas y Búsqueda informada
Ejercicios de búsqueda a Ciegas y Búsqueda informada
 
Método de Búsqueda Hash
Método de Búsqueda HashMétodo de Búsqueda Hash
Método de Búsqueda Hash
 
Programación 3: Grafos, representación y operaciones
Programación 3: Grafos, representación y operacionesProgramación 3: Grafos, representación y operaciones
Programación 3: Grafos, representación y operaciones
 
Pilas en Java
Pilas en JavaPilas en Java
Pilas en Java
 
Analizador léxico
Analizador léxicoAnalizador léxico
Analizador léxico
 

Destacado

Algoritmo de backtracking
Algoritmo de backtrackingAlgoritmo de backtracking
Algoritmo de backtracking
Victor Gonzalez
 
Busqueda por profundidad iterativa
Busqueda por profundidad iterativaBusqueda por profundidad iterativa
Busqueda por profundidad iterativa
Israel Calderón de la Cruz
 
Esquema algorítmico del backtracking
Esquema algorítmico del  backtrackingEsquema algorítmico del  backtracking
Esquema algorítmico del backtracking
Wilmer Quintero
 
Backtracking
BacktrackingBacktracking
Backtracking
Inael Rodrigues
 
Vuelta Atras
Vuelta AtrasVuelta Atras
Vuelta atrás o (backtracking)
Vuelta atrás o (backtracking)Vuelta atrás o (backtracking)
Vuelta atrás o (backtracking)
Giancarlo Gutierrez
 
Vuelta atrás (backtraking)
Vuelta atrás (backtraking)Vuelta atrás (backtraking)
Vuelta atrás (backtraking)
edopaz
 

Destacado (7)

Algoritmo de backtracking
Algoritmo de backtrackingAlgoritmo de backtracking
Algoritmo de backtracking
 
Busqueda por profundidad iterativa
Busqueda por profundidad iterativaBusqueda por profundidad iterativa
Busqueda por profundidad iterativa
 
Esquema algorítmico del backtracking
Esquema algorítmico del  backtrackingEsquema algorítmico del  backtracking
Esquema algorítmico del backtracking
 
Backtracking
BacktrackingBacktracking
Backtracking
 
Vuelta Atras
Vuelta AtrasVuelta Atras
Vuelta Atras
 
Vuelta atrás o (backtracking)
Vuelta atrás o (backtracking)Vuelta atrás o (backtracking)
Vuelta atrás o (backtracking)
 
Vuelta atrás (backtraking)
Vuelta atrás (backtraking)Vuelta atrás (backtraking)
Vuelta atrás (backtraking)
 

Similar a Busqueda por backtracking

Daniela mendozaestructuradedatosii
Daniela mendozaestructuradedatosiiDaniela mendozaestructuradedatosii
Daniela mendozaestructuradedatosii
DanielaMendoza117
 
Esquema algorítmico del backtracking
Esquema algorítmico del  backtrackingEsquema algorítmico del  backtracking
Esquema algorítmico del backtracking
Wilmer Quintero
 
Backtracking
BacktrackingBacktracking
Backtracking
Christian Sanchez
 
Backtracking
BacktrackingBacktracking
Backtracking
Omar Daza
 
Slideshare nelson rodriguez
Slideshare nelson rodriguezSlideshare nelson rodriguez
Slideshare nelson rodriguez
nelro038
 
Técnica del backtracking o vuelta atrás
Técnica del backtracking o vuelta atrásTécnica del backtracking o vuelta atrás
Técnica del backtracking o vuelta atrás
Esperanza Terán Jiménez
 
Programación Dinámica
Programación DinámicaProgramación Dinámica
Programación Dinámica
KimLinares
 
Programacion dinamica
Programacion dinamicaProgramacion dinamica
Programacion dinamica
genesisptc_
 
Enfoques
EnfoquesEnfoques
Enfoques
Jhoan Tenjo
 
PROGRAMACION DINAMICA
PROGRAMACION DINAMICAPROGRAMACION DINAMICA
PROGRAMACION DINAMICA
JOSEPHBADRA3
 
Pro no num Prog dinamica
Pro no num Prog dinamicaPro no num Prog dinamica
Pro no num Prog dinamica
Ruben Gonzalez
 
clase1_TecDiseño_2021.ppsx
clase1_TecDiseño_2021.ppsxclase1_TecDiseño_2021.ppsx
clase1_TecDiseño_2021.ppsx
CesarR26
 
Tecnicas de busqueda en inteligencia artificial
Tecnicas de busqueda en inteligencia artificialTecnicas de busqueda en inteligencia artificial
Tecnicas de busqueda en inteligencia artificial
DamelysCarrillo2
 
Teoria de Optimizacion
Teoria de  OptimizacionTeoria de  Optimizacion
Teoria de Optimizacion
rebeca ferrer
 
Sistemas inteligentes
Sistemas inteligentesSistemas inteligentes
Sistemas inteligentes
Julissa Cardona
 
Solución de problemas mediante busqueda
Solución de problemas mediante busquedaSolución de problemas mediante busqueda
Solución de problemas mediante busqueda
sacrilegetx
 
Optimizacion Angel Peña
Optimizacion Angel PeñaOptimizacion Angel Peña
Optimizacion Angel Peña
Angel Peña
 
Diapositiva prog no numerica 2 algoritmo voraces
Diapositiva prog no numerica 2 algoritmo voracesDiapositiva prog no numerica 2 algoritmo voraces
Diapositiva prog no numerica 2 algoritmo voraces
Ariannys Romero Parra
 
Analisis y diseño de algoritmo
Analisis y diseño de algoritmoAnalisis y diseño de algoritmo
Analisis y diseño de algoritmo
Jose Lluberes
 
Enfoques
EnfoquesEnfoques

Similar a Busqueda por backtracking (20)

Daniela mendozaestructuradedatosii
Daniela mendozaestructuradedatosiiDaniela mendozaestructuradedatosii
Daniela mendozaestructuradedatosii
 
Esquema algorítmico del backtracking
Esquema algorítmico del  backtrackingEsquema algorítmico del  backtracking
Esquema algorítmico del backtracking
 
Backtracking
BacktrackingBacktracking
Backtracking
 
Backtracking
BacktrackingBacktracking
Backtracking
 
Slideshare nelson rodriguez
Slideshare nelson rodriguezSlideshare nelson rodriguez
Slideshare nelson rodriguez
 
Técnica del backtracking o vuelta atrás
Técnica del backtracking o vuelta atrásTécnica del backtracking o vuelta atrás
Técnica del backtracking o vuelta atrás
 
Programación Dinámica
Programación DinámicaProgramación Dinámica
Programación Dinámica
 
Programacion dinamica
Programacion dinamicaProgramacion dinamica
Programacion dinamica
 
Enfoques
EnfoquesEnfoques
Enfoques
 
PROGRAMACION DINAMICA
PROGRAMACION DINAMICAPROGRAMACION DINAMICA
PROGRAMACION DINAMICA
 
Pro no num Prog dinamica
Pro no num Prog dinamicaPro no num Prog dinamica
Pro no num Prog dinamica
 
clase1_TecDiseño_2021.ppsx
clase1_TecDiseño_2021.ppsxclase1_TecDiseño_2021.ppsx
clase1_TecDiseño_2021.ppsx
 
Tecnicas de busqueda en inteligencia artificial
Tecnicas de busqueda en inteligencia artificialTecnicas de busqueda en inteligencia artificial
Tecnicas de busqueda en inteligencia artificial
 
Teoria de Optimizacion
Teoria de  OptimizacionTeoria de  Optimizacion
Teoria de Optimizacion
 
Sistemas inteligentes
Sistemas inteligentesSistemas inteligentes
Sistemas inteligentes
 
Solución de problemas mediante busqueda
Solución de problemas mediante busquedaSolución de problemas mediante busqueda
Solución de problemas mediante busqueda
 
Optimizacion Angel Peña
Optimizacion Angel PeñaOptimizacion Angel Peña
Optimizacion Angel Peña
 
Diapositiva prog no numerica 2 algoritmo voraces
Diapositiva prog no numerica 2 algoritmo voracesDiapositiva prog no numerica 2 algoritmo voraces
Diapositiva prog no numerica 2 algoritmo voraces
 
Analisis y diseño de algoritmo
Analisis y diseño de algoritmoAnalisis y diseño de algoritmo
Analisis y diseño de algoritmo
 
Enfoques
EnfoquesEnfoques
Enfoques
 

Busqueda por backtracking

  • 1. BUSQUEDA POR BACKTRACKING Introduccion: Backtracking:Dentro de las técnicas de diseño de algoritmos, el método de Vuelta Atrás (del inglés Backtracking) es uno de los de más amplia utilización, en el sentido de que puede aplicarse en la resolución de un gran número de problemas, muy especialmente en aquellos de optimización. En ocasiones se ven enfrentados a problemas de optimización que solo pueden ser resueltos a través de un estudio exhaustivo de un conjunto conocido a priori de posibles soluciones, en las que se trata de encontrar una o todas las soluciones y por tanto también la óptima. Para llevar a cabo este estudio exhaustivo, el diseño Vuelta Atrás proporciona una manera sistemática de generar todas las posibles soluciones siempre que dichas soluciones sean susceptibles de resolverse en etapas. Objetivo: Investigar y desarrollar el método de búsqueda por Backtracking (vuelta a tras), para comprender el método de búsqueda. Marco Teorico: Técnica de Backtracking En su forma básica la Vuelta Atrás se asemeja a un recorrido en profundidad dentro de un árbol cuya existencia sólo es implícita, y que se denomina árbol de expansión. Este árbol es conceptual, en donde cada nodo de nivel k representa una parte de la solución y está formado por k etapas que se suponen ya realizadas. Sus hijos son las prolongaciones posibles al añadir una nueva etapa. Para examinar el conjunto de posibles soluciones es suficiente recorrer este árbol construyendo soluciones parciales a medida que se avanza en el recorrido. En este recorrido pueden suceder dos cosas. La primera es que tenga éxito si, procediendo de esta manera, se llega a una solución (una hoja del árbol). Si lo único que buscábamos era una solución al problema, el algoritmo finaliza aquí; ahora bien, si lo que se busca eran todas las soluciones o la mejor de entre todas ellas, el algoritmo seguirá explorando el árbol en búsqueda de soluciones alternativas.Por otra parte, el recorrido no tiene éxito si en alguna etapa la solución parcial construida hasta el momento no se puede completar; s encuentran en lo que llamamos nodos fracaso. En tal caso, el algoritmo vuelve atrás (y de ahí su nombre) en su recorrido eliminando los elementos que se hubieran añadido en cada etapa a partir de ese nodo. Si en este retroceso, si existe uno o más caminos aún no explorados que puedan conducir a solución, el recorrido del árbol continúa por ellos. Algoritmo Genético El algoritmo genérico del backtracking es el siguiente: Inicio
  • 2. IniciarOpciones; Repetir SeleccionarNuevaOpcion; Si Aceptable entonces Inicio AnotarOpcion; Si SolucionIncompleta entonces Backtracking(etapa_siguiente); Si NOT éxito entonces CancelarAnotacion; End Else /*Solución Completa*/ Éxito = true; End End Until(Exito) OR (UltimaOpcion) End Backtracking. En este esquema se puede observar que están presentes tres elementos principales. En primer lugar hay una generación de descendientes, en donde para cada nodo generamos sus descendientes con posibilidad de solución. A este paso se le denomina expansión, ramificación o bifurcación. A continuación, y para cada uno de estos descendientes, debe de aplicar lo que se denomina prueba de fracaso (segundo elemento). Finalmente, caso de que sea aceptable este nodo, aplicaran la prueba de solución (tercer elemento) que comprueba si el nodo que es posible solución efectivamente lo es. Tal vez lo más difícil de ver en este esquema es donde se realiza la vuelta atrás, y para ello han de pensar en la propia recursión y su mecanismo de funcionamiento, que es la que permite ir recorriendo el árbol en profundidad. Cuando se desea encontrar todas las soluciones habrá que alterar ligeramente el esquema dado, de forma que una vez conseguida una solución se continúe buscando hasta agotar todas las posibilidades. Queda por tanto el siguiente esquema general para este caso: Algoritmo BacktrackingTodaslasSoluciones(etapa) Inicio IniciarOpciones; Repetir SeleccionarNuevaOpcion; Si Aceptable entonces AnotarOpcion; Si SolucionIncompleta entonces BactrackingTodaslasSoluciones(etapa_siguiente); Else ComuncicarSolucion; End; CancelarAnotacion; End;
  • 3. Until(UltimaOpcion); EndBacktrackingTodaslasSoluciones; Eficiencia y complejidad del método Gran parte de la eficiencia (siempre relativa) de un algoritmo de Vuelta Atrás proviene de considerar el menor conjunto de nodos que puedan llegar a ser soluciones, aunque siempre asegurar de que el árbol “podado” siga conteniendo todas las soluciones. Por otra parte debe tener cuidado a la hora de decidir el tipo de condiciones (restricciones) que comprueban en cada nodo a fin de detectar nodos fracaso. Evidentemente el análisis de estas restricciones permite ahorrar tiempo, al delimitar el tamaño del árbol a explorar. Sin embargo esta evaluación requiere a su vez tiempo extra, de manera que aquellas restricciones que vayan a detectar pocos nodos fracaso no serán normalmente interesantes. No obstante, y como norma de actuación general, podrías decir que las restricciones sencillas son siempre apropiadas, mientras que las más sofisticadas que requieren más tiempo en su cálculo deberían reservarse para situaciones en las que el árbol que se genera sea muy grande. Usualmente los algoritmos Vuelta Atrás(backtracking) son de complejidad exponencial por la forma en la que se busca la solución mediante el recorrido en profundidad del árbol. De esta forma estos algoritmos van a ser de un orden de complejidad al menos del número de nodos del árbol que se generen y este número, si no se utilizan restricciones, es de orden de zⁿ donde z son las posibles opciones que existen en cada etapa, y n el número de etapas que es necesario recorrer hasta construir la solución (esto es, la profundidad del árbol o la longitud de la n-tupla solución). El uso de restricciones, tanto implícitas como explícitas, trata de reducir este número tanto como sea posible, pero sin embargo en muchos casos no son suficientes para conseguir algoritmos “tratables”, es decir, que sus tiempos de ejecución sean de orden de complejidad razonable. Para aquellos problemas en donde se busca una solución y no todas, es donde entra en juego la posibilidad de considerar distintas formas de ir generando los nodos del árbol. Y como la búsqueda que realiza la Vuelta Atrás es siempre en profundidad, para lograr esto sólo debe de ir variando el orden en el que se generan los descendientes de un nodo, de manera que trate de ser lo más apropiado a nuestra estrategia.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8. El problema de las N reinas Implementacion - Distinta columna: Todos los xi diferentes. - Distinta diagonal: Las reinas (i,j) y (k,l) estan en la misma diagonal sii-j=k-l o bien i+j=k+l, lo que se puede resumir en|j-l| = |k-i|. En terminos de los xi, tendremos |xk-xi|=|k-i|. 100 // Comprobar si la reina de la fila k está bien colocada // (si no está en la misma columna ni en la misma diagonal // que cualquiera de las reinas de las filas anteriores) // Eficiencia: O(k-1). bool comprobar (int reinas[], int n, int k) { inti; for (i=0; i<k; i++) if ( ( reinas[i]==reinas[k] ) || ( abs(k-i) == abs(reinas[k]-reinas[i]) ) )
  • 9. return false; return true; } Implementacion recursiva mostrando todas las soluciones // Inicialmente, k=0 y reinas[i]=-1. voidNReinas (int reinas[], int n, int k) { if (k==n) { // Solución (no quedan reinas por colocar) print(reinas,n); } else { // Aún quedan reinas por colocar (k<n) for (reinas[k]=0; reinas[k]<n; reinas[k]++) if (comprobar(reinas,n,k)) NReinas (reinas, n, k+1); }} mostrando solo la primera solucion boolNReinas (int reinas[], int n, int k) { bool ok = false; if (k==n) { // Caso base: No quedan reinas por colocar ok = true; } else { // Aún quedan reinas por colocar (k<n) while ((reinas[k]<n-1) && !ok) { reinas[k]++; if (comprobar(reinas,n,k)) ok = NReinas (reinas, n, k+1); }} return ok; // La solución está en reinas[] cuando ok==true } Implementacion iterativa mostrando todas las soluciones voidNReinas (int reinas[], int n) { int k=0; // Fila actual = k for (inti=0; i<n; i++) reinas[i]=-1; // Configuracióninicial while (k>=0) { reinas[k]++; // Colocar reina k en la siguiente columna… while ((reinas[k]<n) && !comprobar(reinas,n,k)) reinas[k]++; if (k<n) { // Reina colocada if (k==n-1) { print(reinas,n); // Solución } else { k++; reinas[k] = -1; } // Siguiente reina } else { k--; } }}