Algoritmo para colocar Zoombinis no barco do capitão Cajun?


12

Eu tenho jogado o relançamento de The Logical Journey of the Zoombinis recentemente e tentando implementar alguns algoritmos de computador que podem resolver os vários quebra-cabeças. Estou preso em como abordar o quebra-cabeça de balsa do capitão Cajun.

Para quem não conhece, um Zoombini é uma criatura com 4 atributos: cabelos, olhos, nariz e pés. Cada um desses atributos possui 5 valores possíveis; por exemplo, os pés de um Zoombini podem ser rodas, patins, tênis, uma mola ou uma hélice. Aqui está um exemplo de um Zoombini com cabelos bagunçados, óculos, nariz verde e tênis:

No quebra-cabeça da balsa, a tarefa é organizar uma coleção de 16 Zoombinis nos 16 assentos de uma balsa. O acordo deve obedecer à regra de que quaisquer dois assentos vizinhos ortogonalmente devem ser ocupados pelo Zoombinis que compartilham pelo menos um recurso. Se dois Zoombinis têm cabelos diferentes, olhos diferentes, narizes diferentes e pés diferentes um do outro, eles podem não se sentar um ao lado do outro.

A disposição dos assentos muda de nível; para concretude, vamos nos concentrar no nível "Muito Duro", no qual os 16 assentos estão dispostos em uma grade de 4 por 4. Aqui está um exemplo em que 15 Zoombinis estavam legalmente sentados, mas o Zoombini final parado no banco dos réus não pode ser colocado no último assento vazio, porque ela não compartilharia nenhum recurso com o Zoombini à sua direita:

Exemplo de quebra-cabeça quase completo

São 16! Tr 21 trilhões de atribuições possíveis de Zoombinis aos assentos. Portanto, basta executar todas as tarefas possíveis para ver se é legal não será prático. Quais são algumas heurísticas que eu poderia empregar para abordar esse problema de maneira sensata?


2
Isso me lembra o sudoku, e os solucionadores de sudoku geralmente implementam algum tipo de retorno.
mattecapu

2
Se você estiver pronto e disposto a pesquisar uma literatura mais complexa, poderá encontrar informações úteis pesquisando Subgraph Isomorphism Problem. O problema é encontrar um gráfico em outro gráfico. No seu caso, o subgráfico seria o assento (as bordas são adjacências), enquanto o gráfico pai seria o zoombinis, onde as conexões seriam a presença de uma característica compartilhada. Observe que, em geral, o problema é NP-completo e geralmente é feito também por retrocesso, no entanto, em alguns casos especiais (dos quais seu gráfico pode muito bem ser), são possíveis soluções polinomiais ou mesmo lineares.
Ordous 28/07

essa é uma ótima idéia, adorei o zoombinis quando criança - posso fazer a mesma coisa!
AlexFoxGill

Respostas:


8

Agradecemos a @mattecapu pelo termo útil de pesquisa no Google de "algoritmo de retorno". Isso me deu a comida para o pensamento que eu precisava.

Minha intuição atual é que talvez seja melhor preencher os assentos centrais - que têm quatro vizinhos - primeiro e salvar os assentos de canto - que têm apenas dois vizinhos - por último. Então, organizo os 16 assentos vazios em uma lista vinculada nesta ordem:

13   5   6  14

 7   1   2   9

 8   3   4  10

15  11  12  16

Aqui está um pseudocódigo que descreve a função que acabei escrevendo. Você alimenta uma lista contendo os 16 Zoombinis e um ponteiro para o primeiro assento na lista vinculada.

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

Na verdade, ele é executado surpreendentemente rápido! Eu fiquei muito satisfeita com isso.

Ainda não estou totalmente convencido de que organizei a lista de assentos na melhor ordem possível. Existem 24 restrições totais no problema, e a ordem ideal de preenchimento de assento enfrentaria cada uma dessas restrições o mais cedo possível no processo de preenchimento de assento, para que os galhos que não são viáveis ​​sejam removidos o mais rápido possível.


1
quando você preenche, 8fica adjacente 2, mas pode estar preenchendo 9adjacente a ambos 7e 3. bom trabalho resolvê-lo embora!
AlexFoxGill

Feito essa edição; ainda não tenho certeza se o esquema de dentro para fora é melhor do que preencher linha por linha. Talvez eu faça alguns testes de tempo.
28616
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.