带约束的 Prolog 组合

标签 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 的列表,找到所有组合,然后检查它们以检查我的“约束”,我很快就耗尽了内存,所以我一定是做错了什么。

亲切的问候,

耶勒

最佳答案

对于整数,使用 很容易限制。例如,在 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, super)

示例解决方案:

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)

关于带约束的 Prolog 组合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33668753/

相关文章:

在组间匹配集之前优先考虑组内匹配集的算法

unit-testing - GNU Prolog 中的单元测试

prolog - Prolog 中的 Hello world

prolog - 在 Prolog 中解决七巧板谜题的好方法是什么?

prolog - 你能在纯序言中写 between/3 吗?

python - 来自迭代器的随机项目?

prolog - SWI-Prolog 选项处理

C 中的 Char 置换算法,将输出存储在数组中

c++ - 组合算法

python-3.x - (Python)查找受分区大小限制限制的列表列表的所有可能分区