Escolar Documentos
Profissional Documentos
Cultura Documentos
Backtracking(BT)
Bsqueda con retroceso o Backtracking
Elemento buscado
CARACTERSTICAS DEL ARBOL
La Altura
Hay k posibles decisiones que debemos tomar para
llegar a una solucin.
La Anchura
Cada decisin debe tomarse de un conjunto de
alternativas distintas (dominio).
DIMENSIONES
Anchura: nmero de alternativas (candidatos)
Altura
(profundidad):
La cantidad de
decisiones que
debemos tomar
0 1
0 1 0 1
0 1 0 1 0 1 0 1
0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
Por ejemplo, el camino 1011 significa que se tomaron el primer, tercer y cuarto
artculos y no se tomo el segundo.
# include <iostream>
using namespace std; Cdigo
# define MAX 20 void BT (int k, int n, bool decision[ ])
void BT(int, int, bool [ ]); {
void imprimir(int, bool[ ]); bool cand[MAX];
int construyeCandidatos(bool [ ]);
void main(void) if (k==n)
{ int i, n; imprimir(n, decision);
bool decision[MAX]; else {
cout<<"Nro de elementos:"; int ncand=construyeCandidatos(cand);
cin>>n; for(int i=0; i<ncand; i++) {
decision[k]= cand[i];
// marcamos objetos como no escogidos BT(k+1, n, decision);
for(i=0; i<n; i++) }
decision[i]=false; }
BT(0, n, decision); }
}
int construyeCandidatos(bool cand[]) {
void imprimir(int n, bool decision[ ]) { cand[0]=true;
for(int i=0; i<n; i++) cand[1]=false;
cout<<decision[i]<<" "; return 2;
cout<<endl; }
}
Clculo de la complejidad
Dado que en cada llamada recursiva se invoca 2 veces a la misma
funcin y como hay n invocaciones por cada llamada recursiva, su
complejidad es:
(2n)
Note que al tener una complejidad exponencial, el backtraking no es una
tcnica muy eficiente, pero su ventaja es que siempre encontrar la
solucin si es que existe y si tuviramos todo el tiempo del mundo.
Podemos elegir no recorrer todos los nodos del rbol si sabemos que no
nos llevar a la solucin buscada. Para esto usamos restricciones que
pueden ser dadas en el enunciado de manera explcita o implcita.
0 1
2 2
0 0
1 1
3 3
0 1 3 0 1 3
0 1 0 1
6 6 6 6
0 1 0 1 6 6 0 1 0 1 6 6
0 1 0 1 0 1 0 1
1 1 1 1 1 1 1 1
0
1 0 0 1 0 1 1 1 1 10 1 0 1 0 0 1 1 1 1 1
1 0 1 0 1 0 1 0 1 0
5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 1 0 1 0 1 0 1
5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5
#include <iostream> void bt(int k)
using namespace std; { bool cand[LIM];
#define LIM 20
int suma(int); if (k==n) return; // condicin base
int buscaCandidatos(bool []); int ncand = buscaCandidatos(cand);
void bt(int); for(int i=0; i<ncand; i++)
void impSol(int); { seleccion[k] = cand[i];
int n; // nro de elementos int s=suma(k);
int objetivo; // suma objetivo
int x[LIM]; // elementos if( s==objetivo ) impSol(k);
bool seleccion[LIM]; // objetos elegidos else if( s<objetivo ) bt(k+1);
int main() }
{ int i; }
cout<<"Nro de elementos: "; cin>>n; int buscaCandidatos(bool cand[ ])
cout<<"Objetivo: "; cin>>objetivo;
// marco todos como no seleccionados { cand[0]=true;
for(i=0; i<n; i++) seleccion[i]=false; cand[1]=false;
cout<<"Ingrese elementos: "; return 2;
for(i=0; i<n; i++) cin>>x[i]; }
bt(0); int suma(int k)
}
void impSol(int k) { int sum=0;
{ for(int j=0; j<=k; j++) for(int j=0; j<=k; j++)
if( seleccion[j]==1 ) if( seleccion[j]==1) sum += x[j];
cout<<x[j]<<" "; return sum;
cout<<endl; }
}
Variaciones
1
Ejemplo:
Vectores para el Problema 4 reinas
R
R 2 0 3 1
R 0 1 2 3
R R
2 0 3 0
R 0 1 2 3
Como no puede haber mas de una reina en una misma columna, entonces
podemos restringir el nmero de candidatos desde un principio, usando un
vector donde cada posicin i, indica la columna en que se encuentra la
reina, y el valor indica la fila en que se encuentra la reina.
R
R R R R R
R
R
R
R R R R R
R
R R R R R
R
Ejemplo:
rbol para Problema 4 reinas
Existen 2 Soluciones
EL PROBLEMA DE LAS N REINAS
# include <iostream>
using namespace std;
#define MAXCANDIDATOS 100
#define NMAX 20 // mximo tamao del tablero
int nroSol,n; // cuenta soluciones
int solucion[NMAX];
void imprimeSolucion() {
for(int i=0; i<n; i++) {
for(int j=0; j<n; j++)
if( i==solucion[j] )
cout<<'R'<<' ';
else
cout<<'-'<<' ';
cout<<endl;
}
cout<<endl;
nroSol ++;
}
EL PROBLEMA DE LAS N REINAS
int construyeCandidatos(int k, int candi[]) {
int ncandidatos = 0;
for (int i=0; i<n; i++) {
bool band = true;
for (int j=0; j<k; j++) {
// restriccion de diagonal y de fila
if ( abs(k-j) == abs(i-solucion[j]) || i == solucion[j] )
band = false; break;
}
if (band) { int main(){
candi[ncandidatos] = i; cout<<"Medida del tablero: ";
ncandidatos++; cin>>n;
} nroSol = 0;
} BT(0);
return ncandidatos; cout<<"Num. Soluciones="<< nroSol;
} return 0;
}
Agregar
TAREA: funcin BT()