Я недавно играл в переиздание The Logical Journey of Zoombinis и пытаюсь реализовать некоторые компьютерные алгоритмы, которые могут решать различные головоломки. Я застрял на том, как подойти к загадке парома Капитана Каджуна.
Для тех, кто незнаком, Zoombini - это существо с 4 атрибутами: волосы, глаза, нос и ступни. Каждый из этих атрибутов имеет 5 возможных значений; например, ногами Zoombini могут быть колеса, роликовые коньки, кроссовки, пружина или пропеллер. Вот пример Zoombini с грязными волосами, очками, зеленым носом и кроссовками:
В головоломке с паромом задача состоит в том, чтобы собрать коллекцию из 16 зомби на 16 сиденьях парома. Компоновка должна подчиняться правилу, согласно которому любые два ортогонально соседних места должны быть заняты Zoombinis, которые имеют хотя бы одну особенность. Если два зоомбини имеют разные волосы, разные глаза, разные носы и разные ноги, они могут не сидеть рядом друг с другом.
Расположение сидений меняется в зависимости от уровня; для конкретности, давайте сосредоточимся на уровне «Очень жесткий», в котором 16 мест расположены в сетке 4 на 4. Вот пример, где 15 Зоомбини были юридически размещены, но последний Зоомбини, стоящий на скамье подсудимых, не может быть размещен на последнем свободном месте, потому что она не будет иметь никаких особенностей с Зоомбини справа от нее:
Есть 16! ≈ 21 триллион возможных назначений Зомбини на места. Так что просто пробежаться по каждому возможному заданию, чтобы увидеть, законно ли это, не будет практичным. Какие эвристики я мог бы использовать для разумного подхода к этой проблеме?
источник
Subgraph Isomorphism Problem
. Проблема в том, чтобы найти один граф в другом. В вашем случае подграфом будет размещение (ребра - смежность), в то время как родительским графом будет zoombinis, где в соединениях будет присутствовать общая черта. Обратите внимание, что в общем случае задача является NP-полной и обычно выполняется также путем обратного отслеживания, однако для некоторых особых случаев (из которых ваш граф вполне может быть) возможны полиномиальные или даже линейные решения.Ответы:
Спасибо @mattecapu за полезный поисковый запрос Google для "алгоритма возврата". Это дало мне пищу для размышлений, в которых я нуждался.
Моя текущая интуиция состоит в том, что, возможно, было бы лучше заполнить центральные места - у которых есть 4 соседа - сначала, и сохранить угловые места - у которых есть только 2 соседа - для последнего. Итак, я расположил 16 свободных мест в связанном списке в следующем порядке:
Вот некоторый псевдокод, который описывает функцию, которую я написал. Вы передаете ему список, содержащий 16 зоомини и указатель на первое место в связанном списке.
Это на самом деле работает на удивление быстро! Я был очень доволен этим.
Я еще не полностью убежден, что я расположил список мест в лучшем возможном порядке. Всего существует 24 ограничения на проблему, и идеальный порядок заполнения сидения должен был бы противостоять каждому из этих ограничений как можно раньше в процессе заполнения места, так что ветви, которые не являются жизнеспособными, максимально быстро отсекаются.
источник
8
вы только смежны2
, но вы можете заполнять,9
что смежно с обоими7
и3
. хорошая работа, решающая это все же!