CPLEXのInteractive OptimizerでLPファイルの問題を解く

CPLEXのInteractive Optimizerを使ってLPファイルやsavファイルの問題を解きます。

LPファイルはC#やdocpexなどのAPIで書き出すことができます。

* テスト環境
    * CPLEX 22.1.1
    * Windows 11 64bit




以下の記事のC＃のプログラムで出力したLPファイルを使います。

https://qiita.com/kawada2017/items/2490960cb19166c20107



# Interactive Optimizerの起動
LPファイルなどがあるディレクトリに「cd」で移動し、「cplex」コマンドでInteractive Optimizerを起動します。
「CPLEX>」のプロンプトが出ます。

```cmd:Interactive Optimizerの起動
C:\temp>cd C:\Users\dsuser1\Documents\cs\Dietlesson\Dietlesson\bin\Debug\net7.0

C:\Users\dsuser1\Documents\cs\Dietlesson\Dietlesson\bin\Debug\net7.0>cplex

Welcome to IBM(R) ILOG(R) CPLEX(R) Interactive Optimizer 22.1.1.0
  with Simplex, Mixed Integer & Barrier Optimizers
5725-A06 5725-A29 5724-Y48 5724-Y49 5724-Y54 5724-Y55 5655-Y21
Copyright IBM Corp. 1988, 2022.  All Rights Reserved.

Type 'help' for a list of available commands.
Type 'help' followed by a command name for more
information on commands.

CPLEX>
```

# LPファイルを読み込み、初期解を得る
この例では、LPファイルを読み込んで、実行可能解を一つだけ得てみます。

## LPファイルを読み込み、問題の情報を確認する
LPファイルの中身は以下です。

https://github.com/hkwd/230404cplex/blob/master/230404cs_interactive/DietLesson.lp

「read」でLPファイルを読み込み、「display problem stat」で問題の情報を確認します。

```cmd:LPファイルを読み込み、問題の情報を確認する
read DietLesson.lp
display problem stat
```

```cmd:結果
CPLEX> read DietLesson.lp
Problem 'DietLesson.lp' read.
Read time = 0.00 sec. (0.00 ticks)
CPLEX> display problem stat
Problem name         : DietLesson.lp
Objective sense      : Minimize
Variables            :      16  [Box: 7,  General Integer: 9]
Objective nonzeros   :       9
Linear constraints   :       7  [Equal: 7]
  Nonzeros           :      65
  RHS nonzeros       :       7

Variables            : Min LB: 0.000000         Max UB: 9944.000
Objective nonzeros   : Min   : 0.6000000        Max   : 2.290000
Linear constraints   :
  Nonzeros           : Min   : 1.000000         Max   : 510.0000
  RHS nonzeros       : Min   : 55.00000         Max   : 2000.000
CPLEX>
```

## prmファイルを読み込み、初期解を得る
prmファイルの中身は以下です。

https://github.com/hkwd/230404cplex/blob/master/230404cs_interactive/DietLesson1.prm


「read」でprmファイルを読み込み、「opt」で初期解を得ます。
このprmファイルには「CPXPARAM_MIP_Limits_Solutions 1」が指定されていますので、一つでも実行可能解を見つけた時点で終了します。

```cmd:prmファイルを読み込み、初期解を得る
read DietLesson1.prm
opt
```

```cmd:結果
CPLEX> read DietLesson1.prm
Parameter file 'DietLesson1.prm' read.
CPLEX> opt
Version identifier: 22.1.1.0 | 2022-11-27 | 9160aff4d
CPXPARAM_MIP_Limits_Solutions                    1
Tried aggregator 1 time.
Reduced MIP has 7 rows, 16 columns, and 65 nonzeros.
Reduced MIP has 0 binaries, 9 generals, 0 SOSs, and 0 indicators.
Presolve time = 0.00 sec. (0.02 ticks)
Found incumbent of value 21.080000 after 0.00 sec. (0.09 ticks)

Root node processing (before b&c):
  Real time             =    0.00 sec. (0.09 ticks)
Parallel b&c, 8 threads:
  Real time             =    0.00 sec. (0.00 ticks)
  Sync time (average)   =    0.00 sec.
  Wait time (average)   =    0.00 sec.
                          ------------
Total (root+branch&cut) =    0.00 sec. (0.09 ticks)

Solution pool: 1 solution saved.

MIP - Solution limit exceeded, integer feasible:  Objective =  2.1080000000e+01
Current MIP best bound =  0.0000000000e+00 (gap = 21.08, 100.00%)
Solution time =    0.00 sec.  Iterations = 0  Nodes = 0 (1)
Deterministic time = 0.09 ticks  (87.68 ticks/sec)

CPLEX>
```

「Solution pool: 1 solution saved.」で一つの実行可能解を見つけています。
「MIP - Solution limit exceeded, integer feasible:  Objective =  2.1080000000e+01」なので実行可能で、目的関数は21.08です。


# 初期解から、savファイルの問題を解く
この例では、すでに初期解を得ているという状態で、その初期解をつかって、savファイルの問題を解きます。

## savファイル、prmファイルを読み込み
「read」savファイルを読み込み、「display problem stat」で問題の情報を確認します。
savファイルはバイナリ形式ですが、内容はLPファイルと同様です。ですので、「display problem stat」はlpファイルを読んだ結果と同じです。


```cmd:savファイルを読み込み、問題の情報を確認する
read DietLesson.sav
display problem stat
```

```cmd:結果
CPLEX> read DietLesson.sav
Problem 'DietLesson.sav' read.
Read time = 0.00 sec. (0.00 ticks)
CPLEX> display problem stat
Problem name         : DietLesson.sav
Objective sense      : Minimize
Variables            :       9  [General Integer: 9]
Objective nonzeros   :       9
Linear constraints   :       7  [Range: 7]
  Nonzeros           :      58
  RHS nonzeros       :       7

Variables            : Min LB: 0.000000         Max UB: 10.00000
Objective nonzeros   : Min   : 0.6000000        Max   : 2.290000
Linear constraints   :
  Nonzeros           : Min   : 1.000000         Max   : 510.0000
  RHS nonzeros       : Min   : 55.00000         Max   : 2000.000
  Range values       : Min   : 25.00000         Max   : 9944.000
CPLEX>
```

## prmファイルを読み込み、初期解を使って求解する
prmファイルの中身は以下です。

https://github.com/hkwd/230404cplex/blob/master/230404cs_interactive/DietLesson2.prm

mstファイルに初期解が入っています。内容は以下です。

https://github.com/hkwd/230404cplex/blob/master/230404cs_interactive/DietLesson.mst

「read」でprmファイルとmstファイルを読み込み、「opt」で初期解を得ます。
このprmファイルには「CPXPARAM_MIP_Limits_Solutions 1000」が指定されていますので、最適解が見つからなければ、1000個まで実行可能解を探します。

```cmd:prmファイルを読み込み、初期解を使って求解する
read DietLesson2.prm
read DietLesson.mst
opt
```

```cmd:結果
CPLEX> read DietLesson2.prm
Parameter file 'DietLesson2.prm' read.
CPLEX> read DietLesson.mst
MIP start file 'DietLesson.mst' read.
CPLEX> opt
Version identifier: 22.1.1.0 | 2022-11-27 | 9160aff4d
CPXPARAM_MIP_Limits_Solutions                    1000
Presolve time = 0.00 sec. (0.00 ticks)
1 of 1 MIP starts provided solutions.
MIP start 'm1' defined initial solution with objective 21.0800.
Tried aggregator 1 time.
Reduced MIP has 7 rows, 16 columns, and 65 nonzeros.
Reduced MIP has 0 binaries, 9 generals, 0 SOSs, and 0 indicators.
Presolve time = 0.00 sec. (0.02 ticks)
Tried aggregator 1 time.
Reduced MIP has 7 rows, 16 columns, and 65 nonzeros.
Reduced MIP has 0 binaries, 9 generals, 0 SOSs, and 0 indicators.
Presolve time = 0.00 sec. (0.02 ticks)
MIP emphasis: balance optimality and feasibility.
MIP search method: dynamic search.
Parallel mode: deterministic, using up to 8 threads.
Root relaxation solution time = 0.00 sec. (0.02 ticks)

        Nodes                                         Cuts/
   Node  Left     Objective  IInf  Best Integer    Best Bound    ItCnt     Gap

*     0+    0                           21.0800        0.0000           100.00%
*     0+    0                           20.4800        0.0000           100.00%
      0     0       14.8557     3       20.4800       14.8557        5   27.46%
*     0+    0                           15.6200       14.8557             4.89%
      0     0       14.9349     5       15.6200       Cuts: 2        9    4.39%
*     0+    0                           15.2300       14.9349             1.94%
      0     0       14.9637     4       15.2300       Cuts: 2       12    1.75%
*     0+    0                           15.0500       14.9637             0.57%
      0     0       14.9650     5       15.0500      Fract: 1       13    0.56%
      0     0        cutoff             15.0500       15.0500       13    0.00%
Elapsed time = 0.08 sec. (0.45 ticks, tree = 0.01 MB, solutions = 5)

Zero-half cuts applied:  1
Gomory fractional cuts applied:  2

Root node processing (before b&c):
  Real time             =    0.08 sec. (0.45 ticks)
Parallel b&c, 8 threads:
  Real time             =    0.00 sec. (0.00 ticks)
  Sync time (average)   =    0.00 sec.
  Wait time (average)   =    0.00 sec.
                          ------------
Total (root+branch&cut) =    0.08 sec. (0.45 ticks)

Solution pool: 5 solutions saved.

MIP - Integer optimal solution:  Objective =  1.5050000000e+01
Solution time =    0.11 sec.  Iterations = 13  Nodes = 0
Deterministic time = 0.45 ticks  (4.10 ticks/sec)
CPLEX>
```

「MIP start 'm1' defined initial solution with objective 21.0800.」というログが出力されましたので、mstファイルの初期解をつかってMIP Startが成功したこと示しています。
「MIP - Integer optimal solution:  Objective =  1.5050000000e+01」ですので、最適解で、目的関数は15.05でした。先の解の21.08より良い解が得られていることがわかります。


利用した各種ファイルは以下にあります。

https://github.com/hkwd/230404cplex/tree/master/230404cs_interactive