PuLPで書いた最適化モデルをCPLEXで解く

PuLPで書いた最適化モデルをCPLEXで解くことができます。

- テスト環境
    - CPLEX 22.1.1
    - PuLP 2.9.0
    - python 3.11.9
    
PuLPのデフォルトのソルバーはCBC(COIN-OR Brand-and-Cut)ですが、ソルバーを切り替えて求解することができます。

パスが通っている必要があります。Windows版のCPLEXは、デフォルトの導入ではPATHに設定しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/406aeccf-fe8d-ecde-801c-e0ad47a71ee4.png)

`pulp.pulpTestAll()`で利用可能なソルバーを確認できます。

```python:利用可能なソルバーの確認
import pulp
pulp.pulpTestAll()
```
以下の環境では、CBC(PULP_CBC_CMD)、CPLEX(CPLEX_CMD)、GLPK(GLPK_CMD)のソルバーが利用可能です。

```bash:出力例
Available solvers: ['GLPK_CMD', 'CPLEX_CMD', 'PULP_CBC_CMD']
Unavailable solvers: {'MIPCL_CMD', 'COPT_CMD', 'SCIP_CMD', 'COPT', 'COPT_DLL', 'HiGHS_CMD', 'GUROBI', 'XPRESS_PY', 'GUROBI_CMD', 'CPLEX_PY', 'CHOCO_CMD', 'COINMP_DLL', 'SCIP_PY', 'MOSEK', 'COIN_CMD', 'XPRESS', 'HiGHS', 'PYGLPK', 'FSCIP_CMD'}
ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss................................................................................................................................ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss................................................................ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss................................................................ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
----------------------------------------------------------------------
Ran 1348 tests in 76.787s

OK (skipped=1092)
```

[pulpのドキュメントのREADME](https://github.com/coin-or/pulp/tree/master)にあった問題を解いてみます。

```python:サンプル問題
from pulp import *
x = LpVariable("x", 0, 3)
y = LpVariable("y", cat="Binary")
prob = LpProblem("myProblem", LpMinimize)
prob += x + y <= 2
prob += -4*x + y
```
`prob.solve()`を実行するとデフォルトのCBCソルバーが使用されます。

```python:CBCでの求解
# デフォルトCBC(COIN-OR Brand-and-Cut)ソルバーで解く
prob.solve()
# 解決したLPのステータスを出力
print("Status:", LpStatus[prob.status])
# 最適解を出力
for v in prob.variables():
    print(v.name, "=", v.varValue)
# 目的関数値を出力
print("objective=", value(prob.objective))
```
`prob.solve(CPLEX())`を実行するとCPLEXソルバーが使用されます。それ以外は何も変更せずとも動きます。

```python:CPLEXでの求解
# CPLEXソルバーで解く
prob.solve(CPLEX())
# 解決したLPのステータスを出力
print("Status:", LpStatus[prob.status])
# 最適解を出力
for v in prob.variables():
    print(v.name, "=", v.varValue)
# 目的関数値を出力
print("objective=", value(prob.objective))
```

この問題はランダム要素がないので結果は同じです。
```bash:結果
Status: Optimal
x = 2.0
y = 0.0
objective= -8.0
```

オプションを指定したい場合は以下のように指定します。
```python:オプション指定
prob.solve(CPLEX_CMD(options=['set mip tolerances mipgap 0.25']))
```



# 参考

#### pulp/examples/test1.py
https://github.com/coin-or/pulp/blob/master/examples/test1.py

Interactive Optimizer のオプション

https://www.ibm.com/docs/ja/icos/12.10.0?topic=cplex-table-commands-interactive-optimizer

Pulp ソルバー選択 / 並列計算 (python) - Sabrou-mal サブロウ丸 

https://inarizuuuushi.hatenablog.com/entry/2019/03/07/090000