il
Problema delle N Regine
Il problema delle 8 Regine, proposto
per la prima volta nel 1848 da Max Bezzel, richiede di disporre 8 regine su una scacchiera, in modo che nessuna
sia minacciata da un'altra (considerando che la Regina si muove in
orizzontale, Verticale e Diagonale).
Il problema si può estendere a
una scacchiera NxN, su cui disporre N regine.
Escludendo il caso banale di
una regina su una scacchiera di una sola casella, il Lato deve essere
almeno di quattro caselle per trovare una soluzione (2 disposizioni
simmetriche).
Il numero delle soluzioni cresce al crescere
del Lato.
Struttura dati
La scacchiera dovrebbe
essere allocata in una matrice NxN, con righe e colonne da
1 a Lato.
Per velocizzare le operazioni, però, la scacchiera verrà solo immaginata
nella fase di analisi e non corrisponde ad una reale variabile in memoria:
la posizione delle Regine viene controllata tramite quattro array monodimensionali.
int Colonne [ ]
|
segnala le colonne occupate
dalle Regine
|
int Destre [ ]
|
segnala le diagonali principali occupate
|
int Sinistre[
]
|
segnala le diagonali secondarie occupate
|
int Casa [ ]
|
riporta le posizioni di ogni
regina, una per rigo;
è usato solo per la visualizzazione della soluzione
|
Le case di una diagonale
destra hanno costante la differenza tra gli indici.
Le case di una diagonale sinistra hanno costante la somma degli
indici.
Le diagonali sono in numero quasi doppio rispetto alle righe e alle
colonne, andranno quindi dimensionate adeguatamente.
Nei tre array 0 indica la linea libera, 1 indica la linea occupata.
int Lato |
lato della scacchiera e numero delle
Regine |
long Totale |
numero delle soluzioni trovate |
Per velocizzare le operazioni, le variabili sono
dichiarate globalmente.
Algoritmo
Il calcolo si basa sull'uso della funzione ricorsiva
Regine():
-
la funzione riceve il rigo su cui operare (valori
da 1 a Lato);
-
tenta di posizionare una Regina sul rigo alle
colonne da 1 a N, verificando che non siano già occupate la colonna,
la diagonale destra o la diagonale sinistra.
-
ad ogni regina posizionata correttamente, viene
chiamata ricorsivamente la stessa funzione per il rigo sottostante;
-
sul rigo = Lato, la ricorsione termina e viene
segnalata una nuova disposizione.
Codice Sorgente in C
Il programma è stato
scritto in linguaggio C per compilatore Borland 3.1, ma può essere
facilmente adattato ad un qualsiasi compilatore.
Potete scaricare direttamente l'eseguibile di
soli 13 Kb.
Considerazioni finali
I tempi di calcolo sono notevolmente allungati dalla
visualizzazione continua delle soluzioni; per analizzare qualche soluzione
occorre fermare l'esecuzione con il tasto Pausa.
Eliminando dal programma la chiamata alla Sub VediSoluzione(),
i tempi si riducono drasticamente: per trovare tutte le disposizioni di 15
Regine su una scacchiera con lato 15 (oltre due milioni) bastano circa 20
secondi. In ogni caso il tempo di calcolo cresce di un fattore 7 (circa) ad ogni
incremento del lato.
|