Indicizzazione in un database di schemi: la soluzione Korf's Optimal Rubik's Cube


11

Come progetto divertente, ho lavorato su un'implementazione in C # di Richard Korf - Trovare soluzioni ottimali per il cubo di Rubik usando Pattern Database.

https://www.cs.princeton.edu/courses/archive/fall06/cos402/papers/korfrubik.pdf

In realtà ho funzionato, sto solo cercando di migliorare la mia soluzione.

Una cosa su cui Korf si occupa nel suo documento è il modo in cui memorizza e indicizza nei database dei modelli. Idealmente, penso che vogliamo usare un'istanza del cubo di rubik per generare un indice in un array.

La mia domanda riguarda il modo migliore per generare questo indice.

La mia soluzione è quella di generare un hash perfetto minimo. Ciò implica mantenere TUTTI i cubi in memoria fino a quando non ho scoperto l'intero database dei pattern e quindi generare un hash perfetto minimo basato su quello. L'MPH richiede un paio d'ore per funzionare a seconda delle dimensioni del database dei pattern, ma ho bisogno di farlo solo una volta da quando lo salvo su disco. Alla fine, posso buttare via i cubi stessi conservando solo il MPH. In questo modo posso prendere un cubo di rubik randomizzato, applicare il modello, quindi cercare l'indice di array nell'MPH per ottenere una lunghezza stimata della soluzione.

Credo che Korf e Shultz descrivano un modo migliore per determinare l'indice del cubo nel loro documento del 2005 intitolato "Ampia ricerca in ampie dimensioni"

https://www.aaai.org/Papers/AAAI/2005/AAAI05-219.pdf

Questo documento descrive un algoritmo per generare un indice basato sull'ordinamento lessicografico di una permutazione. Fondamentalmente puoi prendere la permutazione {1, 2, 3} e capire che è il più piccolo con un indice di 0. {1, 3, 2} è il prossimo con un indice di 1 e così via.

Sento che dovrei essere in grado di applicare questo algoritmo a un cubo di Rubik per ottenere il suo indice all'interno di un database di schemi, ma sto facendo fatica a capire come funzionerebbe nella pratica.

Il database dei pattern degli angoli, ad esempio, contiene tutti i cubi di rubik a cui sono stati tolti gli adesivi per bordi. Ci sono esattamente 88.179.840 cubi in questo set. Qualsiasi cubetto d'angolo su un cubo di Rubik può trovarsi in uno di 24 stati diversi. Lo stato dell'ottavo cubo d'angolo può essere calcolato in base agli altri 7, quindi i cubi nel database dei pattern solo degli angoli hanno ciascuno 7 valori tra 0 e 23

es. {0, 3, 6, 9, 12, 15, 18, 21} definisce il cubo "risolto" con tutti gli adesivi sui bordi rimossi.

se ruoto la faccia anteriore di 90 gradi la permutazione potrebbe essere: {0, 3, 11, 23, 12, 15, 8, 20}

C'è un modo per ottenere un indice da questo tipo di permutazioni?


Probabilmente troverete questa interessante.
Tom van der Zanden,

interessante! tu dici che "smorza" qualcosa sul giornale. sarebbe meglio essere più specifici sulla sezione che non è "arricchita". dici anche di farlo funzionare. qual è la tua implementazione iniziale dell'indicizzazione? è un progetto scolastico? suggerire ulteriori chat di informatica su di esso. anche ad esempio blog su di esso o open source del codice può essere utile per gli altri e portare a maggiori dettagli. inoltre l'articolo non sembra riferirsi ad alcuna funzione di hashing ...
vzn,

Ho implementato l'algoritmo di Korf: github.com/benbotto/rubiks-cube-cracker . Anch'io ho trovato difficile l'indicizzazione, quindi ho scritto un articolo al riguardo su Medium: medium.com/@benjamin.botto/…
avejidah

Risposte:


6

Non spieghi cosa significano i numeri da 0 a 23, ma secondo questa risposta , puoi rappresentare lo stato degli angoli usando otto coppie , dove è una permutazione di , e (diciamo) è determinato da . In totale, questo dà gradi di libertà. Supponendo che sia possibile scomporre in coppie , è possibile convertire facilmente una posizione in un indice codificando separatamente la permutazione(pi,oi)(p0,,p7)(0,,7)oi{0,1,2}o7o0,,o68!37=88179840{0,,23}(pi,oi)(p0,,p7)(che il documento AAAI spiega come fare) e i valori , che è possibile codificare in base 3. Riunendo i due valori in modo ovvio (ad esempio, o ), otteniamo un indice.o0,,o637p+o8!o+p


Ehi Yuval, grazie per il commento. Per me, da 0 a 23 sono il modo in cui identifico la posizione / orientamento univoco in cui può trovarsi un cubo d'angolo. 8 posizioni per 3 orientamenti per posizione = 24. Fortunatamente posso facilmente dividere questo valore in tuple di posizione / orientamento separate. La tua risposta mi ha portato a questo codice che è un'implementazione dell'algoritmo che stai descrivendo. github.com/brownan/Rubiks-Cube-Solver/blob/master/cornertable.c Dovrò fare un po 'di lavoro per renderlo più generico (in modo che io possa gestire schemi diversi rispetto a "solo angoli") ma ora Sono sulla strada giusta grazie!
Cosmosis,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.