È BFS, ma non si cerca la scacchiera; cercare lo spazio di posizionamenti:
Stato iniziale: nessun cavaliere è posto
mossa valido: posto un cavaliere su qualsiasi tessera non occupata
stato
Obiettivo: tutte le tessere sono o occupati o attaccati
base algoritmo (BFS dello spazio di stato):
- inserire lo stato iniziale nella coda BFS.
- mentre c'è qualcosa nella coda:
- rimuovere uno stato dalla coda.
- per ogni riquadro non occupato:
- creare una copia dello stato corrente.
- aggiungi un cavaliere a quella tessera.
- se il nuovo stato non esiste nella coda:
- se il nuovo stato è uno stato obiettivo, terminare.
- altro aggiungerlo alla coda.
Si noti che sto supponendo che tutti i percorsi di uno stato sono della stessa lunghezza. Questo è vero quando si cerca un insieme di posizionamenti in questo modo, ma non è vero in generale. Nei casi in cui ciò non è vero, è necessario memorizzare l'insieme di tutti i nodi visitati per evitare di rivedere gli stati già esplorati.
Potrebbe essere necessario aggiungere i cavalieri da sinistra a destra, dall'alto verso il basso. Quindi non è necessario verificare la presenza di duplicati nella coda. Inoltre, puoi scartare uno stato in anticipo se sai che una tessera non attaccata non può essere attaccata senza violare l'ordine di inserimento.
Se non si esegue questa operazione e si lascia il controllo duplicato, l'algoritmo produrrà comunque risultati corretti, ma lo farà molto più lentamente. 40.000 volte più lento, approssimativamente (8! = 40 320 è il numero di duplicati di uno stato di 8 cavalieri).
Se si desidera un algoritmo più veloce, esaminare A *. Qui, una possibile euristica è:
- contare il numero di tessere unattacked e non occupati
- dividere il conteggio da nove, arrotondamento (cavaliere non può attaccare otto nuove piastrelle o occupare più di uno)
- la distanza (il numero di cavalieri necessari per essere aggiunto) non è più di questo numero.
Un euristico migliore noterebbe il fatto che un cavaliere può attaccare solo le tessere dello stesso colore e occupare una tessera del colore opposto. Ciò potrebbe migliorare leggermente l'euristica precedente (ma potrebbe comunque aiutare molto).
Un euristico migliore dovrebbe essere in grado di sfruttare il fatto che un cavaliere può coprire punti liberi in non più di 5x5 quadrati. Un euristico dovrebbe calcolare velocemente, ma questo può aiutare quando ci sono pochi punti da coprire.
Dettagli tecnici:
Si può rappresentare ogni stato come una maschera di bit a 64-bit. Sebbene ciò richieda una manipolazione bit a bit, aiuta davvero la memoria e il controllo di uguaglianza dei numeri a 64 bit è veloce. Se non puoi avere un numero a 64 bit, usa due numeri a 32 bit - questi dovrebbero essere disponibili.
La coda di array circolare è efficiente, e non è che difficile espandere la sua capacità. Se devi implementare la tua coda, scegli questa.
Grazie mille per la risposta dettagliata Jan. Leggerò questo in dettaglio e provo a venire con una semplice implementazione. Potrebbe volerci un po 'di tempo, visto che sono nuovo per questo :) – ragebiswas
Hai un'implementazione di questo? Trovo difficile capire il tuo pseudo codice. – Pavel
Stai dicendo "per ogni tessera non occupata" e presumo che tu stia solo mettendo i cavalieri in ogni tessera del tabellone e ora il tabellone è pieno di cavalieri ... Ovviamente ogni tessera è ora occupata o attaccata. – Pavel