Upload
zet1234
View
11
Download
0
Embed Size (px)
DESCRIPTION
IA
Citation preview
Algoritmia: Bsquedas y Recursividad
Pablo San Segundo (C-206)[email protected]
Ejemplo
1 2 3 4 5
6 8 9 10
11 12 14 15
16 17 18 D
21 22 23 O
GRADO DEL GRAFO?
Escribir un algoritmo que permita establecer si existe un camino desde O (24) a D (20)
Mapa de celdas
Algoritmo
1. N(O) := Vecinos de O2. Seleccin no determinista de un vrtice v de N(O)3. Si D est en N(O) FINSalida TRUE4. Repetir desde paso 1 para N(v)5. Salida FALSE
ASPECTOS DE IMPLEMENTACIN
Lista de NODOS_ABIERTOS
Lista de NODOS_VISITADOS
Operaciones
En el paso 1 se aaden a ABIERTOS los nuevos vecinos que no estn en VISITADOS ni en ABIERTOSEn el paso 3 se extrae un elemento de ABIERTOS y se pasa a VISITADOS
Detalles: iteracin dinmica set
set s;set::iterator it;it=s.begin();int v;while(it!=m_open.end() ) {
v=(*it);//.it++;
}
set s;set::iterator it;set::iterator it2;it=s.begin();int v;while(it!=m_open.end() ) {
v=(*it);//.(it2=it)++;v.erase(it);(it=it2);
}
set s;set::iterator it;set::iterator it2;it=s.begin();int v;int new_member=15;while(it!=m_open.end() ) {
v=(*it);//.v.insert (new_member);//.(it2=it)++;v.erase(it);(it=it2);if(it==v.end()){ //.correccin
it=v.begin();}
}
Funciones para manipular set
` bool SetOfInt::IsEmpty (const set& set)` bool SetOfInt::IsMember(const set& setA, int v)` void SetOfInt::ClearSet (set& set)
return set.empty();
if (setA.find(candidate) != setA.end()) {return true;
}else {
return false;}
return set.clear();
Programacin el ejemplo Path (I)Inicio: aadir vecinos de O a ABIERTOS y O a VISITADOS
m_closed.insert(m_o);for (int i=0; iGetSize(); i++){
if (m_pg->m_graph[m_o][i])m_open.insert(i);
}
Si v_sel est en VISITADOS, borrar de ABIERTOS y elegir siguiente vrtice de ABIERTOS
if(SetOfInt::IsMember(m_closed,v_sel)){(it2=it)++;m_open.erase(it);it=it2;
continue;}
Comprobar si el vrtice elegido es solucinif (v_sel==m_d) break;
Programacin del ejemplo Path (II)Aadir vecinos de vrtice elegido a ABIERTOS que no estn en CERRADOS
for (int i=0; iGetSize(); i++){if(m_pg->m_graph[v_sel][i] && ! SetOfInt::IsMember(m_closed,i) )m_open.insert(i);
}
Borrado del vrtice elegido de ABIERTOS
(it2=it)++;m_open.erase(it);it=it2;
if (it==m_open.end()){it=m_open.begin();
}
Bsqueda primero en anchura (BFS)
1 2 3 4 5
6 8 9 10
11 12 14 15
16 17 18 D
21 22 23 O
Mapa de celdas
O
23
18 22
17 21
1612
1
2 3
45 6
7 8
ABIERTOS
ABIERTOS es una cola (FIFO)
Bsqueda primero en profundidad (DFS)
1 2 3 4 5
6 8 9 10
11 12 14 15
16 17 18 D
21 22 23 O
Mapa de celdas
O
23
18 22
17 21
1612
1
2 6
37 8
4 5
ABIERTOS
ABIERTOS es una pila (LIFO)
Primero en anchura vs. profundidad
` Anchura` Garantiza encontrar la
solucin` La solucin (camino) es
ptima` Exponencial en recurso
ESPACIO con la profundidad del rbol.
` No aplicable para espacios de bsqueda grandes
` Profundidad` No garantiza encontrar la
solucin` La solucin (camino), si la
encuentra, no tiene porqu ser ptima
` Lineal en recurso ESPACIO con la profundidad del rbol de bsqueda
` Aplicable para espacios de bsqueda grandes
` Se puede implementar mediante recursividad
Programacin BFS del ejemplo PathList (I)
for (int i=0; iGetSize(); i++){if ( m_pg->m_graph[v_sel][i] && ! ListOfInt::IsMember(m_closed,i) &&
!ListOfInt::IsMember(m_open,i) ) {m_open.push_back (i);
// almacenamiento del nodo padre (opcional)m_father_info[i]=v_sel; // map}
}
Aadir vecinos de v_sel de ABIERTOS que no estn en CERRADOS
Borrado de v_sel de ABIERTOS y decisin del siguiente elemento a expandir
(it2=it)++;m_open.erase(it); // expansin FIFOit=it2;
Programacin BFS del ejemplo PathList (II)
int v=m_d;
map::iterator it3;
r.push_back(m_d);
while (m_father_info[v] != m_o) {
v=(m_father_info.find(v)second);
r.push_back (v);}
r.push_back (m_o);
Reconstruccin de la solucin
Busqueda DFS (iterativa): PathList (II)
for (int i=0; iGetSize(); i++){if ( m_pg->m_graph[v_sel][i] && ! ListOfInt::IsMember(m_closed,i) &&
!ListOfInt::IsMember(m_open,i) ) {m_open.push_front (i);}
// almacenamiento del nodo padre (opcional)m_father_info[i]=v_sel;
}
Aadir vecinos de v_sel de a ABIERTOS que no estn en CERRADOS
Borrado de v_sel de ABIERTOS y decisin del siguiente elemento a expandir
m_open.erase(it);
it=m_open.begin(); // expansin LIFO
Recursividad
FACTORIAL (n)
IF(n==1) THEN return 1;
ELSE return (n*FACTORIAL (n-1));
END-FACTORIAL
5 5
4
5
34
2
5
34 n=1
2624
120
TRAZA EJECUCIN FACTORIAL(5)
Pila del sistema
Salida
Salida
Ejecucin contina por aqu
Paradigma de programacin tal que una funcin contiene una llamada a s misma
1.15
Trmino general de una sucesin
1 2 0 10, 1k k ky y y y y = + = =
int Rec (int n){
if (n==0) return 0;if (n==1) return 1;
return (Rec (n-1) + Rec (n-2));}
#define N 10
void main(){
int vector [N];vector [0]=0; vector [1]=1;
for (int i=2; i
Bsqueda DFS implementada recursiva
DFS (Estado_Actual)
Declarar espacio en memoria para almacn S
If (Estado_actual = solucin) Then FIN
S= estados vecinos (Estado_actual )
If( ) then return
For each Estado_Nuevo en S
DFS (Estado_Nuevo)
EndFor
END-DFS
S =
1
2 3
4 5 76
1
3
2
Cmo almacenar el camino?
Inicio: Estado actual=nodo raz
3
2
45
3
2 BT
BT
6
7
32
Papel de la pila del sistema?
Salida
BT
Implementacin DFS recursiva
` En cada nodo del rbol de bsqueda:` Seleccin del nuevo nodo a expandir v_sel a partir de
ABIERTOS` Condiciones de salida:` Nodo hoja? BACTRACK` Es solucin FIN
` Generacin de nuevos vecinos de v_selABIERTOS_NEW` Expansin recursiva con ABIERTOS_NEW
EJEMPLO-I
1 2 32 3 (0) 0, (1) 1, (2) 2k k k ky y y y y y y = + = = =
PROGRAMA RECURSIVO: PRIMEROS N ELEMENTOS
int Rec (int n){
if (n==0) return 0;if (n==1) return 1;if (n==2) return 2;
return (Rec (n-1) + 2*Rec (n-2) - 3*Rec(n-3));}
ARBOL TERNARIO : nmero de nodos en funcin de N ?
Implementacin no recursiva?
EJEMPLO-II
1 2 32 3 (0) 0, (1) 1, (2) 2k k k ky y y y y y y = + = = =
PROGRAMA RECURSIVO: PRIMEROS N ELEMENTOS
int Rec (int n){
if (n==0) return 0;if (n==1) return 1;if (n==2) return 2;
return (Rec (n-1) + 2*Rec (n-2) - 3*Rec(n-3));}
ARBOL TERNARIO : nmero de nodos en funcin de N ?
EJEMPLO-III (Feb. 2009)
Se pretende romper la clave de entrada en un servidor remoto, compuesta de 6 dgitos del 0 al 9ambos inclusive. Para ello se dispone de la aplicacin que permite bombardear a dicho servidor contodas las diferentes claves posibles y es necesario implementar exclusivamente el generador declaves.
La estructura de datos a utilizar ser un vector clave de 6 posiciones. En cada posicin de clave seencuentra un dgito de la clave completa (clave[0] el primer dgito, clave[1] el segundo dgito etc.).
Se pide:
A) Implemente un algoritmo iterativo en C para generar todas las claves completando elcdigo que aparece a continuacin:
#define TAM_CLAVE 6#define TAM_NUMEROS 10
void main(){int clave[TAM_CLAVE];//
}
COMPLEJIDAD COMPUTACIONAL?
SOLUCIN-A
for(int i=0; i
EJEMPLO III (Feb. 2009)B) Escriba un algoritmo recursivo de tipo primero en profundidad para generar todas lasclaves. Para ello complete el cdigo siguiente:
#include #define TAM_CLAVE 6#define TAM_NUMEROS 10int clave[TAM_CLAVE];
void FuncRec(int depth){if(depth == TAM_CLAVE){ //salida de recursin
//.mostrar clave en pantallareturn;}//generacin de sucesores y llamada recursivaclave[depth]=-1;for(int i=0; i
permut (ARRAY Valor, POS_ESCRITURA k)NUM_DIGITOS Nstatic num= -1;
num = num+1; Valor[k] = num;IF (num == N)
Mostrar (Valor); ELSE
FOR (int i = 0; i < N; i++)IF (Valor[i] == 0)
permut (Valor, i);ENDIF
ENDFORENDIFnum = num-1; Valor[k] = 0;
END-permut
EJEMPLO-PERMUTACIONES
Salida (nodo hoja)
Sucesores
Backtrack
1-N 1-N 1-N 1-N
VALOR [N]
PERMUTACIONES 3 ELEMENTOS
000321
001
32
num=1 K=0
021
3
num=2 K=1
1 2 3
num=3 K=2
1 2 0
BTnum=num-1=3 Valor[k]=0
001
3BT num=2 Valor[1]=0
201
2
num=2 K=2
231
2
num=3 K=1
000
32
010
31
num=1 K=1
?
BT
HOJA
0 0 0VALOR =
PERMUTACIONES 4 ELEMENTOS
#define N 4void main() {
int Valor[N];for (int i = 0; i < N; i++){
Valor[i] = 0;}
permut (Valor, 0);}
Valor Num Nivel BT
1234 4 4 x
1203 3 3
1243 4 4 x
1020 2 2 x
1320 3 3
1324 4 4 x
1023 2 3
TRAZA
0 0 0 0VALOR =
Valores iniciales
NUM = 0
IMPLEMENTACI COMPLETA (permut.)
void permut (int* valor, int k){static int num=-1;
num++; valor[k]=num;if(num==N){
//..mostrar en pantalla}else {
for(int i=0; i
RESOLUCIN COMPUTACIONAL ` Anlisis preliminar del problema` Caracterizacin del problema` Formalizacin` Estimacin inicial del coste computacional
` Modelado` Anlisis de diferentes representaciones` Heursticas dependientes del dominio` Reduccin del coste computacional
` Implementacin` Algoritmo de bsqueda` Completos: BFS, DFS, etc.` Estocsticos: Genticos, Hill Climbing ,Tabu etc.
` Estructuras de datos` Lenguaje + Codificacin ` C, Java, C++, C#, Ruby, Python etc.` Recursin, iteracin
EJEMPLO: PROBLEMA DE LAS N-REINAS
EXISTE SOLUCIN PARA N>3 y N=1
EXISTE SOLUCIN ?
CARACTERIZACIN:VERIFICACIN SOLUCIN (I)
UN SOLO NDICE
13 14 15 16
9 10 11 12
5 6 7 8
1 2 3 41 2 1C C N = +1 2 1C C N =
DOS NDICES
2 1 2 1x x y y =
APLICACIN
C1
C2
(0,0)x
y
Complejidad?
MODELADO RELACIONAL (I)` RELACIONES BINARIAS R ENTRE PAREJAS DE CASILLAS` Dos casillas estn relacionadas si al colocar una reina en cada casilla no
se atacan entre si
R
MODELADO RELACIONAL-GRAFO (II)
18
27
6
9
3
4 5
1 2 34 5 67 8 9
G CONTIENE TODA LA INFORMACIN DEL PROBLEMA ?
ISLA
CARACTERIZACIN DE UNA SOLUCIN EN EL GRAFO?
GRAFO G con tantos vrtices como casillas y tantas aristas entre vrtices como relaciones binarias R entre casillas
MODELADO RELACIONAL-GRAFO (III)
13 14 15 16
9 10 11 12
5 6 7 8
1 2 3 4
1
8
2
76
9
3
4
5
10
11
12
131415
16
ESTIMACION DE COMPLEJIDAD EN FUNCIN DE N?
Es solucin si forma un N-clique en el grafo
MODELADO CON PERMUTACIONES
1 2 3 4
F4
F3
F2
F1
F1=2 F2=4 F3=1 F4=3
SOLUCIN
RESTRICCIONES HORZONTALES Y VERTICALES
{ }1,2, ,Q N= "
LA SOLUCIN ES UNA DE LAS PERMUTACIONES DE N NUMEROS DONDE CADA NMERO INDICA LA COLUMNA EN LA FILA RELATIVA
IMPLEMENTACIN
` GRAFO` PERMUTACIONES
DISTRIBUCIN / PARALELIZACIN DE BSQUEDA
DESCOMPOSICIN DEPENDIENTE DEL DOMINIO
A) Bsqueda de una contrasea numrica de K dgitos
KK-1321
DESCOMPOSICIN INDEPENDIENTE DEL DOMINIO
xxxx0-1
xxxx1-2
xxxx8-9B) Encontrar K-clique ?
DIVISIN BFS1
2 3
4 5 76
DFS DFS
PARADIGMA: DESCOMPOSICIN + INTEGRACIN
ARQUITECTURA PARA N-REINAS DISTRIBUIDAS
DESCOMPOSICIN
Cliente
Servidores
REPARTO BFS
Busq. DFS
Busq. DFS
Busq. DFS
Busq. DFS
INTEGRACIN
Cliente
N_sol1
N_sol2
N_sol3
N_sol4
N_SOL
+
+
+
+
PARADIGMA: DESCOMPOSICIN + INTEGRACIN
EJERCICIOS EXAMEN (Sep. 2010) (I)Se necesita un algoritmo para determinar una ruta posible entre dos ciudades cualesquiera ORIGENy DESTINO. Para ello un driver de Base de Datos dispone de tres funciones:
int GenCiudadesVecinas (Ciudad ciudad, Ciudad* ciudades_vecinas);int BorrarCiudades (Ciudad* ciudades_a_borrar, const Ciudad* ciudades_ref );bool IsCiudadDestino (const Ciudad ciudad );
GenCiudadesVecinas: Para una ciudad c devuelve el conjunto de ciudades vecinas de c y retorna porvalor el nmero de ciudades que componen dicha lista.
BorrarCiudades: borra de la lista de ciudades pasada como segundo parmetro, las ciudades que yase encuentran en la lista pasada como primer parmetro. Asimismo retorna el nuevo tamao de lista.
IsCiudadDestino: devuelve TRUE si la ciudad pasada como parmetro es la ciudad destino.
Se pide implementar un algoritmo recursivo para obtener un camino entre dos ciudades. Dichoalgoritmo se encapsula en una nueva funcin con el esqueleto siguiente:
void RecCamino (Ciudad* lC, int nlC, int d) {
Ciudad* pC= new Ciudad [MAX_CIUDADES_NIVEL];//
for (int i=0; i
EJERCICIOS EXAMEN (Sep. 2010) (II)
` Interpretacin de los valores de los 3 parmetros de lafuncin recursiva RecCamino en la primera llamada.` (Nota: Se parte de una ciudad ORIGEN)
` Complete RecCamino para que termine nada masencontrar una ciudad destino
bool RecCamino (Ciudad* lC, int nlC, int d) {Ciudad* pC= new Ciudad [MAX_CIUDADES_NIVEL];
//bucle de generacin de vecinosfor (int i=0; i
EJERCICIOS EXAMEN (Sep. 2010) (III)` Modifique el cdigo anterior para que almacene el camino solucin
y no pase nunca por la misma ciudad
bool RecCamino (Ciudad* lC, int nlC, int d) {Ciudad* pC= new Ciudad [MAX_CIUDADES_NIVEL];
//bucle de generacin de vecinosfor (int i=0; i
EJERCICIO EXAMEN (Junio 2009)Implemntese un procedimiento recursivo para mostrar en pantalla unnmero entero positivo en formato binario. Un ejemplo de sesin en unshell (para un ejecutable denominado conversor) sera:
Entrada: conversor 32 Salida: 10000Entrada: conversor 64 Salida: 100000
Nota: La manera ms simple de realizar la tarea es ir dividiendo por dos el dato. Cadadigito del nmero binario buscado es el resto de esa divisin entera. (Por ejemplo 13 enbinario: 13/2 = 6; 13%2=1 // 6/2=3; 6%2=0 // 3/2 =1; 3%2=1; // 1; La conversin es0x1101. Ntese que hay que reconstruir los restos al revs).
void binario(int i){if(i==1) cout