Prolog与Constraints建议

时间:2011-12-03 16:57:51

标签: prolog

我正在尝试解决一个简单的拼图游戏,其中一块作为一个孔或一个突出部分,并且所有部分必须相互适合   到目前为止,我有这个代表每一块,第一个数字代表id,数组中的数字代表它是否有一个孔(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]).

这就是我所做的所有限制,只想象一个4x3拼图,其中每行为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 :(得分:0)

正如Mog在评论中所说的那样,这仍然是同一个问题,所以期待关闭。

但有两件事:我不认为你的谓词encaixaOrientacao/2会起作用,因为你通过调用peca/2访问特定的部分并约束一些变量,从而说明哪一部分在哪里。您的实施还存在其他几个问题:

  • 您可能希望在撰写peca(Vars[N+1], ...)时表达peca(N+1, ...)之类的内容。这在Prolog中不起作用。
  • 您正在重复使用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“(后者是我对你的第一个问题的答案中省略的内容,但是什么会使解决方案成为正确的约束编程而不是仅仅将约束用作测试)。