Capítulo 9: Técnicas de Diseño de Algoritmos
9.3 Backtracking
El backtracking es una técnica algorítmica muy útil que puede resolver una amplia gama de problemas complejos en un tiempo razonable. Se usa comúnmente en problemas de toma de decisiones donde el conjunto de opciones potenciales puede organizarse en un árbol de decisiones o un grafo.
La idea básica detrás del backtracking es construir una solución paso a paso mientras se verifica si cada paso contribuye a la solución general. Si un paso no contribuye a la solución, se elimina y se intenta el siguiente paso.
Un gran ejemplo de un problema que se puede resolver usando backtracking es el rompecabezas de las N reinas. Este rompecabezas requiere colocar N reinas en un tablero de ajedrez NxN de tal manera que ninguna de las reinas se amenace entre sí. Esto significa que ninguna de las reinas puede estar en la misma fila, columna o diagonal. Mediante el uso de backtracking, es posible encontrar una solución a este problema.
El backtracking también se puede utilizar en otros tipos de problemas, como encontrar el camino más corto en un laberinto o identificar la mejor combinación de elementos para empacar en una mochila. En general, el backtracking es una herramienta poderosa que puede ayudar a resolver muchos tipos diferentes de problemas de manera sistemática y eficiente.
Aquí tienes una solución simple en Python:
def isSafe(board, row, col, N):
# Check this row on left side
for i in range(col):
if board[row][i] == 1:
return False
# Check upper diagonal on left side
for i, j in zip(range(row, -1, -1), range(col, -1, -1)):
if board[i][j] == 1:
return False
# Check lower diagonal on left side
for i, j in zip(range(row, N, 1), range(col, -1, -1)):
if board[i][j] == 1:
return False
return True
def solveNQUtil(board, col, N):
if col >= N:
return True
for i in range(N):
if isSafe(board, i, col, N):
board[i][col] = 1
# recur to place rest of the queens
if solveNQUtil(board, col + 1, N) == True:
return True
# if placing queen in board[i][col] doesn't lead to a solution,
# then remove queen from board[i][col]
board[i][col] = 0
return False
def solveNQ(N):
board = [[0]*N for _ in range(N)]
if solveNQUtil(board, 0, N) == False:
print("Solution does not exist")
return False
for i in range(N):
for j in range(N):
print (board[i][j], end = " ")
print()
return True
# test
solveNQ(4)
En este código, solveNQUtil
es una función recursiva que utiliza la técnica de retroceso (backtracking). Toma una solución parcial (el tablero
) y un número de columna col
como argumentos. Intenta colocar una reina en todas las celdas de la columna actual col
, y luego recursivamente pasa a la siguiente columna. Si no es posible realizar ninguna colocación en la columna actual, devuelve Falso. Si es posible realizar una colocación, coloca una reina y recursivamente pasa a la siguiente columna.
El retroceso es una técnica poderosa utilizada para resolver problemas complejos que pueden no tener soluciones o métodos directos disponibles. Básicamente, este método implica tomar una decisión, y si no conduce a una solución, deshacer (retroceder) esa elección. La idea detrás de este ensayo y error metódico es que permite al solucionador de problemas explorar diversas alternativas que podrían llevar a una solución.
En el caso del arreglo tablero
, si no hay una reina que se pueda colocar en la siguiente columna, el algoritmo elimina la reina de la celda actual y retrocede para probar la siguiente alternativa en su columna. Este proceso continúa hasta que se encuentre una solución o se agoten todas las alternativas. La belleza del retroceso es que permite al solucionador de problemas explorar sistemáticamente diferentes opciones y descartar aquellas que no funcionan, aumentando así las posibilidades de encontrar una solución óptima.
En resumen, el retroceso es una técnica poderosa y efectiva para resolver problemas complejos que pueden no tener soluciones o métodos directos disponibles. Al explorar sistemáticamente diferentes alternativas y retroceder en las elecciones que no conducen a soluciones, los solucionadores de problemas pueden aumentar sus posibilidades de encontrar soluciones óptimas.
De hecho, el retroceso es un concepto fascinante que se puede aplicar a muchos problemas diferentes. Además del problema de las N-Reinas que discutimos, también se puede utilizar para resolver rompecabezas como Sudoku, encontrar el camino más corto en un laberinto, la permutación de una cadena dada y muchos otros.
Es importante entender que aunque el retroceso puede ser una manera eficiente de encontrar soluciones, no siempre es el mejor enfoque. Para problemas con grandes espacios de entrada, el retroceso puede llevar a soluciones ineficientes ya que opera de manera exhaustiva. Hay muchos factores diferentes que pueden influir en si el retroceso es el mejor enfoque para resolver un problema.
Además, otra cosa importante a tener en cuenta al usar el retroceso es diseñar cuidadosamente su condición de detención. Debido a que el retroceso opera verificando soluciones recursivamente, si no define correctamente cuándo debe detenerse su función, puede terminar con un bucle infinito o cálculos innecesariamente largos.
El retroceso es una herramienta crítica en el arsenal de un diseñador de algoritmos, pero al igual que cualquier otra herramienta, debe usarse con comprensión y cuidado. Dominarlo requiere mucha práctica y resolución de problemas, así que te animo a intentar resolver una variedad de problemas para comprender cuándo y cómo usarlo de manera efectiva.
Recuerda, la belleza del retroceso radica en su simplicidad y elegancia. Se trata de tomar decisiones, y si no te llevan a una solución, simplemente retrocedes y haces una elección diferente. Este ensayo y error sistemático puede ser una estrategia poderosa para resolver problemas complejos, y definitivamente es una habilidad que vale la pena cultivar.
9.3 Backtracking
El backtracking es una técnica algorítmica muy útil que puede resolver una amplia gama de problemas complejos en un tiempo razonable. Se usa comúnmente en problemas de toma de decisiones donde el conjunto de opciones potenciales puede organizarse en un árbol de decisiones o un grafo.
La idea básica detrás del backtracking es construir una solución paso a paso mientras se verifica si cada paso contribuye a la solución general. Si un paso no contribuye a la solución, se elimina y se intenta el siguiente paso.
Un gran ejemplo de un problema que se puede resolver usando backtracking es el rompecabezas de las N reinas. Este rompecabezas requiere colocar N reinas en un tablero de ajedrez NxN de tal manera que ninguna de las reinas se amenace entre sí. Esto significa que ninguna de las reinas puede estar en la misma fila, columna o diagonal. Mediante el uso de backtracking, es posible encontrar una solución a este problema.
El backtracking también se puede utilizar en otros tipos de problemas, como encontrar el camino más corto en un laberinto o identificar la mejor combinación de elementos para empacar en una mochila. En general, el backtracking es una herramienta poderosa que puede ayudar a resolver muchos tipos diferentes de problemas de manera sistemática y eficiente.
Aquí tienes una solución simple en Python:
def isSafe(board, row, col, N):
# Check this row on left side
for i in range(col):
if board[row][i] == 1:
return False
# Check upper diagonal on left side
for i, j in zip(range(row, -1, -1), range(col, -1, -1)):
if board[i][j] == 1:
return False
# Check lower diagonal on left side
for i, j in zip(range(row, N, 1), range(col, -1, -1)):
if board[i][j] == 1:
return False
return True
def solveNQUtil(board, col, N):
if col >= N:
return True
for i in range(N):
if isSafe(board, i, col, N):
board[i][col] = 1
# recur to place rest of the queens
if solveNQUtil(board, col + 1, N) == True:
return True
# if placing queen in board[i][col] doesn't lead to a solution,
# then remove queen from board[i][col]
board[i][col] = 0
return False
def solveNQ(N):
board = [[0]*N for _ in range(N)]
if solveNQUtil(board, 0, N) == False:
print("Solution does not exist")
return False
for i in range(N):
for j in range(N):
print (board[i][j], end = " ")
print()
return True
# test
solveNQ(4)
En este código, solveNQUtil
es una función recursiva que utiliza la técnica de retroceso (backtracking). Toma una solución parcial (el tablero
) y un número de columna col
como argumentos. Intenta colocar una reina en todas las celdas de la columna actual col
, y luego recursivamente pasa a la siguiente columna. Si no es posible realizar ninguna colocación en la columna actual, devuelve Falso. Si es posible realizar una colocación, coloca una reina y recursivamente pasa a la siguiente columna.
El retroceso es una técnica poderosa utilizada para resolver problemas complejos que pueden no tener soluciones o métodos directos disponibles. Básicamente, este método implica tomar una decisión, y si no conduce a una solución, deshacer (retroceder) esa elección. La idea detrás de este ensayo y error metódico es que permite al solucionador de problemas explorar diversas alternativas que podrían llevar a una solución.
En el caso del arreglo tablero
, si no hay una reina que se pueda colocar en la siguiente columna, el algoritmo elimina la reina de la celda actual y retrocede para probar la siguiente alternativa en su columna. Este proceso continúa hasta que se encuentre una solución o se agoten todas las alternativas. La belleza del retroceso es que permite al solucionador de problemas explorar sistemáticamente diferentes opciones y descartar aquellas que no funcionan, aumentando así las posibilidades de encontrar una solución óptima.
En resumen, el retroceso es una técnica poderosa y efectiva para resolver problemas complejos que pueden no tener soluciones o métodos directos disponibles. Al explorar sistemáticamente diferentes alternativas y retroceder en las elecciones que no conducen a soluciones, los solucionadores de problemas pueden aumentar sus posibilidades de encontrar soluciones óptimas.
De hecho, el retroceso es un concepto fascinante que se puede aplicar a muchos problemas diferentes. Además del problema de las N-Reinas que discutimos, también se puede utilizar para resolver rompecabezas como Sudoku, encontrar el camino más corto en un laberinto, la permutación de una cadena dada y muchos otros.
Es importante entender que aunque el retroceso puede ser una manera eficiente de encontrar soluciones, no siempre es el mejor enfoque. Para problemas con grandes espacios de entrada, el retroceso puede llevar a soluciones ineficientes ya que opera de manera exhaustiva. Hay muchos factores diferentes que pueden influir en si el retroceso es el mejor enfoque para resolver un problema.
Además, otra cosa importante a tener en cuenta al usar el retroceso es diseñar cuidadosamente su condición de detención. Debido a que el retroceso opera verificando soluciones recursivamente, si no define correctamente cuándo debe detenerse su función, puede terminar con un bucle infinito o cálculos innecesariamente largos.
El retroceso es una herramienta crítica en el arsenal de un diseñador de algoritmos, pero al igual que cualquier otra herramienta, debe usarse con comprensión y cuidado. Dominarlo requiere mucha práctica y resolución de problemas, así que te animo a intentar resolver una variedad de problemas para comprender cuándo y cómo usarlo de manera efectiva.
Recuerda, la belleza del retroceso radica en su simplicidad y elegancia. Se trata de tomar decisiones, y si no te llevan a una solución, simplemente retrocedes y haces una elección diferente. Este ensayo y error sistemático puede ser una estrategia poderosa para resolver problemas complejos, y definitivamente es una habilidad que vale la pena cultivar.
9.3 Backtracking
El backtracking es una técnica algorítmica muy útil que puede resolver una amplia gama de problemas complejos en un tiempo razonable. Se usa comúnmente en problemas de toma de decisiones donde el conjunto de opciones potenciales puede organizarse en un árbol de decisiones o un grafo.
La idea básica detrás del backtracking es construir una solución paso a paso mientras se verifica si cada paso contribuye a la solución general. Si un paso no contribuye a la solución, se elimina y se intenta el siguiente paso.
Un gran ejemplo de un problema que se puede resolver usando backtracking es el rompecabezas de las N reinas. Este rompecabezas requiere colocar N reinas en un tablero de ajedrez NxN de tal manera que ninguna de las reinas se amenace entre sí. Esto significa que ninguna de las reinas puede estar en la misma fila, columna o diagonal. Mediante el uso de backtracking, es posible encontrar una solución a este problema.
El backtracking también se puede utilizar en otros tipos de problemas, como encontrar el camino más corto en un laberinto o identificar la mejor combinación de elementos para empacar en una mochila. En general, el backtracking es una herramienta poderosa que puede ayudar a resolver muchos tipos diferentes de problemas de manera sistemática y eficiente.
Aquí tienes una solución simple en Python:
def isSafe(board, row, col, N):
# Check this row on left side
for i in range(col):
if board[row][i] == 1:
return False
# Check upper diagonal on left side
for i, j in zip(range(row, -1, -1), range(col, -1, -1)):
if board[i][j] == 1:
return False
# Check lower diagonal on left side
for i, j in zip(range(row, N, 1), range(col, -1, -1)):
if board[i][j] == 1:
return False
return True
def solveNQUtil(board, col, N):
if col >= N:
return True
for i in range(N):
if isSafe(board, i, col, N):
board[i][col] = 1
# recur to place rest of the queens
if solveNQUtil(board, col + 1, N) == True:
return True
# if placing queen in board[i][col] doesn't lead to a solution,
# then remove queen from board[i][col]
board[i][col] = 0
return False
def solveNQ(N):
board = [[0]*N for _ in range(N)]
if solveNQUtil(board, 0, N) == False:
print("Solution does not exist")
return False
for i in range(N):
for j in range(N):
print (board[i][j], end = " ")
print()
return True
# test
solveNQ(4)
En este código, solveNQUtil
es una función recursiva que utiliza la técnica de retroceso (backtracking). Toma una solución parcial (el tablero
) y un número de columna col
como argumentos. Intenta colocar una reina en todas las celdas de la columna actual col
, y luego recursivamente pasa a la siguiente columna. Si no es posible realizar ninguna colocación en la columna actual, devuelve Falso. Si es posible realizar una colocación, coloca una reina y recursivamente pasa a la siguiente columna.
El retroceso es una técnica poderosa utilizada para resolver problemas complejos que pueden no tener soluciones o métodos directos disponibles. Básicamente, este método implica tomar una decisión, y si no conduce a una solución, deshacer (retroceder) esa elección. La idea detrás de este ensayo y error metódico es que permite al solucionador de problemas explorar diversas alternativas que podrían llevar a una solución.
En el caso del arreglo tablero
, si no hay una reina que se pueda colocar en la siguiente columna, el algoritmo elimina la reina de la celda actual y retrocede para probar la siguiente alternativa en su columna. Este proceso continúa hasta que se encuentre una solución o se agoten todas las alternativas. La belleza del retroceso es que permite al solucionador de problemas explorar sistemáticamente diferentes opciones y descartar aquellas que no funcionan, aumentando así las posibilidades de encontrar una solución óptima.
En resumen, el retroceso es una técnica poderosa y efectiva para resolver problemas complejos que pueden no tener soluciones o métodos directos disponibles. Al explorar sistemáticamente diferentes alternativas y retroceder en las elecciones que no conducen a soluciones, los solucionadores de problemas pueden aumentar sus posibilidades de encontrar soluciones óptimas.
De hecho, el retroceso es un concepto fascinante que se puede aplicar a muchos problemas diferentes. Además del problema de las N-Reinas que discutimos, también se puede utilizar para resolver rompecabezas como Sudoku, encontrar el camino más corto en un laberinto, la permutación de una cadena dada y muchos otros.
Es importante entender que aunque el retroceso puede ser una manera eficiente de encontrar soluciones, no siempre es el mejor enfoque. Para problemas con grandes espacios de entrada, el retroceso puede llevar a soluciones ineficientes ya que opera de manera exhaustiva. Hay muchos factores diferentes que pueden influir en si el retroceso es el mejor enfoque para resolver un problema.
Además, otra cosa importante a tener en cuenta al usar el retroceso es diseñar cuidadosamente su condición de detención. Debido a que el retroceso opera verificando soluciones recursivamente, si no define correctamente cuándo debe detenerse su función, puede terminar con un bucle infinito o cálculos innecesariamente largos.
El retroceso es una herramienta crítica en el arsenal de un diseñador de algoritmos, pero al igual que cualquier otra herramienta, debe usarse con comprensión y cuidado. Dominarlo requiere mucha práctica y resolución de problemas, así que te animo a intentar resolver una variedad de problemas para comprender cuándo y cómo usarlo de manera efectiva.
Recuerda, la belleza del retroceso radica en su simplicidad y elegancia. Se trata de tomar decisiones, y si no te llevan a una solución, simplemente retrocedes y haces una elección diferente. Este ensayo y error sistemático puede ser una estrategia poderosa para resolver problemas complejos, y definitivamente es una habilidad que vale la pena cultivar.
9.3 Backtracking
El backtracking es una técnica algorítmica muy útil que puede resolver una amplia gama de problemas complejos en un tiempo razonable. Se usa comúnmente en problemas de toma de decisiones donde el conjunto de opciones potenciales puede organizarse en un árbol de decisiones o un grafo.
La idea básica detrás del backtracking es construir una solución paso a paso mientras se verifica si cada paso contribuye a la solución general. Si un paso no contribuye a la solución, se elimina y se intenta el siguiente paso.
Un gran ejemplo de un problema que se puede resolver usando backtracking es el rompecabezas de las N reinas. Este rompecabezas requiere colocar N reinas en un tablero de ajedrez NxN de tal manera que ninguna de las reinas se amenace entre sí. Esto significa que ninguna de las reinas puede estar en la misma fila, columna o diagonal. Mediante el uso de backtracking, es posible encontrar una solución a este problema.
El backtracking también se puede utilizar en otros tipos de problemas, como encontrar el camino más corto en un laberinto o identificar la mejor combinación de elementos para empacar en una mochila. En general, el backtracking es una herramienta poderosa que puede ayudar a resolver muchos tipos diferentes de problemas de manera sistemática y eficiente.
Aquí tienes una solución simple en Python:
def isSafe(board, row, col, N):
# Check this row on left side
for i in range(col):
if board[row][i] == 1:
return False
# Check upper diagonal on left side
for i, j in zip(range(row, -1, -1), range(col, -1, -1)):
if board[i][j] == 1:
return False
# Check lower diagonal on left side
for i, j in zip(range(row, N, 1), range(col, -1, -1)):
if board[i][j] == 1:
return False
return True
def solveNQUtil(board, col, N):
if col >= N:
return True
for i in range(N):
if isSafe(board, i, col, N):
board[i][col] = 1
# recur to place rest of the queens
if solveNQUtil(board, col + 1, N) == True:
return True
# if placing queen in board[i][col] doesn't lead to a solution,
# then remove queen from board[i][col]
board[i][col] = 0
return False
def solveNQ(N):
board = [[0]*N for _ in range(N)]
if solveNQUtil(board, 0, N) == False:
print("Solution does not exist")
return False
for i in range(N):
for j in range(N):
print (board[i][j], end = " ")
print()
return True
# test
solveNQ(4)
En este código, solveNQUtil
es una función recursiva que utiliza la técnica de retroceso (backtracking). Toma una solución parcial (el tablero
) y un número de columna col
como argumentos. Intenta colocar una reina en todas las celdas de la columna actual col
, y luego recursivamente pasa a la siguiente columna. Si no es posible realizar ninguna colocación en la columna actual, devuelve Falso. Si es posible realizar una colocación, coloca una reina y recursivamente pasa a la siguiente columna.
El retroceso es una técnica poderosa utilizada para resolver problemas complejos que pueden no tener soluciones o métodos directos disponibles. Básicamente, este método implica tomar una decisión, y si no conduce a una solución, deshacer (retroceder) esa elección. La idea detrás de este ensayo y error metódico es que permite al solucionador de problemas explorar diversas alternativas que podrían llevar a una solución.
En el caso del arreglo tablero
, si no hay una reina que se pueda colocar en la siguiente columna, el algoritmo elimina la reina de la celda actual y retrocede para probar la siguiente alternativa en su columna. Este proceso continúa hasta que se encuentre una solución o se agoten todas las alternativas. La belleza del retroceso es que permite al solucionador de problemas explorar sistemáticamente diferentes opciones y descartar aquellas que no funcionan, aumentando así las posibilidades de encontrar una solución óptima.
En resumen, el retroceso es una técnica poderosa y efectiva para resolver problemas complejos que pueden no tener soluciones o métodos directos disponibles. Al explorar sistemáticamente diferentes alternativas y retroceder en las elecciones que no conducen a soluciones, los solucionadores de problemas pueden aumentar sus posibilidades de encontrar soluciones óptimas.
De hecho, el retroceso es un concepto fascinante que se puede aplicar a muchos problemas diferentes. Además del problema de las N-Reinas que discutimos, también se puede utilizar para resolver rompecabezas como Sudoku, encontrar el camino más corto en un laberinto, la permutación de una cadena dada y muchos otros.
Es importante entender que aunque el retroceso puede ser una manera eficiente de encontrar soluciones, no siempre es el mejor enfoque. Para problemas con grandes espacios de entrada, el retroceso puede llevar a soluciones ineficientes ya que opera de manera exhaustiva. Hay muchos factores diferentes que pueden influir en si el retroceso es el mejor enfoque para resolver un problema.
Además, otra cosa importante a tener en cuenta al usar el retroceso es diseñar cuidadosamente su condición de detención. Debido a que el retroceso opera verificando soluciones recursivamente, si no define correctamente cuándo debe detenerse su función, puede terminar con un bucle infinito o cálculos innecesariamente largos.
El retroceso es una herramienta crítica en el arsenal de un diseñador de algoritmos, pero al igual que cualquier otra herramienta, debe usarse con comprensión y cuidado. Dominarlo requiere mucha práctica y resolución de problemas, así que te animo a intentar resolver una variedad de problemas para comprender cuándo y cómo usarlo de manera efectiva.
Recuerda, la belleza del retroceso radica en su simplicidad y elegancia. Se trata de tomar decisiones, y si no te llevan a una solución, simplemente retrocedes y haces una elección diferente. Este ensayo y error sistemático puede ser una estrategia poderosa para resolver problemas complejos, y definitivamente es una habilidad que vale la pena cultivar.