2014-12-13 4 views
3

This is the gameРешить Instant Insanity в PROLOG с CLP

мне удалось сформировать проблему с 4-х цветов и 4 кубов случайно смешанных и ниже цветовая схема предложенной в ссылке.

Таким образом, целью является создание возможных решений проблемы с использованием clpfd. Основной принцип является основным, одно и то же лицо для всех 4 кубов должно быть разным. Использовал all_different/2 по 4 спискам, каждый из которых содержит соответствующую сторону «башни», состоящую из 4 лиц. Все идет нормально.

Теперь я должен заверить, что конечный результат - это состав действительных ходов, а форма 4 кубов должна оставаться неизменной. Как я могу это сделать?

Я также подумал о внедрении этого алгоритма графа, чтобы получить возможные решения для исходной проблемы, но я действительно не знаю, как или даже если это возможно, используя Программу логики Constraint.

С другой стороны, поговорил с другом, который также занимается этим проектом, и он просто реализует основной принцип, о котором я говорил. Этого достаточно? Проделав некоторое время с этим приложением JavaScript на странице, и хотя кубы одинаковы, у решений, похоже, есть кубы, ориентированные в разных направлениях.

ответ

2

Ваша основная идея - звук. Вам действительно нужны только ограничения all_different/1. Интересная вещь в этой головоломке - как представить кубы. Я возьму прямолинейный подход и представляю кубы почти так же, как на странице, на которую вы ссылаетесь. Например, я буду представлять первую куб, чей 2D-макет:

b 
r r r g 
    y 

в качестве основного Prolog термина:

tmb(b,[r,r,r,g],y)

, где tmb означает "верхние, средний, нижний" часть куб.

Изначально мы дали следующие 4 кубика:

cube(tmb(b,[r,r,r,g],y)). 
cube(tmb(r,[g,y,g,b],b)). 
cube(tmb(r,[b,g,r,y],y)). 
cube(tmb(g,[b,r,y,g],y)). 

Следующие предикаты относятся куб с его стороны интерес:

side_cube(top, tmb(Top,_,_), Top). 
side_cube(front, tmb(_,[_,Front|_],_), Front). 
side_cube(bottom, tmb(_,_,Bottom), Bottom). 
side_cube(back, tmb(_,[_,_,_,Back],_), Back). 

Главное теперь: Что делает поворот куба выглядят?

cube_rotation(Cube0, Cube) :- 
     cube_flip(Cube0, Cube1), 
     cube_rotation_(Cube1, Cube). 

cube_rotation_(tmb(Top,[A,B,C,D],Bottom), tmb(Top,[E,F,G,H],Bottom)) :- 
     append(_, [E,F,G,H|_], [A,B,C,D,A,B,C]). 

cube_flip(Cube, Cube). 
cube_flip(tmb(Top,[A,B,C,D],Bottom), tmb(A,[Bottom,B,Top,D],C)). 
cube_flip(tmb(Top,[A,B,C,D],Bottom), tmb(B,[A,Bottom,C,Top],D)). 

УПРАЖНЕНИЕ: Заполните 3 недостающих положений cube_flip/2 для полного решения.

Описывая решение теперь легко, даже без CLP (FD):

solution(Cs) :- 
     findall(C, cube(C), Cs0), 
     same_length(Cs0, Cs), 
     maplist(side_different(Cs), [top,front,bottom,back]), 
     maplist(cube_rotation, Cs0, Cs). 

side_different(Cubes, Side) :- 
     maplist(side_cube(Side), Cubes, Colors), 
     all_dif(Colors). 

all_dif([]). 
all_dif([D|Ds]) :- maplist(dif(D), Ds), all_dif(Ds). 

Даже приведенный выше код (который, как я уже говорил, не хватает 3 статьи, которые я опущенные в качестве упражнения для вас) мы уже находим два решения:

?- solution(Cubes). 
Cubes = [tmb(r,[r,y,r,b],g),tmb(y,[g,b,g,r],b),tmb(b,[y,g,r,y],r),tmb(g,[b,r,y,g],y)] ; 
Cubes = [tmb(r,[r,b,r,y],g),tmb(y,[g,r,g,b],b),tmb(b,[r,y,y,g],r),tmb(g,[y,g,b,r],y)] ; 
false. 

для использования CLP (FD), вы можете просто отобразить все цвета в целых числах, а также использовать all_different/1 (или all_distinct/1, для более сильного распространения) вместо all_dif/1.