具有约束的Prolog组合

时间:2015-11-12 10:01:32

标签: prolog combinations

我正在寻找一种方法,在给定一组约束的情况下找到所有可能的解决方案。我在学校有过序幕,但已经有一段时间了,所以考虑一下我相当新。我想要实现的是这样的:

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;,我很快耗尽了内存,所以我一定做错了。

亲切的问候,

耶勒

2 个答案:

答案 0 :(得分:2)

对于整数,约束很容易。例如,在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.

对于理性数字的约束,请查看约束和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 ;
...