케이준 선장의 페리 보트에 Zoombinis를 설치하기위한 알고리즘?


12

나는 최근 Zoombinis의 논리 여행의 재 발표를 재생 하고 다양한 퍼즐을 해결할 수있는 컴퓨터 알고리즘을 구현하려고했습니다. 케이준 선장의 페리 보트 퍼즐에 접근하는 방법에 붙어 있습니다.

익숙하지 않은 사람들을 위해 Zoombini는 머리카락, 눈, 코 및 발의 4 가지 속성을 가진 생물입니다. 각 속성에는 5 가지 가능한 값이 있습니다. 예를 들어 Zoombini의 발은 바퀴, 롤러 스케이트, 운동화, 스프링 또는 프로펠러 일 수 있습니다. 지저분한 머리, 안경, 녹색 코 및 운동화가 포함 된 Zoombini의 예는 다음과 같습니다.

페리 보트 퍼즐에서 임무는 페리 보트의 16 석에 16 개의 Zoombinis 컬렉션을 배치하는 것입니다. 이 배치는 적어도 하나의 특징을 공유하는 Zoombinis가 두 개의 직교 인접 좌석을 점유해야한다는 규칙을 준수해야합니다. 두 개의 Zoombinis가 다른 머리카락, 다른 눈, 다른 코 다른 발을 가지면 서로 옆에 앉지 않을 수 있습니다.

좌석 배치는 레벨별로 변경됩니다. 구체적으로, 16 개의 시트가 4x4 그리드로 배열되는 "매우 단단한"레벨에 초점을 맞추겠습니다. 다음은 15 개의 Zoombinis가 합법적으로 장착되었지만 도크에 서있는 최종 Zoombini는 마지막 빈 좌석에 배치 할 수없는 예입니다. 왜냐하면 Zoombini와 오른쪽으로 기능을 공유하지 않기 때문입니다.

거의 완성 된 퍼즐의 예

16이 있습니다! bin 좌석에 21 조 개의 Zoombinis 할당 가능. 따라서 가능한 모든 과제를 수행하는 것이 합법적이지 않은지 확인하십시오. 이 문제에 현명하게 접근하기 위해 사용할 수있는 휴리스틱은 무엇입니까?


2
그것은 스도쿠를 생각 나게하고 스도쿠 솔버는 일반적으로 일종의 역 추적을 구현합니다.
mattecapu

2
좀 더 복잡한 문헌을 찾을 준비가 되었으면 검색하여 유용한 정보를 찾을 수 있습니다 Subgraph Isomorphism Problem. 문제는 다른 그래프에서 하나의 그래프를 찾는 것입니다. 귀하의 경우 하위 그래프는 좌석 (가장자리는 인접)이며 부모 그래프는 확대 / 축소이며 연결은 공유 특성의 존재입니다. 일반적으로 문제는 NP- 완전이며 일반적으로 역 추적을 통해 이루어 지지만 일부 특수한 경우 (그래프가 매우 적합 할 수 있음) 다항식 또는 선형 솔루션도 가능합니다.
Ordous

이것은 좋은 생각입니다. 나는 zoombinis를 어린 시절 좋아했습니다. 나는 똑같은 일을 할 수도 있습니다!
AlexFoxGill

답변:


8

"backtracking algorithm"의 유용한 Google 검색어에 대한 @mattecapu에게 감사드립니다. 그것은 나에게 내가 필요한 생각을위한 음식을 주었다.

현재 직관은 네 개의 이웃이있는 중앙 좌석을 채우고 마지막에 두 개의 이웃이있는 코너 좌석을 저장하는 것이 더 나을 수 있다는 것입니다. 그래서 나는 16 개의 빈 자리를 다음과 같은 순서로 링크 된 목록으로 배열합니다.

13   5   6  14

 7   1   2   9

 8   3   4  10

15  11  12  16

다음은 필자가 작성하는 기능을 설명하는 의사 코드입니다. 16 개의 Zoombinis가 포함 된 목록과 링크 된 목록의 첫 번째 좌석에 대한 포인터를 제공합니다.

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

실제로 놀라 울 정도로 빠르게 실행됩니다! 나는 그것을 매우 기쁘게 생각했다.

좌석 목록을 최상의 순서로 정렬했다고 아직 확신하지 않습니다. 이 문제에는 총 24 개의 제약이 있으며 이상적인 시트 필링 순서는 시트 필링 프로세스에서 가능한 한 빨리 각 제약 조건에 직면하여 실행 불가능한 분기가 최대한 빨리 정리되도록합니다.


1
당신이 채울 때 8당신 만이 인접 해있어 2,하지만 당신은 충전이 될 수 9모두에 인접 7하고 3. 그것을 해결하는 좋은 일!
AlexFoxGill

편집했다; 그럼에도 불구하고 내부 구성표가 행 단위로 채워지는지 여부는 확실하지 않습니다. 어쩌면 타이밍 테스트를해볼 수도 있습니다.
thecommexokid
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.