prolog - 在 clpfd 中制定二次方程

标签 prolog quadratic clpfd

CLPFD 系统的主要目标不是有效地处理二次方程,但是,是否有更好的方法来制定如下问题?

似乎问题归结为如下等式。 SWI 与 library(clpfd)给:

?- 时间( ((L+7)^2#=L^2+189, L in 0..10000000) )。
% 252,169,718 推理,87445.038 秒内 87208.554 CPU(100% CPU,2892 唇)
错误:超出本地堆栈

但现在the latest version in SWI

?- 时间( ((L+7)^2#=L^2+189, L in 0..10000000) )。
% 3,805,545,940 推理,868.635 CPU 在 870.311 秒内(100% CPU,4381063 唇)
L = 10。

在 SICStus 4.3beta7 中,我得到:

| ?- 统计(运行时,_)。
是的
| ?- (L+7)*(L+7)#=L*L+189,L 在 0..10000000 中。
L = 10 ? ;

| ?- 统计(运行时,[_,T_ms])。
T_ms = 2550 ? ;

最佳答案

为了快速解决这个问题,已经有一个原始 X #= Y^2 约束的约束求解器也可能实现以下规则:

规则1:

X #= (Y+C)^2 --> H #= Y^2, X #= H + 2*C*Y + C^2
% where C is an integer and X,Y variables

规则#2:
X #= Z^2, Y #= Z^2 --> X #= Z^2, X #= Y.
% where X,Y,Z are variables

上述规则将方程简化为线性方程,它无论如何都可以由一个体面的 CLP(FD) 系统直接求解。在这里您可以看到有和没有规则 #2 的系统之间的区别:

没有规则#2:
?- (L+7)*(L+7) #= L*L+189, stored.
_C #= 140+_B-14*L.
_B #>= 0.
_C #>= 0.
_B #= L*L.
_C #= L*L.
Yes

使用规则#2:
?- (L+7)*(L+7) #= L*L+189, stored.
L = 10
?- statistics(time, S), (L+7)*(L+7) #= L*L+189, statistics(time, T), U is T-S.
U = 3

但是规则#2 对我来说有点特别。还不确定是否应该保留它。

再见

关于prolog - 在 clpfd 中制定二次方程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22642239/

相关文章:

prolog - Prolog递归过程解释

PROLOG 全不同

javascript - 找到位于二次曲线上的两点之间的控制点

prolog - 在序言中定义多个规则的最短方法

prolog - 是否有任何项目是从 Prolog 原型(prototype)开始的

prolog - 处理序言上下文无关语法

javascript - 二次贝塞尔曲线 : Calculate x for any given y

Python:使用 CVXOPT 进行二次规划

recursion - Prolog递归程序不返回值

prolog - 忽略序言中的类型错误并返回 false