我将平衡代表产品需求和可用性的两个向量。
这是材料需求计划中的一个典型问题,非常容易以命令式进行。函数编程中可能吗?
我必须以下列优先级从A1传递到A2:首先为具有相同:cat的记录分配aval qty,然后在:day早期分配给需求。
:day的格式为AAAAMMDD
(def A1
{:avail [{:day 20190101 :qty 10 :mkey "AAABB" :cat "CO1"}
{:day 20190101 :qty 20 :mkey "OS100" :cat "CO1"}
{:day 20190102 :qty 50 :mkey "OS200" :cat " "}
{:day 20190103 :qty 50 :mkey "OS300" :cat " "}
{:day 20190104 :qty 40 :mkey "OS400" :cat " "}]
:needs [{:day 20190107 :qty -100 :mkey "OS200" :cat " "}
{:day 20190108 :qty -50 :mkey "OS300" :cat " "}
{:day 20190109 :qty -100 :mkey "OS400" :cat " "}
{:day 20190217 :qty -100 :mkey "OS100" :cat "CO1"}]})
(def A2
{:avail [{:day 20190101 :qty 0 :mkey "AAABB" :cat "CO1"}
{:day 20190101 :qty 0 :mkey "OS100" :cat "CO1"}
{:day 20190102 :qty 0 :mkey "OS200" :cat " "}
{:day 20190103 :qty 0 :mkey "OS300" :cat " "}
{:day 20190104 :qty 0 :mkey "OS400" :cat " "}]
:needs [{:day 20190107 :qty 0 :mkey "OS200" :cat " "}
{:day 20190108 :qty -10 :mkey "OS300" :cat " "}
{:day 20190109 :qty -100 :mkey "OS400" :cat " "}
{:day 20190217 :qty -70 :mkey "OS100" :cat "CO1"}]})
从A1获取A2的可能的Java算法
ArrayList avail = new ArrayList();
ArrayList needs = new ArrayList();
/* first assign based on same :cat */
for (int i=0;i< needs.size();i++) {
// get needs record of index i..
for (int j=0;j< avail.size();j++) {
// get avail record of index j..
if (need.cat != avail.cat) // only same same cat !
continue;
balance the actuals records needs and avail
updating relative qty,
trying to set need qty to zero decrementing avail
}
}
/* now again without test on cat */
for (int i=0;i< needs.size();i++) {
// get needs record of index i..
for (int j=0;j< avail.size();j++) {
// get avail record of index j..
balance the actuals records needs and avail
updating relative qty
trying to set need qty to zero decrementing avail
}
}
答案 0 :(得分:0)
我将通过两个功能来做到这一点:
(defn consume
"Reduce demands base on one supply"
[can-consume? demands supply]
(reduce (fn [{:keys [supply] :as ans} d]
(let [qty (:qty supply)]
(if (can-consume? d supply)
(let [used (-> d :qty (+ qty))]
(-> ans
(update :needs conj (assoc d :qty (min 0 used)))
(assoc-in [:supply :qty] (max 0 used))))
(update ans :needs conj d))))
;; initial state - no demands just one supply
{:needs []
:supply supply}
;; feed demands into reducing function
demands))
(defn consume-all
"Reduce demands with a list of supplies"
[{:keys [needs avails]}]
(->> (reduce (fn [ans s]
(let [{:keys [supply needs]
:as same-cat} (consume (fn [d s] (and (<= (:day s) (:day d))
(= (:cat s) (:cat d))))
(:needs ans)
s)
{:keys [supply needs]} (if supply ;; supply of same cat is consumed
same-cat
(consume (fn [d s] (<= (:day s) (:day d)))
(:needs ans)
s))]
(-> ans
(assoc :needs needs)
(update :avails conj supply))))
;; initial state - no supply only demands
{:needs needs
:avails []}
;; feed supplies into reducing function
avails)))
运行样品
(consume-all {:needs [{:day 20190107 :qty -100 :mkey "OS200" :cat " "}
{:day 20190108 :qty -50 :mkey "OS300" :cat " "}
{:day 20190109 :qty -100 :mkey "OS400" :cat " "}
{:day 20190217 :qty -100 :mkey "OS100" :cat "CO1"}]
:avails [{:day 20190101 :qty 10 :mkey "AAABB" :cat "CO1"}
{:day 20190101 :qty 20 :mkey "OS100" :cat "CO1"}
{:day 20190102 :qty 50 :mkey "OS200" :cat " "}
{:day 20190103 :qty 50 :mkey "OS300" :cat " "}
{:day 20190104 :qty 40 :mkey "OS400" :cat " "}]})
==>
{:needs
[{:day 20190107, :qty 0, :mkey "OS200", :cat " "}
{:day 20190108, :qty -10, :mkey "OS300", :cat " "}
{:day 20190109, :qty -100, :mkey "OS400", :cat " "}
{:day 20190217, :qty -70, :mkey "OS100", :cat "CO1"}],
:avails
[{:day 20190101, :qty 0, :mkey "AAABB", :cat "CO1"}
{:day 20190101, :qty 0, :mkey "OS100", :cat "CO1"}
{:day 20190102, :qty 0, :mkey "OS200", :cat " "}
{:day 20190103, :qty 0, :mkey "OS300", :cat " "}
{:day 20190104, :qty 0, :mkey "OS400", :cat " "}]}