El problema de las nueve reinas consiste en colocar 9 reinas en un tablero de ajedrez de 9×9 de manera que ninguna reina pueda atacar a otra.
En ajedrez, una reina puede moverse:
- horizontalmente
- verticalmente
- diagonalmente
Por lo tanto, dos reinas no pueden compartir:
- la misma fila
- la misma columna
- la misma diagonal
Este problema es un clásico ejemplo usado en informática para enseñar técnicas de búsqueda y algoritmos de Backtracking.
El método de backtracking prueba posiciones posibles y retrocede cuando encuentra un conflicto, explorando sistemáticamente todas las soluciones.
Idea del algoritmo
Para resolver el problema se usa el siguiente enfoque:
- Colocar una reina en la primera columna.
- Intentar colocar otra reina en la segunda columna.
- Verificar si la posición es segura.
- Si no lo es, probar otra fila.
- Si ninguna fila funciona, regresar a la columna anterior.
- Continuar hasta colocar las 9 reinas.
Este proceso se repite hasta encontrar una solución válida.
#include <iostream>
using namespace std;
// N define el tamaño del tablero.
// Como es el problema de las nueve reinas,
// usamos un tablero de 9x9.
const int N = 9;
// Esta matriz representa el tablero de ajedrez.
// 0 = casilla vacía
// 1 = hay una reina colocada
int tablero[N][N];
// ------------------------------------------------------------
// Función: esSeguro
// Verifica si es posible colocar una reina en la posición
// (fila, col) sin que sea atacada por otra reina.
// ------------------------------------------------------------
bool esSeguro(int fila, int col)
{
int i, j;
// Revisar si existe una reina en la misma fila
// hacia la izquierda (columnas anteriores).
// No revisamos hacia la derecha porque aún
// no hemos colocado reinas allí.
for(i = 0; i < col; i++)
if(tablero[fila][i])
return false;
// Revisar diagonal superior izquierda.
// Si encontramos una reina, la posición no es válida.
for(i = fila, j = col; i >= 0 && j >= 0; i--, j--)
if(tablero[i][j])
return false;
// Revisar diagonal inferior izquierda.
for(i = fila, j = col; i < N && j >= 0; i++, j--)
if(tablero[i][j])
return false;
// Si no hay conflictos, la posición es segura.
return true;
}
// ------------------------------------------------------------
// Función: resolverReinas
// Implementa el algoritmo de backtracking.
// Intenta colocar una reina en cada columna.
// Si una posición no funciona, retrocede (backtrack)
// y prueba otra posición.
// ------------------------------------------------------------
bool resolverReinas(int col)
{
// Si ya colocamos reinas en todas las columnas,
// significa que encontramos una solución válida.
if(col >= N)
return true;
// Intentar colocar la reina en cada fila
// de la columna actual.
for(int i = 0; i < N; i++)
{
// Verificar si la posición es segura.
if(esSeguro(i, col))
{
// Colocamos la reina.
tablero[i][col] = 1;
// Intentamos colocar la siguiente reina
// en la siguiente columna.
if(resolverReinas(col + 1))
return true;
// Si no se pudo encontrar solución,
// quitamos la reina (backtracking)
// y probamos otra fila.
tablero[i][col] = 0;
}
}
// Si ninguna fila funcionó en esta columna,
// devolvemos false para retroceder.
return false;
}
// ------------------------------------------------------------
// Función: imprimirTablero
// Muestra el tablero en pantalla.
// Q representa una reina.
// . representa una casilla vacía.
// ------------------------------------------------------------
void imprimirTablero()
{
for(int i = 0; i < N; i++)
{
for(int j = 0; j < N; j++)
{
if(tablero[i][j] == 1)
cout << "Q ";
else
cout << ". ";
}
cout << endl;
}
}
// ------------------------------------------------------------
// Función principal del programa.
// Inicializa el tablero y llama al algoritmo
// que resuelve el problema.
// ------------------------------------------------------------
int main()
{
// Inicializamos todo el tablero en 0
// (sin reinas).
for(int i = 0; i < N; i++)
for(int j = 0; j < N; j++)
tablero[i][j] = 0;
// Intentamos resolver el problema
// comenzando por la columna 0.
if(resolverReinas(0))
{
cout << "Solucion encontrada:\n\n";
imprimirTablero();
}
else
{
cout << "No existe solucion.\n";
}
return 0;
}
Aplicaciones en informática
Aunque parezca un simple rompecabezas, este problema se usa para enseñar conceptos importantes como:
- diseño de algoritmos
- recursividad
- optimización
- inteligencia artificial
- búsqueda en árboles de decisión
Conclusión
El problema de las nueve reinas es un excelente ejercicio para comprender el funcionamiento de algoritmos de búsqueda y la técnica de backtracking. A través de una implementación relativamente sencilla en C++, es posible resolver un problema combinatorio complejo de manera eficiente.
Este tipo de ejercicios sigue siendo utilizado en cursos de programación y algoritmos para desarrollar habilidades de pensamiento lógico y estructuración de soluciones computacionales.
