You are on page 1of 17

ALGORÍTMICA

Backtracking.
1. Método general.
2. Ejemplos de aplicación.
2.1. Problema de las N reinas.
2.2 Problema del Laberinto.
2.3 Coloreado de Grafos.
2.4 Resolución de juegos.

Backtracking.
1
1. Método general.
• El backtracking (método de retroceso ó vuelta atrás) es
una técnica general de resolución de problemas, aplicable
tanto a problemas de optimización, juegos y otros tipos.
• El backtracking realiza una búsqueda exhaustiva y
sistemática en el espacio de soluciones. Por ello, suele
resultar ineficiente.
• La solución de un problema de backtracking se puede
expresar como una tupla (x1, x2, ..., xn), satisfaciendo unas
restricciones P(x1, x2, ..., xn) y tal vez optimizando una cierta
función objetivo.
• En cada momento, el algoritmo se encontrará en un cierto
nivel k, con una solución parcial (x1, ..., xk). Si esta solución
parcial es válida se puede añadir un nuevo elemento a la
solución avanzando al nivel k+1 y probando los valores
para xk+1
Backtracking.
2
1. Método general.
• Si no, se prueban otros valores de xk.
• Si no existe ningún otro valor posible por probar, entonces se
retrocede al nivel anterior k-1.
• Se sigue hasta que la solución parcial sea una solución
completa del problema, o hasta que no queden más
posibilidades.
• El resultado es equivalente a hacer un recorrido en
profundidad en el árbol de soluciones. Sin embargo, este
árbol es implícito, no se almacena en ningún lugar.

• Ejemplo. Dado un conjunto de números enteros {13, 11, 7},


encontrar si existe algún subconjunto cuya suma sea
exactamente 20.
Backtracking.
3
1. Método general.
• Posibilidad 1) En cada nivel i decidir si el elemento i está o
no en la solución. Representación de la solución: (x1, x2, x3),
donde xi= (0, 1).
1
0 1 k=1 (13)
Árbol de
soluciones 1 0 2 1 0
9
1 k=2 (11)

3 6 10 13
0 1 0 1 0 1 0 1 k=3 (7)
4 5 7 8 11 12 14 15
0 7 11 18 13 20 24 31 Sumas totales
• Cada nodo representa un paso del algoritmo, una solución parcial en
cada momento dado. El árbol indica un orden de ejecución (recorrido
en profundidad) pero no se almacena en ningún lugar.
• Una solución es un nodo hoja con valor de suma 20.
• Posible mejora: No probar con los nodos cuya suma va a exceder el
valor 20.
Backtracking.
4
1. Método general.
SUBPROGRAMA BackTracking (IN k:INTEGER,OUT Solucion:INTEGER[1..N],
IN Suma:INTEGER, OUT Fin:BOOLEAN, IN PMAX:INTEGER,
IN Valor:INTEGER[1..N]):void
BEGIN
IF (K > N) THEN
IF (Suma==PMAX) THEN Fin=TRUE;
ELSE
BEGIN
Solucion[k]=0;
Backtracking(k+1,Solucion,Suma,Fin,PMAX,Valor);
IF (¬ FIN) THEN
BEGIN
Solucion[k]=1;
Backtracking(k+1,Solucion,Suma+Valor[k],
Fin,PMAX,Valor);
END
END
END;
 Backtarcking(1,(0,0,0),0,FALSE,20,(13,11,7));

Backtracking.
5
1. Método general.
• Posibilidad 2) En cada nivel i decidir qué elemento se añade (1, 2 ó 3).
Representación de la solución (s1, ..., sm), donde mn y si  {1, 2, 3}.

20
1
1 2 3 k=1
Árbol de
soluciones 2 7 2 9 13
6 8
3 3 k=2
0 5 2 7

k=3

• Cada nodo es una posible solución. Será válida si la suma es 20.


• El recorrido es también en profundidad.
• Necesitamos funciones para generar los nodos, para descartar
nodos y para saber si un nodo es solución.

Backtracking.
6
1. Método general.
SUBPROGRAMA BackTracking2(IN k:INTEGER,OUT Solucion:INTEGER[1..N],
IN Cantidad:INTEGER, IN elemento:INTEGER,IN Valor:INTEGER[1..N]):void
VAR
i:INTEGER;
BEGIN
FOR i IN k..N DO
BEGIN
IF (elemento<=N) ^ (Valor[elemento]<=Cantidad) THEN
BEGIN
Solucion[k]=elemento;
IF (Cantidad-Valor[elemento] == 0) THEN
PROCESAR(Solucion);
ELSE
Backtracking2(k+1,Solucion,
Cantidad-Valor[elemento], elemento+1,Valor);
END
elemento=elemento+1;
END
END;
 Backtarcking2(1,(0,0,0),20,1,(13,11,7));

Backtracking.
7
1. Método general.

k=3 Cant=2 Sol=(2,3,0) k=3 Cant=0 Sol=(1,3,0)


elem=4 i=3 elem=4 i=3

k=2 Cant=13 k=2 Cant=9 Sol=(2,0,0) k=2 Cant=7 Sol=(1,3,0)


Sol=(1,0,0)
Sol=(3,0,0) elem=3 i=3
elem=4 i=2 elem=2 i=3
elem=3 i=2
elem=4 i=2

k=1 Cant=20
Sol=(1,0,0)
Sol=(2,0,0)
Sol=(3,0,0)
elem=1 i=3
elem=2
elem=3 i=1
i=2

Backtracking.
8
1. Método general.

• Sea (x1, x2, ..., xi-1) un camino de la raíz hasta un nodo del
árbol del espacio de estados.
• Sea G(x1, x2, ..., xi-1) el conjunto de los valores posibles de xi
tales que (x1, x2, ..., xi) es un camino hasta un nodo del árbol.
• Suponemos que existe algún predicado acotador A tal que
A (x1, x2, ..., xi) es falso si el camino (x1, x2, ..., xi) no puede
extenderse para alcanzar un nodo de respuesta (i.e., una
solución).
• Por tanto, los candidatos para xi son los valores de G
tales que satisfacen A.
• Supongamos, finalmente, que existe un predicado R que
determina si un camino (x1, x2, ..., xi) termina en un nodo
respuesta (i.e., es ya una solución).

Backtracking.
9
1. Método general.
SUBPROGRAMA retroceso(IN k:INTEGER,
OUT solución:elemento[1..N]):void
VAR
nodo:elemento;
BEGIN
PARA TODO nodo en G(solución,1,k-1) DO
BEGIN
solución[k]=nodo;
IF A(solución,1,k)THEN
BEGIN
IF R(solución,1,k) THEN guardar(solución,1,k);
retroceso(k+1,solución);
END
END
END;
Backtracking.
10
1. Método general.
• Nótese que el árbol no se construye explícitamente
sino implícitamente mediante las llamadas recursivas
del algoritmo de búsqueda.

• El algoritmo no hace llamadas recursivas cuando:


- k = N+1, o cuando
- ningún nodo generado por G satisface A.

• Backtracking = búsqueda en profundidad y con


predicados acotadores.

• El algoritmo anterior halla todas las soluciones y


además éstas pueden ser de longitud variable.
Backtracking.
11
Variantes:
1. Método general.
•Limitar el número de soluciones a una sola añadiendo un
parámetro boolean de salida que indique si se ha
encontrado una solución.
•Forzar a que sólo los nodos hoja puedan significar
solución (realizando la recursión sólo si no se ha
encontrado un nodo solución):
IF R(solución,1,k) THEN
guardar(solución,1,k);
ELSE
retroceso(k+1,solución);
•Resolver problemas de optimización: además de la
solución actual en construcción hay que guardar la mejor
solución encontrada hasta el momento.
Backtracking.
12
Problema de las N reinas.

• El problema consiste en colocar N reinas en un tablero de ajedrez sin que


se den jaque (dos reinas se dan jaque si comparten fila, columna o
diagonal).

• Cada solución se representa por una n-tupla (x1, x2,.., xi), en la que xi es la
columna de la i-ésima fila en la que se coloca la i-ésima reina.

• El espacio de soluciones se reduce a n! elementos teniendo en cuenta que


todas ellas han de ser permutaciones de (1,2,…,n), es decir, todas las xi
han de ser distintas.

• Además, no deben compartir diagonal.


Backtracking.
13
Backtracking.
14
2.1 Problema de las n reinas.
Representación de la información:
• Debe permitir interpretar fácilmente la solución:
x:INTEGER[1..n] {x[i]=columna de la reina i en i-ésima fila}

Evaluación del predicado acotador:


• Utilizaremos una función buenSitio que devuelva el valor
verdad si la k-ésima reina se puede colocar en el valor x[k], es
decir, si está en distinta columna y diagonal que las k-1 reinas
anteriores.
• Dos reinas están en la misma diagonal si tienen el mismo
valor de “fila+columna”, mientras que están en la misma
diagonal si tienen el mismo valor de “fila-columna”.
( f 1 c1 f 2 c2) ( f 1 c1 f 2 c2)
 (c1 -c2 f 1 f 2) (c1 c2 f 2 f 1)
 c1 -c2| f 1 f 2| Backtracking.
15
2.1 Problema de las n reinas.
SUBPROGRAMA colocarReinas(IN k:INTEGER,
OUT solucion:INTEGER[1..N]):void
VAR
i:INTEGER;
BEGIN
FOR i IN 1..N DO
BEGIN
solucion[k]=i;
IF buenSitio(k,solucion) THEN
IF (k==n) THEN
escribir(solucion);
ELSE
colocarReinas(k+1,solucion);
END
END;
...
colocarReinas(1,solucion);
...

Backtracking.
16
2.1 Problema de las n reinas.
SUBPROGRAMA buenSitio(IN k:INTEGER; IN x:INTEGER[1..N]):BOOLEAN
{devuelve verdad si y sólo si se puede colocar una reina en la fila k y columna x[k],
habiendo sido colocadas ya las k-1 reinas anteriores}
VAR
i:INTEGER;
amenaza:BOOLEAN;
BEGIN
i=1;
amenaza=FALSE;
WHILE ((i<k) ^ ¬ amenaza) DO
BEGIN
IF ((x[i]==x[k])  abs(x[i]-x[k])==abs(i-k)) THEN
amenaza=TRUE;
ELSE
i=i+1;
 
END
return ¬ amenaza;
END;
Backtracking.
17

You might also like