線形計画法のソルバの使い方:Python
最近,線形計画法のソルバを使ってあれこれしました.使うために色々調べたわけですが,時間が立つと調べた内容を忘れそうなので記録しておきます.
線形計画法のソルバはPuLPというライブラリから呼び出して使います.
例題を解いてみる
こういう最適化問題があるとします.
これは が答えなのですが,本当にそうなるかを試します.
バッチ処理版
細かいところを説明する前に,まずは全体像をお見せします.バッチ処理で書くとこんな感じです.
# (1)ライブラリ呼び出し import pulp # (2)問題の定義 lp = pulp.LpProblem('lp', pulp.LpMaximize) # (3)変数の設定 x1 = pulp.LpVariable('x1', 0) x2 = pulp.LpVariable('x2', 0) # (4)評価関数の生成 lp += 4*x1 + 3*x2 # (5)制約条件の生成 lp += 2*x1 + 3*x2 <= 15 lp += 2*x1 + x2 <= 9 # (6)最適化問題の確認 print(lp) # (7)求解 lp.solve() # (8)結果の確認 print('x1=',x1.value()) print('x2=',x2.value())
これを読み込むと,
lp: MAXIMIZE 4*x1 + 3*x2 + 0 SUBJECT TO _C1: 2 x1 + 3 x2 <= 15 _C2: 2 x1 + x2 <= 9 VARIABLES x1 Continuous x2 Continuous x1= 3.0 x2= 3.0
おぉ.ちゃんと が出力されました.
解説
(1)ライブラリの呼び出し
これは何も説明する必要はないと思います.
import pulp
(2)問題の定義
pulp.LpProblemで最大化問題か最小化問題かを設定するそうです.引数はそれぞれ下記のようになります.
pulp.LpProblem(『1.問題の名前』, 『2.最大化or最小化』)
- 『1.問題の名前』で問題の名前を決めるらしいです.
- 『2.最大化or最小化』では最小化問題ならLpMinimize ,最大化問題なら LpMaximizeと入力します.デフォルトではLpMinimizeです.
これに関しても,下記のリンク先に英語で載っていますので,ご参考にしていただければと思います.
今回は最大化問題なので次のように書きました.
lp = pulp.LpProblem('lp', pulp.LpMaximize)
(3)変数の生成
pulp.LpVariableで変数を作ります.引数はそれぞれ
pulp.LpVariable(『1.名前』, 『2.変数の最小値』,『3.変数の最大値』, 『4.連続値or離散値or01』, 『5.e』)
を意味するらしいです.要するに
- 『1.名前』では変数の名前を入力する
- 『2.変数の最小値』では,文字通り変数の最小値を入力します.何も入れないと設定されないようです.
- 『3.変数の最大値』では,同じく最大値を入力します.何も入れないと設定されないようです.
- 『4.連続値or離散値or01』では Integer(整数計画問題), Binary(0,1) or Continuous(連続値)を入力するそうです.デフォルトではContinuous(連続値)だそうです
- 『5.e』は列ベースのモデリングに使用されるそうですが,正直良くわかりません.
ということみたいです.下記のリンク先に英語で書いてあるので,こちらも御覧ください.
今回は制約条件より なので,下記のように入力しました.
x1 = pulp.LpVariable('x1', 0) x2 = pulp.LpVariable('x2', 0)
(4)評価関数の生成
評価関数はさっき作ったオブジェクトに足していくみたいです.
lp += 4*x1 + 3*x2
(5)制約条件の生成
制約条件もさっき作ったオブジェクトに足していくみたいです.
lp += 2*x1 + 3*x2 <= 15 lp += 2*x1 + x2 <= 9
(6)最適化問題の確認
さっき作ったオブジェクトlpを出力すれば問題が表示されます.どういう問題を解くか?というのが見れます.
print(lp)
と書くと
lp: MAXIMIZE 4*x1 + 3*x2 + 0 SUBJECT TO _C1: 2 x1 + 3 x2 <= 15 _C2: 2 x1 + x2 <= 9
と出力されます.
(7)求解
さっきのオブジェクトに,.solve()モジュールをくっつけます.
lp.solve()
(8)計算結果の確認
変数に.value()モジュールをくっつければ,結果が見れます.
print(x1.value()) print(x2.value())