【发布时间】:2015-11-23 19:31:39
【问题描述】:
我正在尝试解决 Prolog 中的Magic Hexagon 问题,在维度 5 中,现在(?)。我首先使用 2D 列表创建布局。然后我尝试约束该列表的每个元素(实际上是一个列表)。 但是,我无法让它工作,这是我的代码,在所有更新之后:
:- use_module(library(clpfd)).
solve(Dim) :-
length(L, 5), % define 5 diagonals
Offset is Dim - 2,
Flag is 0,
fill(L, Offset, Dim, Flag),
writeln(L),
constraint_sum(L, 38),
writeln(L).
constraint_sum([], _).
constraint_sum([H|T], Sum) :-
label(H),
sum_list(H, Sum),
constraint_sum(T, Sum).
fill([], _, _, _).
fill([H|T], Len, Dim, Flag) :-
Flag == 0,
Len < Dim,
length(H, Len),
H ins 1..19,
all_different(H),
NewLen is Len + 1,
fill(T, NewLen, Dim, Flag).
fill([H|T], Len, Dim, _) :-
length(H, Len),
H ins 1..19,
all_different(H),
NewLen is Len - 1,
Flag is 1,
fill(T, NewLen, Dim, Flag).
我得到了:
1 ?- 求解(5)。
[[_G2537,_G2581,_G2617],[_G2857,_G2893,_G2929,_G2965],
[_G3263,_G3299,_G3335,_G3371,_G3407],[_G3757,_G3793,_G3829,_G3865],
[_G4157,_G4193,_G4229]]
[[1,18,19],[1,2,16,19],[1,2,3,13,19],[1,2,16,19],[1,18,19 ]]
真的。
..如您所见,问题在于元素不是唯一的,因为我已将 all_different() 分别用于每个列表而不是整个列表,但我不知道该怎么做!
【问题讨论】:
-
sum_list内部使用is/2。因此,sum_list的第一个参数中必须有一些未实例化的列表元素。你的constraint_sum([H|T], Sum)看起来也很奇怪。递归调用不应该是constraint_sum(T, Sum)而不是sum_list(T, Sum)?而且您使用了两次Sum,这意味着它可能会失败,因为sum_list(H, Sum)将实例化Sum,并且它可能与获取Sum的递归调用不匹配。 -
但是没有元素被初始化,如果这就是你所说的实例化@lurker的意思。到目前为止,我看到的问题是所有元素都应该不同,并且通过我的实现,我使每个列表的所有元素都与同一列表中的元素不同,而不是与其他所有元素不同,因为它应该。
-
查看我的更新评论。使用
clpfd时,您必须先调用labeling(Vars),然后才能执行sum_list之类的操作来实例化这些值。所以labeling(H), sum_list(H, Sum)... -
@lurker 谢谢,我更正了,但仍然是同样的错误。那么 Sum 有一个固定值为 38 的值,不是吗?从在
solve()中调用constraint_sum()时开始。 -
请看完我关于
sum_list的cmets。 :)
标签: list prolog logic constraints clpfd