Mateo Sanabria Ardila
ISIS1105: Diseño y análisis de algoritmos

Exploración de grafos de estados

Capitulo 9: Combinational Search
  • Backtracking
  • Best-First Search
  • A* Heuristic

Backtracking

Es una método sistemático de recorrer todas las posibilidades de un espacio de búsqueda. Por ejemplo:
  • Todas las posibles configuraciones de determinados elementos. 
  • Enumerar todos los ST de un grafo.
  • Obtener todos los caminos entre dos vertices.
    
  • ...

Backtracking

Un problema es considero para ser resuelto con este método si se debe generar cada posible configuración exactamente una única vez  
  • 'Enumera' todas las posibilidades
     en el espacio de estados.
  • Nunca visita un estado mas de una vez. 

Backtracking

Modelaremos nuestra solución de búsqueda como un vector a:
a = (a_1, a_2, \cdots, a_n)
Donde cada elemento aiai se selecciona de un conjunto iSi

Backtracking
All Subsets

Cuales son los subconjuntos de un conjunto de tamaño n ?
def backtrack(a: list, k: int, additional_input: Any) -> None:
    c = [0 for _ in range(MaxCandidates)]
    nc = 0
    if is_solution(a,k,additional_input):
        process_solution(a,k,additional_input)
    else:
        k = k + 1
        nc = construct_candidate(a,k,additional_input,c)
        for i in range(0,nc):
            a[k] = c[i]
            make_move(a,k,additional_input)
            backtrack(a,k,additional_input)
            unamake_move(a,k,additional_input)
            if finished:
                return
def backtrack(a: list, k: int, additional_input: Any) -> None:
    c = [0 for _ in range(MaxCandidates)]
    nc = 0
    # Funcion booleana para saber si los primeros k 
    # elementos de a forman una solucion completa 
    # para UNA solucion del problema
    if is_solution(a,k,additional_input):
        process_solution(a,k,additional_input)
    else:
        k = k + 1
        nc = construct_candidate(a,k,additional_input,c)
        for i in range(0,nc):
            a[k] = c[i]
            make_move(a,k,additional_input)
            backtrack(a,k,additional_input)
            unamake_move(a,k,additional_input)
            if finished:
                return
def backtrack(a: list, k: int, additional_input: Any) -> None:
    c = [0 for _ in range(MaxCandidates)]
    nc = 0
    if is_solution(a,k,additional_input):
      	# Guarda, printea, cuenta o procesa la solucion
        process_solution(a,k,additional_input)
    else:
        k = k + 1
        nc = construct_candidate(a,k,additional_input,c)
        for i in range(0,nc):
            a[k] = c[i]
            make_move(a,k,additional_input)
            backtrack(a,k,additional_input)
            unamake_move(a,k,additional_input)
            if finished:
                return
def backtrack(a: list, k: int, additional_input: Any) -> None:
    c = [0 for _ in range(MaxCandidates)]
    nc = 0
    if is_solution(a,k,additional_input):
        process_solution(a,k,additional_input)
    else:
        k = k + 1
        nc = construct_candidate(a,k,additional_input,c)
        for i in range(0,nc):
            a[k] = c[i]
            make_move(a,k,additional_input)
            backtrack(a,k,additional_input)
            unamake_move(a,k,additional_input)
            if finished:
                return
def backtrack(a: list, k: int, additional_input: Any) -> None:
    c = [0 for _ in range(MaxCandidates)]
    nc = 0
    if is_solution(a,k,additional_input):
        process_solution(a,k,additional_input)
    else:
        k = k + 1
        # Asigna valores en c con el posible conjunto de
        # valores candidatos para la posicion k de a, 
        # basados en las k-1 posiciones. El numero de
        # candidatos es retornado en nc.
        nc = construct_candidate(a,k,additional_input,c)
        for i in range(0,nc):
            a[k] = c[i]
            make_move(a,k,additional_input)
            backtrack(a,k,additional_input)
            unamake_move(a,k,additional_input)
            if finished:
                return
def backtrack(a: list, k: int, additional_input: Any) -> None:
    c = [0 for _ in range(MaxCandidates)]
    nc = 0
    if is_solution(a,k,additional_input):
        process_solution(a,k,additional_input)
    else:
        k = k + 1
        nc = construct_candidate(a,k,additional_input,c)
        for i in range(0,nc):
            a[k] = c[i]
            make_move(a,k,additional_input)
            backtrack(a,k,additional_input)
            unamake_move(a,k,additional_input)
            if finished:
                return
def backtrack(a: list, k: int, additional_input: Any) -> None:
    c = [0 for _ in range(MaxCandidates)]
    nc = 0
    if is_solution(a,k,additional_input):
        process_solution(a,k,additional_input)
    else:
        k = k + 1
        nc = construct_candidate(a,k,additional_input,c)
        for i in range(0,nc):
            a[k] = c[i]
            make_move(a,k,additional_input)
            backtrack(a,k,additional_input)
            unamake_move(a,k,additional_input)
            if finished:
                return

Backtracking
All Permutation

  • Construir una lista de n elementos. 
    
  • El conjunto de candidatos para el i-ésimo elemento serán todos los elementos que no aparecen en la solucion parcial.
S_k = \{1,\cdots,n\} - \{a_1,\cdots,a_k\}