Пролог с советами Constrains - PullRequest
0 голосов
/ 03 декабря 2011

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

peca(1,[0,1,1,1]).
peca(2,[0,0,1,0]).
peca(3,[1,0,0,0]).
peca(4,[0,1,0,1]).
peca(5,[1,1,1,1]).
peca(6,[0,0,0,1]).
peca(7,[1,1,0,1]).
peca(8,[0,0,1,1]).
peca(9,[1,1,1,0]).
peca(10,[1,0,1,1]).
peca(11,[1,1,0,0]).
peca(12,[0,1,0,0]).

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

encaixaOrientacao(Vars,0):-
                Vars#=N,
                    peca(N,[L,U,R,D]),
                peca(N+1,[NL,NU,NR,ND]),
                R+NL#=1,
                peca(N+1,[L,U,R,D]),
                peca(N+2,[NL,NU,NR,ND]),
                    R+NL#=1,
                peca(N+2,[L,U,R,D]),
                peca(N+3,[NL,NU,NR,ND]),
                R+NL#=1,
                peca(N,[L,U,R,D]),
                peca(N+4,[NL,NU,NR,ND]),
                    D+NU#=1,
                peca(N+1,[L,U,R,D]),
                peca(N+5,[NL,NU,NR,ND]),
                D+NU#=1,
                peca(N+2,[L,U,R,D]),
                peca(N+6,[NL,NU,NR,ND]),
                D+NU#=1,
                peca(N+3,[L,U,R,D]),
                peca(N+7,[NL,NU,NR,ND]),
                D+NU#=1,
                peca(N+4,[L,U,R,D]),
                peca(N+5,[NL,NU,NR,ND]),
                R+NL#=1,
                peca(N+5,[L,U,R,D]),
                    peca(N+6,[NL,NU,NR,ND]),
                R+NL#=1,
                peca(N+6,[L,U,R,D]),
                peca(N+7,[NL,NU,NR,ND]),
                R+NL#=1,
                peca(N+4,[L,U,R,D]),
                peca(N+8,[NL,NU,NR,ND]),
                D+NU#=1,
                peca(N+5,[L,U,R,D]),
                peca(N+9,[NL,NU,NR,ND]),
                D+NU#=1,
                peca(N+6,[L,U,R,D]),
                peca(N+10,[NL,NU,NR,ND]),
                D+NU#=1,
                peca(N+7,[L,U,R,D]),
                peca(N+11,[NL,NU,NR,ND]),
                D+NU#=1,
                peca(N+8,[L,U,R,D]),
                peca(N+9,[NL,NU,NR,ND]),
                R+NL#=1,
                peca(N+9,[L,U,R,D]),
                peca(N+10,[NL,NU,NR,ND]),
                R+NL#=1,
                peca(N+10,[L,U,R,D]),
                peca(N+11,[NL,NU,NR,ND]),
                R+NL#=1.

Это главное, пока игнорируйте O, так как я до сих пор не реализовал его

  main(Vars):-
        read(O),
        length(Vars,12),
        domain(Vars,1,12),
        all_distinct(Vars),

        %ainda nao funciona o encaixaOrientacao
        encaixaOrientacao(Vars,O),

        labeling([],Vars).

Я сделал это так, но я потерян к тому, что делать дальше, мне действительно нужна помощь, чтобы сделать эту работу. Так что любые советы будут приветствоваться

Эта головоломка сама по себе http://www.jaapsch.net/puzzles/rapids.htm Хотя я до сих пор ничего не реализовал в отношении "границ" и ориентации

1 Ответ

0 голосов
/ 05 декабря 2011

Как сказал Мог в своем комментарии, это все тот же вопрос, поэтому ожидайте, что он будет закрыт.

Тем не менее, две вещи: я не думаю, что ваш предикат encaixaOrientacao/2 будет работать, так как вы получаете доступ к определенным частям, вызывая peca/2 и ограничиваете некоторые переменные, тем самым указывая, какая часть идет куда. Есть также несколько других проблем с вашей реализацией:

  • Вы, вероятно, хотели выразить что-то вроде peca(Vars[N+1], ...), когда писали peca(N+1, ...). Это не работает в Прологе.
  • вы повторно используете L,U,R,D,NL,NU,NR,ND переменные. Это означает, что они будут иметь одинаковые значения при каждом вызове peca/2. Это не сработает.

Кроме того, ваш предикат peca/2 является обычным предикатом, а не ограничением. Это означает, что когда вы вызываете encaixaOrientacao/2, любой вызов peca/2 будет напрямую извлекать какой-либо факт из вашей базы данных, а ваши ограничения X+Y #= 1 будут проверять, является ли это возможным соседом. Хотя это будет работать в принципе (по модулю проблем, на которые я указывал выше), это не будет ограничивающим программированием, поскольку ограничения будут использоваться только после выбора следующего фрагмента. Ваша модель должна различать поля и фрагменты, и ограничения X+Y #= 1 будут ограничивать поля, а не фрагменты.

Следующим шагом будет выражение ограничения «если кусок N находится в позиции X, то ребра этого поля имеют свойства P», а «если ребра поля X имеют свойства P, то он не может содержать часть N "(последнее было опущено в моем ответе на ваш первый вопрос, но что сделало бы решение правильным программированием ограничений вместо использования ограничений просто в качестве тестов).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...