有没有办法向求解器提供提示,关于哪些路径更好?



有没有办法在求解过程中更喜欢某些路径而不是其他路径?这确实是一个性能问题。当我将所有逻辑放在一起时,它会生成 1000 个解决方案,这需要成倍增加的时间。 这些确实都是有效的解决方案,所以我可以做一些类似(run 1 …)而不是(run* …)的事情,但这给了我一个任意的解决方案。 我想做的是能够提供一些关于哪些路径更好的提示。

我知道,我可以通过使用自定义比较器对它们进行排序来获得一个最佳答案,但这无助于解决性能问题。

下面是一个简化的、人为的示例:

(require
'[clojure.core.logic :refer :all]
'[clojure.core.logic.fd :as fd]))
(defn multipleo
[multiple value domain]
(fresh [n]
(fd/in multiple domain)
(fd/in n (fd/interval 1 10))
(fd/* n multiple value)))
(run* [q]
(multipleo q 60 (fd/domain 30 24 15 12)))
=> (12 15 30)

12、15 和 30 都是有效的解决方案,但我想要的是最大的(-> *1 sort last),但我想再次使用求解器来做,这样(run 1 [q] (multipleo q 60 (fd/domain 30 24 15 12)))理想情况下会产生(30)

根据@amlloy的建议,我可以尝试一下:

(defn multipleo
[multiple value]
(fresh [n]
(conde
[(== multiple 6)]
[(== multiple 3)])
(fd/in n (fd/interval 1 10))
(fd/* n multiple value)))
(run* [q] (multipleo q 12))
=> (6 3)

这似乎有效。 据我所知,在 fd/in 中对域进行排序没有任何影响。 但是,如果我按照我喜欢的顺序移动域条目 intpconde,那就行了。 如果没有conde上面的代码将生成(3 6)。 但是,这比 fd/in 方法慢得多。 我想 fd/in 与 conde 相比,做一些不错的性能技巧。

我也尝试了condu,但这并没有像我预期的那样工作。

(defn multipleo
[multiple value]
(fresh [n]
(condu
[(== multiple 6)]
[(== multiple 3)])
(fd/in n (fd/interval 1 10))
(fd/* n multiple value)))
(run* [q] (multipleo q 3))
=> ()

我本以为第一个condu组会失败,因为在这个例子中,整体逻辑不能在 multiple=6 的情况下成功。 谁能帮助我理解为什么这不能像我预期的那样工作?

相关内容

  • 没有找到相关文章

最新更新