見出し画像

生産配分(出荷計画)をナップサック問題に置き換えて解いてみる

 ここでは、前回の記事「グローバルSCMにおける生産配分・出荷計画の最適化(ナップサック問題)について」でご紹介した生産配分の最適化をナップサック問題に置き換えて解くpython処理の詳細をご紹介します。

 生産配分(出荷計画)をナップサック問題で解いた時の処理イメージは、「図1.  マザープラントにおける生産配分(出荷優先)」のとおりです。

図1. マザープラントにおける生産配分(出荷優先)

 ナップサック問題(Knapsack problem)とは、「いくつかの種類の品物( 品目番号 i、価値 Vi、重量 Wi )が与えられたとき、重量の合計が W を超えない範囲で品物のいくつかをナップサックに入れて、その入れた品物の価値の合計を最大化するためには、入れる品物の組み合わせをどのように選べばよいか」という問題です。

 ナップサック問題を解くknapsack_solverの入出力処理のイメージは、「図2. Knapsack solverによる生産配分(出荷優先)」の右上のグレー枠の部分に示すとおりです。

図2. Knapsack solverによる生産配分(出荷優先)

ここで入力として、「ナップサックの重量制約」と「詰め込む品目のリスト」を与えると、knapsack_solverモジュールの中で線形計画法のライブラリ(PULP)がナップサック問題を解きます。
出力として、「価値を最大化する品目の組合せ」を生成します。

【入力データ】
● weight_limit ナップサックの重量上限: W
● items_number 詰め込む品物のリスト: [品目連番: i , 価値Vi, 重量Wi ]

【ナップサック問題の処理】
● 線形計画ライブラリ(PULP)で価値を最大にする品目の組合せを計算する
solved_items = knapsack_solver(weight_limit, items_number)

【出力データ】
● 価値を最大化する品目の組合せ: solved_itemsリスト
0/1をOFF/ONとして、リスト中の1がある
「要素の位置」が選択された「品目番号」になります。
例えば、品目リストの選定結果は、
solved_items [0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0]
のようになります。

【データ変換】
ナップサック問題の前後の処理として、サプライチェーン上の発注オーダーに相当する、仕向地node(Arv_entiry)と着荷週(Arv_week)のペア・リスト[ Arv_entiry, Arv_week ]を、ナップサック問題の「品目」に対応させています。

「図2. Knapsack solverによる生産配分(出荷優先)」は、knapsack_solverの前後の処理を含めた全体の処理フローを示します。
処理ステップの詳細は以下のとおりです。

①生産配分問題とナップサック問題との間で「品目の粒度」を整合させて品目データの変換用の辞書を作成する。

➁マザープラント出荷週毎に、出荷要求オーダー情報から「品目辞書」を使って、品目リスト(items_number)を生成する。

➂Knapsachk_solverにより、価値を最大化する「品目の組合せ」を生成する。

④後処理として、価値を最大化する「組合せ」をその出荷週の確定オーダーとして変換・生成する。

⑤未確定の出荷オーダー(当週の出荷から漏れたオーダー)は、次の出荷候補として「繰り越し」される。

以上の処理は、マザープラントの出荷週の上での1週分の処理に相当します。ここでは、一年間の出荷計画を確定させるために、第52週から第51,50,49,48,,,と順に第1週まで、時間を戻る方向に出荷オーダーを確定していきます。
もし、市場からの需要に対して生産供給能力が不足している場合には、先行生産が必要になるので、マイナス週(当年0週は前年の53週、当年の-1週は前年52週という)からの生産出荷スタートになり、年を跨る出荷計画を作成します。


 生産配分問題とナップサック問題の対応を整理すると、「表1. ナップサック問題と生産配分問題の対比」のようになります。

表1. ナップサック問題と生産配分問題の対比

【サプライチェーン上の発注オーダーの価値】

 ナップサック問題で生産配分(出荷計画)を解く上で、ポイントになるのは、サプライチェーン上の各拠点nodeから発生した発注オーダー・出荷要求が持つ「価値」を、どのように算定すればよいのかという点にあると思います。
 幸い、以前の記事「PSI計画のコスト評価方法について」でご紹介したとおり、ここで扱っているサプライチェーン計画モデル中の各発注オーダーは、機械学習の機能を付加したPSI計画で発注オーダーを生成しており、機械学習の行動・評価・選択の処理を行う過程で、報酬Reward ( = 価値value = 利益金額profit ) を算定して持っています。この発注ロット別の利益profitを取り出して、ナップサック問題に渡すことで、サプライチェーン上での価値を最大化する生産配分(出荷計画)を生成することができます。

下記のnoteの記事を参照:
PSI計画のコスト評価方法について|Yasushi Ohsugi|note

 ただ、サプライチェーン上の各拠点nodeの単体の価値は算定されていますが、サプライチェーンの親子node間の需給連鎖を考慮した価値、言い換えると「マザープラントを出荷したオーダーが、最終市場に届くまでの価値の累計」を加算していく必要があります。そこで、「図3. サプライチェーン拠点nodeの価値算定方法(案)」に示すように、複数の子ノードの「年間発注総数」と「年間の価値平均」から価値の加重平均を取る方法を試案として、サプライチェーン上の価値を算定しました。

【最終市場(末端ノード: Leaf node)の場合】
最終市場(末端ノード: Leaf node)の場合は、子ノードは無いので、各拠点node自身の価値が、そのままサプライチェーン上の価値になります。

【域内拠点在庫(中間ノード)とマザープラント(Root node)の場合】
この場合、node自身の価値に、子ノードで発生する商品の価値を含めて、サプライチェーン上の拠点nodeの価値とします。
算定の手順は、以下のとおりです。

【域内拠点在庫・中間nodeの価値算定】
①中間node自身の価値を計算して置く
➁子ノードの年間発注総数と年間平均価値を計算して、リストに入れる
➂複数の子ノードの年間発注総数と年間価値平均をリスト形式の入力として、加重平均を算定する
④中間nodeの価値に、子ノードの加重平均値を加算して、サプライチェーン上の価値とする

図3. サプライチェーン拠点nodeの価値算定方法(案)

 少し余談になりますが、筆者の経験では、業種を限らずマザープラントの工場出荷時の価格は、末端市場の価格の約20%というコスト構成が、旧来の流通の仕組みでは、よくある事例ではないかと思います。
サプライチェーン上の各拠点node 毎の価値は、この残りの約80%の部分で価値を取り合っているという感覚です。
また、近年のネット直販の場合には、末端価格が半値になっていれば、工場出荷時の価格は末端価格の約40%というコスト構成が想定され、残りの約60%の部分で価値を取り合っている状況が想定されます。

 また、もし仮に、特定の海外市場向けの出荷ロットについて、供給元マザープラントの出荷時点での価値が高い状況 ( 例えば、工場出荷時点の利益率が25%~30%程度など、海外販社が高い価格で仕入れるとofferしてきた場合 ) であったとしても、該当の海外流通市場における商品価値が低い、利益が得られない市場環境 ( 例えば、自社商品のブランド力が十分に浸透していない市場セグメントなど ) であれば、出荷の優先度を検討する時点で、より価値の得られる(自社商品ブランドが認知されている )市場への供給を優先する、という経営判断が十分にあり得ます。
 このように、サプライチェーン上のend to endの価値は、グローバル供給方針の重要な判断材料になると思います。

 繰り返しになりますが、図3の価値valueの算定方法は、
①各拠点node毎、発注オーダー毎の価値value (利益)を算定する
②このvalueを使って、子ノードのvalueの加重平均を算定した後、親ノードのvalueに加算する
③上記の処理を子ノードから親ノードへ、マザープラントまで繰り返す
という考え方で、マザープラント側の出荷ポジションにおける各出荷オーダーのサプライチェーン上の価値として、Value on Supply Chainを算定することができます。

このValue on Supply Chainの算定処理は、knapsack_solver処理に入る前処理として、バッチ処理で事前に生成しています。
このバッチ処理のpythonコードは、以下のgithubのリンクに、PySI_V0R3_Demand_Plan020_value_on-SC.py
として、公開しています。

Yasushi-Osugi/PySI_V0R3_Demand_Plan020_value_on-SC: PySI_V0R3_Demand_Plan020_value_on SC calculates each "lot value", that is purchase order by order, from nodes on supply chain defined. (github.com)


 以上、生産配分の最適化をナップサック問題に置き換えて解くpython処理の詳細について、ご紹介させていただきました。

 次回は、実務の立場からは、供給元のマザープラントで出荷確定したオーダーを起点に、Supply Planとして、サプライチェーン上を供給元から末端市場に向かって商品が流れる様子を、在庫の変化、経営の評価指標の変化などで、サプライチェーンを可視化して見ていきたいと思います。
 pythonの実装の立場からは、サプライチェーン上でグローバル供給拠点から各国販社、販売チャネルに向かって商品が流れるsupply planingの計画処理の実装とdataframe管理、サプライチェーン全体を俯瞰できる可視化ライブラリーの応用について検討していきたいと思います。

追記:PSI計画の初期処理について、ご紹介の順番が逆になってしまいましたが、サプライチェーン上を最終消費地からマザープラント側へ、需要情報を順番に生成するdemand_planのpythonコードをご紹介します。
以前の記事で紹介したPSI計画のpythonのデータ入出力をpandas DataframeでI/Oするように修正しています。
下記のgithubリンクに、PySI_V0R3_demand_plan010_on_SC.pyとして公開しています。
ただ、PSI計画のバッチ処理のみなので、このコードだけではPSI計画の結果を判断するのは難しいです。
別途、PSIグラフ表示(いくつか試作しているのですが)するdashboard的なもの、Supply Chain Planning dashboardを作ってみたいと思ってます。

Yasushi-Osugi/PySI_V0R3_demand_plan010_on_SC: PySI_V0R3_demand_plan_on_SC makes "mother plant shipping position" from supply chain end-market (=leaf-node) demand forecast. with using P-S-I calculating from children nodes to parent node, that is opostordering process , demand of all supply chain node is generated (github.com)


2022年12月 自宅にて 

この記事が気に入ったらサポートをしてみませんか?