考察
投資効率の良いものの選定
全体重量合計がある中で電源の最大を求める、最適化の話。
電源容量/重量をそれぞれ算出して
絶妙なバランスを人間が選択して・・・となるが
見逃す最適解があるかもしれない
コードで解決
pulpライブラリを使って数理最適化問題として対処する。
解決問題定義
# 問題定義
prob = pulp.LpProblem('モバイルバッテリ選択最適化', sense=pulp.LpMaximize)
# モバイルバッテリ定義
## ラベル
goods = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
## 重さ
weight = [150, 170, 180, 200, 200, 240, 250]
## 出力
power = [3000, 4000, 5000, 7000, 8000, 8000, 9000]
# 変数定義
## 0 or 1の選択になるので変数カテゴリは Binary で定義する
## fstring使っています
xs = [pulp.LpVariable(f'{x}', cat='Binary') for x in goods]
# 目的関数定義 a*3000 + b*4000 + .... + g*9000:これを最大化する
prob.setObjective(pulp.lpDot(power, xs))
# 制約定義
## 合計 1kg以下(1000g)
prob += pulp.lpDot(weight, xs) <= 1000
print(prob)
計算します。計算過程のログも出します(わからない・・けど、何かしら試行錯誤している様子あり)
選択するa〜gの組み合わせと
その結果が表示されます。
# status = prob.solve(pulp.PULP_CBC_CMD(msg=0)) # ログなし
# ログ出力、4スレッドで実施
# status = prob.solve(pulp.PULP_CBC_CMD(msg=1)) # ログあり
# ログ出力、4スレッドで実施
status = prob.solve(pulp.PULP_CBC_CMD(msg=1, threads=4))
print("Status", pulp.LpStatus[status])
print(xs)
print([x.value() for x in xs])
print(prob.objective.value())
これだけだとわかりにくいので
条件、結果、効率をまとめます。
df = pd.DataFrame({
'製品': xs,
'選択': [int(_.value()) for _ in xs],
'電源容量': power,
'重量': weight,
'効率': [np.round(p/w, decimals=2) for p, w in zip(power, weight)],
}).T
df
なんとなくですが
- 効率の良いものから、半分よりちょっと少ない分を採択
- 一旦固定
- ここから調整
がいい感じの試行錯誤ステップになっているような、そうでないような。
今回:7つ → 7/2を切り捨てて3
効率の良い順から3つを採択、あとは試行錯誤。