ILP基礎とPuLP

🔥 Vibe プロンプト

「2つの製品を生産。原料と労働時間に制限あり。利益を最大化。」

整数線形計画法(ILP)とは?

ILP は線形計画法(LP)を拡張し、変数の一部または全部が整数値であることを要求します。現実の意思決定(0.7個の工場を建てる、0.5人雇う)に最適です。

| 構成要素 | 説明 | 例 | |---------|------|------| | 決定変数 | 制御できるもの | A製品の生産量(整数) | | 目的関数 | 最適化するもの | 利益を最大化 | | 制約条件 | 制限事項 | 原料≤100kg、労働時間≤80h | | 整数制約 | 整数値のみ | 生産量は整数(端数不可) |

LP vs ILP

| 項目 | LP | ILP | |------|-----|------| | 変数 | 連続値(0.5可) | 整数値(0,1,2…) | | 難易度 | 易(多項式時間) | 難(NP困難) | | 解法 | シンプレックス法 | 分枝限定法 | | 用途 | 配合、資源配分 | スケジューリング、配置 |

PuLPによる実装

import pulp

prob = pulp.LpProblem("工場生産計画", pulp.LpMaximize)

# 決定変数(整数 = 端数不可)
ProductA = pulp.LpVariable("製品A", lowBound=0, cat="Integer")
ProductB = pulp.LpVariable("製品B", lowBound=0, cat="Integer")

# 目的関数: 総利益を最大化
prob += 40 * ProductA + 30 * ProductB, "総利益"

# 制約条件
prob += 2 * ProductA + 1 * ProductB <= 100, "原料制約"
prob += 1 * ProductA + 2 * ProductB <= 80, "労働時間制約"

# 求解
prob.solve()

# 結果
print(f"\n{'='*45}")
print(f"求解状態: {pulp.LpStatus[prob.status]}")
print(f"{'='*45}")
print(f"製品A: {int(pulp.value(ProductA))} 個")
print(f"製品B: {int(pulp.value(ProductB))} 個")
print(f"総利益: ${pulp.value(prob.objective)}")

# 制約確認
print(f"\n制約確認:")
print(f"  原料: 2×{int(pulp.value(ProductA))}+1×{int(pulp.value(ProductB))} = {2*int(pulp.value(ProductA))+int(pulp.value(ProductB))} ≤ 100 ✅")
print(f"  労働: 1×{int(pulp.value(ProductA))}+2×{int(pulp.value(ProductB))} = {int(pulp.value(ProductA))+2*int(pulp.value(ProductB))} ≤ 80 ✅")

応用

| 産業 | 用途 | 変数タイプ | |------|------|----------| | 製造 | 製品ミックス最適化 | 整数(ロットサイズ) | | 物流 | 配送ルート計画 | バイナリ(行く/行かない) | | 金融 | ポートフォリオ選択 | バイナリ(選ぶ/選ばない) | | 小売 | 在庫発注最適化 | 整数(発注数) |

まとめ

| 概念 | 要点 | |------|------| | LP | 連続変数、多項式時間 | | ILP | 整数変数、NP困難、分枝限定法 | | PuLP | PythonのLP/ILPモデリングライブラリ | | CBC | デフォルトのオープンソースソルバー | | 変数タイプ | Continuous, Integer, Binary

まとめ

  • ILP は線形計画法に整数制約を加えたもの
  • 分枝限定法 が ILP の主要な解法
  • PuLP は Python で ILP を解くためのライブラリ
  • 実際の問題では、問題の規模が大きくなると求解時間が急増する

よくある問題と解決策

| 問題 | 原因 | 解決方法 | |------|------|---------| | 期待通りの結果が出ない | パラメータ設定ミス | デフォルト値と境界条件を確認 | | 実行が遅い | アルゴリズムの効率 | より効率的なデータ構造を使用 | | メモリ不足 | データ量過多 | バッチ処理を検討 | | デバッグが困難 | ログ不足 | 詳細なログ出力を追加 |

さらに学ぶには

  • 公式ドキュメントを読む
  • GitHubのオープンソース例を参照
  • コミュニティディスカッションに参加
  • コードを修正して結果の変化を観察

会員限定無料チュートリアル

このチャプターは登録会員限定の無料コンテンツです!ログインまたは登録してすぐにロックを解除してください。

今すぐログイン / 登録