clojure - 有没有办法向求解器提供关于哪些路径更好的提示?
问题描述
有没有办法在解决过程中更喜欢某些路径而不是其他路径?这确实是一个性能问题。当我将所有逻辑放在一起时,它会生成 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 中对域进行排序没有影响。conde
但是,如果我按照我喜欢的顺序移动域条目 intp a ,那就可以了。没有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
组会失败,因为在这个例子中,整体逻辑不能成功 w/multiple=6。谁能帮我理解为什么这不能按我的预期工作?
推荐阅读
- arm - 使用 openocd 显示 Cortex-M4 SWO 日志
- assembly - 从文本文件中打印字符串的代码
- api - 如何在进程环境块中触发“BeingDebugged”字段
- php - PhpStorm 找不到使用魔术方法的声明
- angular - 打字稿标识符名称不能以数字开头
- c# - Xamarin IOS - 类没有默认的无参数构造函数
- xampp - 如何将 localhost 和 php 脚本中的数据库移动到在线
- android - 如何实现 viewModel 和 Live 数据?
- reactjs - 如何使用音量按钮博览会捕获图片
- android - 如何使用自定义按钮拍照