Prolog座位限制

Com*_*sNo 6 prolog clpfd

我必须在Prolog中解决以下问题.亚历克斯,弗雷德和简是3个孩子,他们用10米长的木板做了一个跷跷板.它们沿着木板标记了11个座位,每个位置相距一米.座位数为-5,-4,-3,-2,-1,0,1,2,3,4,5,其中0为中心位置.亚历克斯,弗雷德和简的重量分别为4,3和2个单位.他们有兴趣知道当他们三个坐在木板的某个地方时,他们如何让跷跷板平衡,每个孩子都必须坐在不同的位置.

一个座位位置是Alex,Fred和Jane位于-4,2和5位置,因为(-4*4)+(2*3)+(5*2)= - 16 + 6 + 10 = 0. Alex,Fred和Jane的另一个座位是-4,4和2,而另一个是-3,2和3.

我已尝试以下方法来解决此问题但得到错误:错误:输入错误:integer' expected, found[_ G11889,_G11892,_G11895]'

任何人都可以帮助解释我哪里出错/如何去做?

提前谢谢了

:-use_module(library(clpfd)).

find(Seats):-
    Seats=[Alex, Fred, Jane],
    Seats in -5..5,
    all_different(Seats),
    (Alex*4+Fred*3+Jane*2)#=0,     % I am not sure about this line
    labeling([],Seats).
Run Code Online (Sandbox Code Playgroud)

小智 3

我会使用对称性破缺来减少解的数量。简单的对称性是当 (A,F,J) 是解时,(-A,-F,-J) 也是解。因此,我们可以限制 J #>= 0,并记住如果 J #\= 0,则存在翻转解决方案。

因此,我们首先导入 CLP(FD) 库:

Welcome to SWI-Prolog (Multi-threaded, 64 bits, Version 7.1.16)
Copyright (c) 1990-2014 University of Amsterdam, VU Amsterdam
?- use_module(library(clpfd)).
Run Code Online (Sandbox Code Playgroud)

然后我们制定我们的查询,而不是 (in)/2 应该使用 (ins)/2,正如 larsman 已经指出的那样。使用 (in)/2 也会导致错误消息。线性形式不需要括号。所以我们得到:

?- Seats=[Alex, Fred, Jane],
   Seats ins -5..5,
   Jane #> 0,
   all_different(Seats),
   Alex*4+Fred*3+Jane*2 #= 0,
   label(Seats),
   write(Seats), nl, fail; true.
[-4,2,5]
[-4,4,2]
[-3,2,3]
[-2,0,4]
[-2,2,1]
[-1,-2,5]
[-1,0,2]
[0,-2,3]
[1,-4,4]
true.
Run Code Online (Sandbox Code Playgroud)

如果您需要没有人坐在跷跷板中间,您可以获得针对不同重量的独特解决方案。权重 15、10 和 6 可以完成这项工作。这是一个运行示例,请注意修改后的 (ins)/2 语句:

?- Seats=[Alex, Fred, Jane],
   Seats ins -5.. -1\/1..5,
   Jane #> 0,
   all_different(Seats),
   Alex*15+Fred*10+Jane*6 #= 0,
   label(Seats),
   write(Seats), nl, fail; true.
[-4,3,5]
true.
Run Code Online (Sandbox Code Playgroud)

再见