PuLPはGurobiをサポートするモデリングフレームワークの一つです。本記事では、PuLPを通じてGurobiを使用する方法について説明します。より詳しい情報やPuLPに関連する問題の解決には、PuLP公式ウェブサイトおよびGurobiインターフェースの特定のドキュメントをご覧ください。
Gurobiへのインターフェース
PuLPはGurobiへの2つのインターフェースを提供しています。これらのインターフェースはPuLPで定義されたモデルをGurobiモデルに変換します。それぞれのインターフェースはわずかに異なる機能を持ち、デフォルトの動作も異なります。したがって、はじめに適切なインターフェースを選ぶことが重要です。以下のインターフェースが利用可能であり、詳細は後述します。
-
GUROBIは一時ファイルを生成せずにモデルを直接gurobipyに変換します。通常はこちらの方法が推奨されます。 -
GUROBI_CMDはモデルを記述したLPファイルを生成し、その後コマンドラインでgurobi_clを呼び出します。この方法は通常遅く、オプションも少なくなります。
以下のセクションでは、それぞれのインターフェースの詳細について説明します。すべてのコードスニペットは、すでにPuLPモデルが構築されていること(例えば下記のようなprobオブジェクト)を前提としています。
from pulp import *
prob = LpProblem("Sample problem", LpMinimize)
x = LpVariable("x", 0, 5)
y = LpVariable("y", 0, 4)
prob += x + y >= 1, "c"
prob += 2*x + 3*y, "Obj"直接インターフェース
インターフェースの使用方法
直接インターフェースを使ってモデルを解くには、以下のコードを使用します:
solver = GUROBI()
prob.solve(solver)Gurobi environmentの管理
デフォルトでは、PuLPはグローバル(デフォルト)Gurobi environmentオブジェクトに依存しています。欠点は、この環境が最初の使用時に自動的に作成されるものの、Pythonスクリプト全体が終了するまで破棄されないことです。これにより、他のプロセスが同じライセンスに依存している場合に問題が生じることがあります。
モデルを確実に解放するためには、solver.close()を呼び出します。その後、gp.disposeDefaultEnv()を使ってGurobiにデフォルト環境の破棄を指示できます。
または、既存のGurobi環境をenv引数としてソルバー構築時に渡すこともできます。PuLPは、この環境のセットアップおよび破棄はユーザーの責任であるとみなします。この場合でもモデルを解放するためにsolver.close()を呼び出します。
import gurobipy as gp
params = { } # 環境パラメータをここに記述
with gp.Env(params=params) as env:
solver = GUROBI(env=env)
prob.solve(solver)
solver.close()
# このwithブロック内でenvを引き続き使用可能最後に、PuLPに環境の作成、管理、および解放を任せ、環境初期化のためのオプションだけを与える方法もあります。この場合、manageEnv=True引数を設定し、(任意で)環境パラメータをenvOptions引数を通じて提供します。
params = { } # 環境パラメータをここに記述
solver = GUROBI(manageEnv=True, envOptions=params)
prob.solve(solver)
solver.close()環境パラメータの設定
PuLPがデフォルトのGurobi environmentを使用する場合(前述の1番目の方法)、コード内ではパラメータを与えられず、ライセンスファイルに依存する必要があります。前述の2・3番目の方法でなら、コードスニペットのようにパラメータを提供できます。
モデルパラメータの設定
特定のモデルを解くためのパラメータは、prob.solve(solver)呼び出し時に提供できません。代わりに、ソルバー構築時に追加のキーワード引数としてこれらのパラメータを提供します。例:GUROBI(TimeLimit=60)。PuLPにはさまざまなパラメータの特別な名前があり、それらは対応するGurobiパラメータに自動的に変換されます。したがって、GUROBI(timeLimit=60, gapRel=0.01)を呼び出すと、GUROBI(TimeLimit=60, MIPGap=0.01)と同じ動作になります。
モデルのエクスポート
PuLPはGurobiに依存せずにMPSおよびLPファイルを生成できます。つまり、Gurobiをインストールする前からファイルを生成できます。PuLPはモデル構築時に提供した変数名および制約名を常に使用し、エクスポート時に匿名化されることはありません。
以下の関数のいずれかを使用してください:
prob.writeLP("test.lp")
prob.writeMPS("test.mps", with_objsense=True)モデルエクスポートによって目的関数の方向(最大化)が失われる既知の問題を避けるため、必ずwith_objsense=Trueを使用してください。Gurobiサポートとファイルを共有するために完全に同等のモデルエクスポートを得たい場合は、代わりにResultFileパラメータを使用してください。このパラメータを"test.mps"に設定すると、(PuLPではなく)GurobiがMPSファイルをエクスポートします。
ログ出力
デフォルトでは、PuLPはGurobiのログ出力動作を変更しません。つまり、画面に出力は表示されますがログファイルは作成されません。
- ログファイルを生成するには、Gurobiの
LogFileパラメータを設定するか、同効果のlogPathパラメータを提供してください。 - コンソールへのログ出力を無効にするには、ソルバー構築時に
msg=False引数を設定してください。
サポートされるモデルタイプ
PuLPはLPおよびMIPモデルのみをサポートします。二次計画や一般的な非線形モデルはサポートしていません。
基盤となるGurobiモデルオブジェクトへのアクセス
基盤となるモデルオブジェクトには以下のようにアクセスできます。以下の例はIISを計算します。
prob.solverModel.computeIIS()この呼び出しの結果を取得するには、個別のgurobipy変数および制約にアクセスする必要があります。これは結果がPyomoの変数や制約に戻されないためです。インターフェースは生成されたGurobi変数および制約を元のPuLP変数および制約に保存します:
# Gurobi変数にアクセス
gurobi_x = x.solverVar
# 制約を構築時に保存
c2 = x + y >= 3
prob += c2, "c2"
# 後でGurobi制約にアクセス
gurobi_c2 = c2.solverConstraintコマンドラインインターフェース
インターフェースの使用方法
コマンドラインインターフェースを使用するには、以下の方法を用います:
solver = GUROBI_CMD()
prob.solve(solver)Gurobi environmentの管理
コマンドラインインターフェースはGurobiを外部プロセスとして実行するため、Gurobi環境の初期化や破棄のカスタマイズはできません。Gurobiは利用可能なライセンスファイルを使用します。
モデルパラメータの設定
GUROBI_CMDオブジェクト構築時に、(key, value)ペアのリスト形式で解法関連のパラメータを提供します。例えば、GUROBI_CMD([("LogFile", "test.log")])のようにします。これらのパラメータはGurobiにコマンドライン引数として送られます。
その他の注意事項
- モデルのエクスポートは上記(直接インターフェースの場合)と同じ方法を使用してください。
- ログ出力の動作も直接インターフェースの場合と同じです。
- サポートされるモデルタイプも同じです(LPおよびMIPのみ、二次計画や一般的非線形は不可)
- コマンドラインインターフェース使用時は、基盤となる
gurobipyモデル表現はありません。Gurobi固有の機能は利用できません。特にIISを必要とする場合は、ResultFileパラメータに.ilp拡張子のファイル名を追加することを検討してください。