pulp のバグ:目的関数が零のとき valid() の返り値が正しくない
python の LP/MIP ソルバー(のラッパー)である pulp のバグをみつけたのでメモ. GitHub - coin-or/pulp: A python Linear Programming API
具体的には,目的関数がゼロの場合,ダミー変数が現れて
solve()
後の valid()
(現在の解が実行可能かどうか)の挙動が正しくなくなる.
サンプル
import pulp mip1 = pulp.LpProblem('****** MIP1 ******') x = pulp.LpVariable('x') mip1 += (0 * x) mip1 += (x >= 1) mip1.solve() print mip1 print 'x', x.value() print mip1.valid() print mip2 = pulp.LpProblem('****** MIP2 ******') y = pulp.LpVariable('y') mip2 += (1 * y) mip2 += (y >= 1) mip2.solve() print mip2 print 'y', y.value() print mip2.valid()
出力(# 以降は注釈)
****** MIP1 ******: MINIMIZE 0*__dummy + 0 SUBJECT TO _C1: x >= 1 VARIABLES __dummy = 0 Continuous # 自分で定義していないダミー変数が現れている x free Continuous x 1.0 False # validでないと判定される.しかし,x = 1.0 は明らかに実行可能. ****** MIP2 ******: MINIMIZE 1*y + 0 SUBJECT TO _C1: y >= 1 VARIABLES y free Continuous y 1.0 True
理由はダミー変数 __dummy
の値が零でなく None
になるから.
for v in mip1.variables(): print v, v.value()
出力:
__dummy None x 1.0
LpProblem.valid()
は問題に現れるすべての変数,制約が valid であれば True
を返すが,
変数の値が None
のとき,変数は valid ではないという実装になっているのが問題.
おそらく正しい解決は,ダミー変数の値のデフォルトを 0 にすること?
ダミー変数のポリシーとかよく分かっていないのでプルリクを送るには至っていない.
4月8日追記 issueたてた