【发布时间】:2014-08-10 10:11:21
【问题描述】:
在这里,我建议以defined here 为 Smullyan 的数值机找到解决方案。
问题陈述
它们是一种将数字列表作为输入的机器,并根据输入的模式遵循一些规则将其转换为另一个数字列表。 这是上面链接中给出的机器规则,表达得更正式一些。 假设 M 是机器,M(X) 是 X 的变换。 我们定义了一些这样的规则:
M(2X) = X
M(3X) = M(X)2M(X)
M(4X) = reverse(M(X)) // reverse the order of the list.
M(5X) = M(X)M(X)
并且任何不符合任何规则的东西都会被拒绝。 以下是几个例子:
- M(245) = 45
- M(3245) = M(245)2M(245) = 45245
- M(43245) = 反向(M(3245)) = 反向(45245) = 54254
- M(543245) = M(43245)M(43245) = 5425454254
问题是,找到这样的 X:
- M(X) = 2
- M(X) = X
- M(X) = X2X
- M(X) = 反向(X)
- M(X) = 反向(X2X)反向(X2X)
这是第二个示例,它使用详尽的搜索更加复杂(尤其是如果我想要前 10 或 100 个解决方案)。
M(1X2) = X
M(3X) = M(X)M(X)
M(4X) = reverse(M(X))
M(5X) = truncate(M(X)) // remove the first element of the list truncate(1234) = 234. Only valid if M(X) has at least 2 elements.
M(6X) = 1M(X)
M(7X) = 2M(X)
问题:
- M(X) = XX
- M(X) = X
- M(X) = 反向(X)
(非)解决方案
在 Prolog 中编写求解器非常简单。除了这只是详尽的探索(a.k.a brute force)并且可能需要一些时间来制定一些规则。
我试过但无法用 CLP(FD) 的逻辑约束来表达这个问题,所以我尝试用 CHR(约束处理规则)来用列表的约束(尤其是 append 约束)来表达这个问题,但是无论我如何表达,它总是归结为详尽的搜索。
问题
知道我可以采取什么方法在合理的时间内解决任何此类问题吗? 理想情况下,我希望能够生成比某个界限更短的所有解决方案。
【问题讨论】:
-
我已经实现了简单的 Prolog 解决方案,它可以立即为您的所有问题提供答案。有哪些需要花费大量时间的问题示例?
-
我认为 Prolog 可以很好地解决这类问题 - 它是关系型的。我看不出 CLP(FD) 如何在这里加快速度。
-
这是关于数字还是数字列表?该链接建议数字。取 4200。链接回答 00 而不是 0
-
@SergeyDymchenko 您的 Prolog 代码是否也解决了相反的问题,例如哪个序列产生 2?
-
@hakank 是的。
length(X, _), m(X, [2]).: 'X = [2,2] ?; X = [3,2] ?;'等等。
标签: prolog constraint-programming