Traffine I/O

日本語

2022-12-04

Python-MIP

Python-MIPとは

Python-MIP(Mixed Integer Programmingの略)は、複雑な最適化問題を解決するために設計されたOSSのPythonライブラリです。

Python-MIPは、Pythonのインターフェースの下に、C++ライブラリであるCbc(Coin-or branch and cut)を利用しています。Cbcは、混合整数計画問題を解決する能力で知られる高度に最適化されたライブラリです。CbcのパフォーマンスとPythonのシンプルさの組み合わせにより、さまざまな最適化タスクに対応することができます。

Python-MIPは混合整数計画だけでなく、連続線形計画問題も扱うことができます。この柔軟性により、Python-MIPはオペレーションリサーチや物流から機械学習やデータサイエンスまで、さまざまなユースケースに適しています。

Python-MIPの主な特徴

Python-MIPライブラリは、最適化タスクに優れたツールとなるいくつかの主要な特徴を持っています。

  • 混合整数線形計画(MILP)と連続線形計画(LP)
    Python-MIPは、1つの種類の最適化問題に限定されません。MILPとLPの両方の問題を扱うことができ、さまざまな最適化タスクの要件に適応する柔軟なツールとなっています。

  • 使いやすさ
    Python-MIPの魅力の一つは、Pythonicなインターフェースです。ユーザーフレンドリーな高レベルの使いやすいインターフェースを提供しており、初心者でも簡単にライブラリを利用することができます。

  • 高いパフォーマンス
    Python-MIPは、シンプルで使いやすいPythonのインターフェースを提供しますが、内部ではCbcライブラリが動作しています。Cbcは、混合整数計画問題を解決するために特化された高度に最適化されたC++ライブラリです。Cbcのパワーを活用することで、Python-MIPは大規模で複雑な問題を効率的に処理できる高性能なツールを提供します。

  • コールバック機能
    Python-MIPのより高度な機能の一つは、コールバック機能です。この機能により、ユーザーは解決プロセスにカスタムロジックを注入することができます。ソルバーの動作を変更するために使用することができます。これにより、特定のニーズに合わせて解決プロセスをカスタマイズする柔軟性が提供されます。

PuLPとの比較

最適化に関する別のよく知られたPythonライブラリであるPuLPと比較して、Python-MIPの利点はいくつかあります。Python-MIPの主な利点はパフォーマンスです。Cbcソルバーを使用しているため、特に大規模で複雑な問題においてPython-MIPはしばしばPuLPよりも優れたパフォーマンスを発揮します。さらに、Python-MIPのインターフェースは、Python開発者にとってよりPythonicで直感的とされ、使用が容易です。最後に、Python-MIPのコールバック機能は、PuLPでは利用できないカスタマイズのための強力なツールを提供します。

Python-MIPが解ける最適化問題の種類

Python-MIPは、次のようなさまざまな最適化問題を解決することができます。

  • 線形計画問題(LP)
  • 混合整数線形計画問題(MILP)

ケーススタディ

大規模な製造会社の物流ネットワークを最適化するケーススタディを考えてみます。

問題の説明

会社は複数の生産施設を運営し、広範な小売業者ネットワークにサービスを提供しています。目標は、生産施設から小売業者への輸送の総コストを最小化することです。問題には次の変数と制約が含まれます。

  • 各生産施設には特定の生産能力がある
  • 各小売業者には特定の需要がある
  • 各施設から各小売業者への輸送コストがある
  • 各小売業者の需要は満たされる必要がある
  • 各施設の総生産量はその能力を超えてはならない

問題の定式化

この問題はMILP問題として定式化することができます。目的関数と制約条件は次のように記述されます(ここでc_{ij}は施設iから小売業者jへの輸送コスト、x_{ij}iからjへの輸送量、s_iは施設iの供給量、d_jは小売業者jの需要量です)。

最小化:

\sum_i \sum_j c_{ij} * x_{ij}

制約条件:

\textrm{For all } i: \sum_j x_{ij} \leqq s_i \\ \textrm{For all } j: \sum_i x_{ij} \geqq d_j \\ \textrm{For all } i,j: x_{ij} \geqq 0 \\

Python-MIPのコード

問題を表現し、Python-MIPを使用して解決します。

python
from mip import Model, xsum, MINIMIZE, CONTINUOUS

# Define the data
costs = [[2, 4, 5, 2], [3, 1, 3, 2], [2, 3, 2, 3]]  # costs from each facility to each retailer
supply = [1000, 2000, 1500]  # supply capacity at each facility
demand = [500, 900, 1800, 300]  # demand at each retailer

# Create a new model
m = Model("Transportation", sense=MINIMIZE)

# Create variables
x = [[m.add_var(var_type=CONTINUOUS) for j in range(len(demand))] for i in range(len(supply))]

# Set the objective function
m.objective = xsum(costs[i][j]*x[i][j] for i in range(len(supply)) for j in range(len(demand)))

# Add constraints
for i in range(len(supply)):
    m += xsum(x[i][j] for j in range(len(demand))) <= supply[i]

for j in range(len(demand)):
    m += xsum(x[i][j] for i in range(len(supply))) >= demand[j]

# Solve the problem
m.optimize()

# Print the solution
for i in range(len(supply)):
    for j in range(len(demand)):
        if x[i][j].x >= 0.99:
            print(f"Ship {x[i][j].x} units from facility {i} to retailer {j}")
Ship 500.0 units from facility 0 to retailer 0
Ship 300.0 units from facility 0 to retailer 3
Ship 900.0 units from facility 1 to retailer 1
Ship 300.0 units from facility 1 to retailer 2
Ship 1500.0 units from facility 2 to retailer 2

このスクリプトは、データを定義し、モデルを作成し、変数、目的関数、制約条件を定義します。最後に、optimize関数を呼び出して問題を解決します。解は、輸送コストを最小化するために各施設から各小売業者への商品の輸送方法が示されます。

参考

https://www.python-mip.com/

Ryusei Kakujo

researchgatelinkedingithub

Focusing on data science for mobility

Bench Press 100kg!