Ejemplos de Backtracking Andrés Becerra Sandoval Backtracking I Técnica genérica de diseño de algoritmos de búsqueda I Una solución I Todas las soluciones I La mejor solución! Estrategia General I I Representar las variables del problema en un arreglo Denir los dominios de las variables del problema I Pensar como recorrer dichos dominios iterativamente I I Visualizar un árbol de búsqueda para un n pequeño Plantear que es un arreglo k-prometedor Permutaciones I I I A contendrá una permutación A[i ] 6= A[j ] si i 6= j para todos los 1 ≤ i , j ≤ n El dominio de cada variable es [1, n] El arreglo I Se puede recorrer en un ciclo for I k prometedor: el valor que ponga en A[k ] debe ser distinto a todos los anteriores k-prometedor prometedor(A, k ) PRE: A ya es k-1 prometedor for j ← 1 to k − 1 do if A[j ] = A[k ] then return False return True Permutaciones permutar(A, k , n) if k = n then if prometedor(A,k) then print A else return else for j ← 1 to n do if prometedor(A, k ) then A[k + 1] ← j permutar(A, k + 1, n) Permutaciones Iterativo permutaciones(A,n) k =1 while k > 0 do A[k ] ← proximoElemento(A, k ) while not ultimaOpcion(A,k) and not prometedor(A,k) do A[k ] ← proximoElemento(A, k ) if not ultimaOpcion(A,k,n) then if k = n then print A else k ← k + 1 else A[k ] ← primerElemento(A, k ) Vuelta atrás al nivel superior (Backtrack) k ←k −1 Funciones ultimaOpcion(A, k , n) return A[k ] == n + 1 proximoElemento(A, k ) return A[k ] + 1 primerElemento(A, k ) return 0 Subconjuntos de un conjunto I I I El conjunto de partes de un conjunto tiene 2n elementos Podemos buscarlos todos sistemáticamente si denimos una codicación adecuada en un arreglo ¾Cual? Codicación I I I A[i ] ∈ 0, 1 Si A[i ] = 0 el elemento i no está en el subconjunto que se está armando Si A[i ] = 1 el elemento i armando está en el subconjunto que se está k-Prometedor I I El valor que asigne a cada variable es 1 o 0. O sea, todos son prometedores!. k-Prometedor prometedor(A, k ) return True Subconjuntos subconjuntos(A, k , n) if k = n then if prometedor(A,k) then print A else return else for j ← 0 to 1 do if prometedor(A, k ) then A[k + 1] ← j subconjuntos(A, k + 1, n) Subconjuntos iterativo permutaciones(A,n) k =1 while k > 0 do A[k ] ← proximoElemento(A, k ) while not ultimaOpcion(A,k) and not prometedor(A,k) do A[k ] ← proximoElemento(A, k ) if not ultimaOpcion(A,k,n) then if k = n then print A else k ← k + 1 else A[k ] ← primerElemento(A, k ) Vuelta atrás al nivel superior (Backtrack) k ←k −1 Subconjuntos iterativo ultimaOpcion(A, k , n) return A[k ] == 2 proximoElemento(A, k ) return A[k ] + 1 primerElemento(A, k ) return −1 Tareas I I Hallar todas las rutas entre un par de nodos en un grafo Obtener todas las formas de dar un cambio (devuelta) con unas cantidades especicadas de monedas de cada denominación.