我正在寻找一种方法,在给定一组约束的情况下找到所有可能的解决方案。我在学校有过序幕,但已经有一段时间了,所以考虑一下我相当新。我想要实现的是这样的:
fC(U,V,X,Y,Z):-
(U*2 + V - Y -(2*Z)) =< -5,
(U*2 + V - Y -(2*Z)) >= -108,
(U+V+X+Y+Z) =:= 54.
U,V,X,Y和Z是非负数。他们只有2个规则来计算它们:介于-5和-108之间(当我试图在上面的代码中制定一定的权重时),并加在一起恰好是54。
我尝试生成5个从0到54的列表,查找所有组合然后检查我的约束&#39;,我很快耗尽了内存,所以我一定做错了。
亲切的问候,
耶勒
答案 0 :(得分:2)
对于整数,clpfd约束很容易。例如,在SICStus Prolog或SWI中:
:- use_module(library(clpfd)).
fC(U,V,X,Y,Z):-
U*2 + V - Y -2*Z #=< -5,
U*2 + V - Y -2*Z #>= -108,
U+V+X+Y+Z #= 54.
您已使用最常见的查询获取剩余目标:
?- fC(U, V, X, Y, Z).
X+U+V+Z+Y#=54,
2*Z+Y#=<2*U+V+108,
2*U+V+5#=<2*Z+Y.
在这种情况下,这当然没有多大帮助。
要获得具体的解决方案,请使用labeling/2
。例如:
?- fC(U, V, X, Y, Z), Vs = [U,V,X,Y,Z], Vs ins 0..sup, label(Vs).
约束Vs ins 0..sup
表明所有变量都是非负数。在SICStus Prolog中,使用domain(Vs, 0, sup)
。
示例解决方案:
U = V, V = X, X = Y, Y = 0, Vs = [0, 0, 0, 0, 54], Z = 54 ; U = V, V = X, X = 0, Vs = [0, 0, 0, 1, 53], Y = 1, Z = 53 ; etc.
对于理性数字的约束,请查看clpq约束和library(clpq)
。
答案 1 :(得分:0)
'低技术'替代......但实际上,使用库(clpfd)
?- maplist(between(0,54),[U,V,X,Y,Z]),fC(U,V,X,Y,Z).
U = V, V = X, X = Y, Y = 0,
Z = 54 ;
U = V, V = X, X = 0,
Y = 1,
Z = 53 ;
U = V, V = X, X = 0,
Y = 2,
Z = 52 ;
...