繁体   English   中英

CLP(FD) 可变域和传播

[英]CLP(FD) variable domains & propagation

在上学期的 Prolog 课程中,我在引入 CLP 时落后了一点。 现在我正在努力追赶,并尝试了教授提供给所有学生的过去考试。

特别是,有这样一个问题:

以下查询后,CLP(FD) 中决策变量 Z 的域是什么:

?- X in 1..7, Y in -3..100, Y #> X, Z #\\= 0, Z #= Y - X.

在我看来答案应该是

Z in 1..99

但是当我在 SWI-Prolog 安装中运行它进行仔细检查时,我得到了

Z in -5.. -1\/1..99

这似乎是基于对X & Y的最大值和最小值的简单比较,而不考虑链接它们的约束( Y #> X )。

我意识到必须在此处对可行性做出让步,并且返回的域有时会比它们应有的限制更少,但我很惊讶地看到它在这样一个简单的例子中失败了。

我的问题

  1. 我认为这与 CLP 如何选择在内部传播(或不传播)各种约束有关,但我不明白它是如何做到的 - 这对我来说都是一个黑匣子。 CLP 如何准确地(或近似地失败)传播其约束?
  2. 没有办法让 CLP(FD) 适当地应用约束,也许是通过重新排序? 我已经尝试在最后添加一个额外的Y #> X ,但这并没有改变任何变量域。

在我看来答案应该是

Z in 1..99

你怎么能确定你是对的? 这是约束的一个很好的属性:您可以最轻松地验证这一点:

?- X in 1..7, Y in -3..100, Y #> X, Z #\= 0, Z #= Y -X.
X in 1..7,
Z+X#=Y,
X#=<Y+ -1,
Z in -5.. -1\/1..99,
Y in 2..100.

?- X in 1..7, Y in -3..100, Y #> X, Z #\= 0, Z #= Y -X, Z #< 0.
false.

好的,现在我相信你说的了。

所以,你在这里发现的不一致是在SICStus'本土也存在library(clpfd)以及library(clpz) 首先请注意,给出的答案没有错误! 它说:是的, X in 1..7, Z+X#=Y, X#=<Y+ -1, Z in -5.. -1\\/1..99, Y in 2..100.提供了X in 1..7, Z+X#=Y, X#=<Y+ -1, Z in -5.. -1\\/1..99, Y in 2..100. 是真的。 嘿,这不是真的。

所以这个答案有点像许多保险合同中的法律术语,他们说,是的,我们将支付,前提是所有这些微小的无法阅读的印刷品都保留了下来,但实际上,您可以用一个巨大的false代替那堵缩微文本墙。

通常,这种不一致是不可避免的,因为在上述系统中定义的 CLP(FD)/CLP(Z) 允许制定无法确定的问题。 因此,无论您的约束求解器如何进化,我们都可以保证总会有我们无法解决的情况。 这是一个科学的数学定律,比重力或速度限制等经验定律可靠得多。

这里的不一致实际上是一种工程权衡。 只要没有人抱怨并且没有令人信服的用例,此类系统的开发人员就不会看到改进的理由。 毕竟,这样的改进可能会减慢现有用例的速度。

  1. CLP 如何准确地(或近似地失败)传播其约束?

实际上,对于任何实际大小的问题,没有人知道。 但这也不是必须的。 在 CLP(FD) 的情况下,基本元素是附加到逻辑变量的域。 您将它们视为(in)/2个目标,例如Z in -5.. -1\\/1..99 它们之间连接的是实际的约束。 在你的情况下Y #> XZ #= YX 这些约束现在只看到变量的域并尝试保持它们之间的一致性。 作为更粗略的近似,域被视为区间,因此Z in -5 .. 99而不是上面。 (他们中的大多数)没有看到的是其他约束。 在这种情况下, Y #> XZ #= YX之间没有直接联系。 因此不一致。 这种有限的一致性检查更容易实现,而且速度也非常快,并且通常优于更完整的算法。 随着更好算法的发现,事情也在发展。 一个很好的例子是all_distinct/1 ,它使用 Regin 算法保持所有变量之间的一致性,而all_different/1只保持每对变量之间的一致性。 但无论如何:这些事情不断发展,这是一道考试题,这有点令人惊讶。

  1. 有什么方法可以让 CLP(FD) 适当地应用约束......?
?- X in 1..7, Y in -3..100, Y #> X, Z #\= 0, Z #= Y -X, clpfd:contracting([X,Y,Z]).
X in 1..7,
Z+X#=Y,
X#=<Y+ -1,
Z in 1..99,
Y in 2..100.

但大多数人会忽略这个问题,只添加labeling([],[X,Y])

  1. Z的域是什么?

这是一个模棱两可的问题。 给出两者作为答案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM