Algoritmo per far sedere Zoombinis sul traghetto del Capitano Cajun?


12

Recentemente ho giocato alla nuova release di The Logical Journey of the Zoombinis e ho cercato di implementare alcuni algoritmi informatici in grado di risolvere i vari enigmi. Sono bloccato su come affrontare il puzzle del traghetto del Capitano Cajun.

Per quelli che non hanno familiarità, uno Zoombini è una creatura con 4 attributi: capelli, occhi, naso e piedi. Ognuno di questi attributi ha 5 possibili valori; per esempio, i piedi di uno Zoombini possono essere ruote, pattini a rotelle, scarpe da ginnastica, una molla o un'elica. Ecco un esempio di Zoombini con capelli disordinati, occhiali, naso verde e scarpe da ginnastica:

Nel puzzle del traghetto, il compito è quello di organizzare una raccolta di 16 Zoombinis sui 16 posti di un traghetto. L'accordo deve obbedire alla regola secondo la quale due posti vicini ortogonalmente devono essere occupati da Zoombinis che condividono almeno una caratteristica. Se due Zoombinis hanno capelli diversi, occhi diversi, nasi diversi e piedi diversi l'uno dall'altro, potrebbero non sedersi uno accanto all'altro.

La disposizione dei posti cambia di livello; per concretezza, concentriamoci sul livello "Molto difficile", in cui i 16 posti sono disposti in una griglia 4 per 4. Ecco un esempio in cui 15 Zoombinis sono stati seduti legalmente, ma l'ultimo Zoombini in piedi sul molo non può essere posizionato sull'ultimo posto vuoto, perché non condividerebbe alcun aspetto con Zoombini alla sua destra:

Esempio di puzzle quasi completato

Ce ne sono 16! ≈ 21 trilioni di possibili assegnazioni di Zoombinis ai posti. Quindi semplicemente eseguendo ogni possibile incarico per vedere se è legale non sarà pratico. Quali sono alcune euristiche che potrei impiegare per affrontare questo problema in modo sensato?


2
Mi ricorda il sudoku, e i solutori del sudoku di solito implementano una sorta di backtracking.
Mattecapu,

2
Se sei pronto e disposto a scavare in qualche letteratura più complessa, puoi trovare informazioni utili cercando Subgraph Isomorphism Problem. Il problema è trovare un grafico in un altro grafico. Nel tuo caso il sottografo sarebbe la sede (i bordi sono adiacenze), mentre il grafico principale sarebbe lo zoombinis, dove le connessioni sarebbero la presenza di un tratto condiviso. Si noti che in generale il problema è NP-completo e di solito viene eseguito anche con il backtracking, tuttavia per alcuni casi speciali (di cui il grafico potrebbe essere benissimo), sono possibili soluzioni polinomiali o persino lineari.
Ordous,

questa è un'ottima idea, ho amato gli zoombin da bambino - potrei fare la stessa cosa!
AlexFoxGill,

Risposte:


8

Grazie a @mattecapu per l'utile termine di ricerca di Google "algoritmo di backtracking". Questo mi ha dato il cibo per il pensiero di cui avevo bisogno.

La mia attuale intuizione è che potrebbe essere meglio riempire i posti centrali — che hanno 4 vicini — per primi, e salvare i posti d'angolo — che hanno solo 2 vicini — per ultimo. Quindi organizzo i 16 posti vuoti in un elenco collegato in questo ordine:

13   5   6  14

 7   1   2   9

 8   3   4  10

15  11  12  16

Ecco alcuni pseudocodici che descrivono la funzione che ho finito per scrivere. Gli dai un elenco contenente i 16 Zoombinis e un puntatore al primo posto nell'elenco collegato.

function recursively_assign_seat(zoombini_list, seat):

    if zoombini_list is empty:
        return True

    else:
        for each z in zoombini_list:

            for each n in seat.neighbors:
                if not allowed_as_neighbors(z, n):
                    next z

            seat.occupant ← z
            if recursively_assign_seat(zoombini_list.remove(z), seat.next):
                return True
            else:
                seat.occupant ← None

        return False

In realtà funziona sorprendentemente rapidamente! Ne sono rimasto molto soddisfatto.

Non sono ancora del tutto convinto di aver organizzato l'elenco dei posti nel miglior ordine possibile. Esistono 24 vincoli totali sul problema e l'ordine ideale di riempimento dei sedili dovrebbe affrontare ciascuno di questi vincoli il più presto possibile nel processo di riempimento dei sedili, in modo che i rami non vitali vengano potati al massimo rapidamente.


1
quando riempi 8sei solo adiacente 2, ma potresti riempire 9che è adiacente a entrambi 7e 3. bel lavoro risolvendolo però!
AlexFoxGill,

Fatto quella modifica; non sono ancora sicuro se lo schema dentro e fuori batte solo compilando riga per riga, però. Forse farò dei test di cronometraggio.
comitato ha espresso il
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.