mac*_*mac 6 optimization clojure constraint-programming
我正在尝试使用loco进行优化的基本示例.
我有一个成本向量,其索引对应于多个时隙的整数值,并希望最小化时隙的不同子集的成本之和.
请参阅下面的我的尝试,但由于所选插槽与成本之间没有"链接",因此无效.
(def costs [10 10 20 20 30 30 40 40 10 10])
(let [slot-vars (for [i (range 5)] ($in [:slot i] 1 10))
cost-vars (for [i (range 10)] ($in [:cost i] 10 40))]
(solution
(concat
slot-vars
cost-vars
[($distinct (for [i (range 5)] [:slot i]))]
(for [i (range 5)]
($= [:cost i] (get costs i))))
:minimize (apply $+ (for [i (range 5)] [:slot i]))))
Run Code Online (Sandbox Code Playgroud)
小智 2
首先,我不完全确定我理解这个问题的要点,因为显然解决方案是只取列表中的 5 个最小值。但如果你想让机车做到这一点,我同意背包约束是一个方便的工具。与迈克在评论中所说的相反,我认为使用背包进行最小化没有任何障碍。令权重全部为 1,并强制权重之和为 5,以便从 10 个插槽中选择 5 个。我使用该变量[:include i]来指示插槽 i 是否应包含在子集中(1 表示 true,0 表示 false)。我们希望最小化 :include 变量向量和成本向量的点积。
(def costs [10 10 20 20 30 30 40 40 10 10])
(def weights (repeat 10 1))
(def include-vars (for [i (range 10)] [:include i]))
(def include-constraints (for [i (range 10)] ($in [:include i] 0 1)))
(def model
(concat
include-constraints
[($knapsack weights costs include-vars 5 :total)
($in :total 0 (apply + costs))]))
(solution model :minimize :total)
Run Code Online (Sandbox Code Playgroud)
结果是:
{[:include 4] 0, [:include 6] 0, [:include 9] 1, [:include 1] 1, [:include 3] 0, [:include 8] 1, :total 60, [:include 0] 1, [:include 7] 0, [:include 2] 1, [:include 5] 0}
Run Code Online (Sandbox Code Playgroud)