リソース配分
🔥 Vibe プロンプト
「10件の注文(利益、工数、期限)から選択。週100時間の制限内で利益を最大化。」
リソース配分とは?
リソース配分は、限られたリソース(時間、資金、人材)の中でどのプロジェクトや注文を受諾するかを選択する問題です。
| シナリオ | リソース | 決定 | |---------|---------|------| | 🏭 工場 | 機械時間 | どの注文を受けるか | | 💻 ソフトウェア | 開発者時間 | どの機能を作るか | | 🏗️ 建設 | 人員時間 | どの案件に入札するか |
PuLPによる実装
import pulp
# 注文データ
orders = [
{"id": "A", "profit": 500, "hours": 40, "deadline": 5},
{"id": "B", "profit": 300, "hours": 25, "deadline": 3},
{"id": "C", "profit": 800, "hours": 60, "deadline": 7},
{"id": "D", "profit": 200, "hours": 15, "deadline": 2},
{"id": "E", "profit": 650, "hours": 50, "deadline": 4},
{"id": "F", "profit": 450, "hours": 35, "deadline": 6},
]
prob = pulp.LpProblem("注文選択", pulp.LpMaximize)
# 決定変数: x[order_id] = 1 if accepted
x = {o["id"]: pulp.LpVariable(f"x_{o['id']}", cat="Binary") for o in orders}
# 目的: 総利益最大化
prob += pulp.lpSum(o["profit"] * x[o["id"]] for o in orders)
# 制約: 週間容量(各週最大100時間)
max_hours = 100
num_weeks = max(o["deadline"] for o in orders)
for week in range(num_weeks):
week_orders = [o for o in orders if o["deadline"] >= week + 1]
prob += pulp.lpSum(o["hours"] * x[o["id"]] for o in week_orders) <= max_hours
# 求解
prob.solve(pulp.PULP_CBC_CMD(msg=False))
# 結果
if pulp.LpStatus[prob.status] == "Optimal":
print(f"\n{'='*50}")
print(f"注文選択 — 最適解")
print(f"{'='*50}")
selected = [o for o in orders if x[o["id"]].value() == 1]
total_profit = sum(o["profit"] for o in selected)
total_hours = sum(o["hours"] for o in selected)
print(f"選択注文 ({len(selected)}/{len(orders)}):")
for o in selected:
print(f" ✅ {o['id']}: 利益${o['profit']}, 工数{o['hours']}h, 期限{o['deadline']}週")
print(f"\n総利益: ${total_profit}")
print(f"総工数: {total_hours}h")
# 週間容量確認
print(f"\n週間容量確認:")
for week in range(num_weeks):
wh = sum(o["hours"] for o in selected if o["deadline"] >= week + 1)
mark = "✅" if wh <= max_hours else "❌"
print(f" 第{week+1}週: {wh}/{max_hours}h {mark}")
拡張制約
# 依存関係: BにはAが必要
prob += x["B"] <= x["A"]
# 最低/最高受注数
prob += pulp.lpSum(x.values()) >= 2 # 最低2件
prob += pulp.lpSum(x.values()) <= 4 # 最高4件
# 優先度重み付け
priority = {"A": 1.0, "B": 0.8, "C": 1.5, "D": 0.5, "E": 1.2, "F": 0.9}
# 重み付き利益を最大化
prob += pulp.lpSum(o["profit"] * priority[o["id"]] * x[o["id"]] for o in orders)
まとめ
| 項目 | 詳細 | |------|------| | 問題 | リソース制約下で注文を選択 | | 変数 | バイナリ: 各注文を受諾するか | | 制約 | 週間容量、依存関係、上限/下限 | | 目的 | 総利益最大化 | | ソルバー | CBC (PuLP) | | 応用 | 工場、IT、クラウド、コンサルティング |