問題解決の数理

放送大学教養学部 主任講師:大西 仁

GLPK (GNU Linear Programming Kit)

GLPK (GNU Linear Programming Kit)はオープンソースの混合整数最適化法のソルバーである.Rのパッケージ glpk や Rglpk を利用すれば,RからGLPKを使用することができる.モデルとデータを別ファイルに記述することができるので,同一モデルによる計算はデータファイルのみを変更すればよい.また,APIが提供されているので,最適化計算を含むアプリケーションを自作する時,最適化計算の部分でGLPK APIを利用するということもできる.

GLPKのインストール

Windowsのバイナリ版の場合

  1. こちらからwinglpk-xxxx.zip (2020年9月15日時点では winglpk-4.65.zip)をダウンロードする.
  2. ダウンロードしたzipファイルを展開する.
  3. Windows が 32 bit版であれば,w32フォルダの glpsol.exe と glpk_4_65.dll を実行パスの通っているフォルダにコピーする.もちろん,DLLファイルはWindows\System32フォルダなどでもよい. Windows が 64 bit版であれば,w64フォルダのglpsol.exe と glpk_4_65.dll を使う.

ソースコードからコンパイルする場合

Linux環境(gcc)を使用することと仮定する.Unix系OSなら同じようにできると思う.
  1. GLPKのページに入り,最新のglpk-xxx.tar.gz(2020/09/15時点では glpk-4.65.tar.gz)をダウンロードする.
  2. 以下の手順でインストールする.
$ tar zxf glpk-xxx.tar.gz
$ cd glpk-xxx
$ ./configure
$ make
$ make check
$ make install

その他のシステムやインストール方法

Linuxならディストリビューションごとにインストール方法があり,GLPKが対応していれば,そちらの方法でインストールするほうが便利かもしれない.また,Windows で VC++ や Borland C++ によりコンパイルすることもできる.
このページのトップへ

GLPKの基本的な使い方

線形最適化法

次の線形最適化問題を例として用いる.
最大化z = 2x1 + 3x2
制約条件1x1 + 3x2 ≤ 24
4x1 + 4x2 ≤ 48
2x1 + 1x2 ≤ 22
x1 ≥ 0, x2 ≥ 0

この問題を解くためのプログラム(モデルファイル)は次のように書く. ダウンロードはこちら

/* LP.mod.txt */

var x1 >= 0 ;
var x2 >= 0 ;

maximize z: 2*x1 + 3*x2 ;
s.t. st1: x1 + 3*x2 <= 24 ;
s.t. st2: 4*x1 + 4*x2 <= 48 ;
s.t. st3: 2*x1 + x2 <= 22 ;

end;
数式と似た表記なので,モデルの記述はこれだけで大体分かると思う.
var x1, >=0, <=9;
このページのトップへ
モデルファイルの拡張子は mod を用いるのが慣習のようであるが,拡張子を変えても計算はできる.Windowsの場合は txt とするのが使いやすいであろう.ただし,モデルファイルであることは明示しておきたいので, LP.mod.txt のようなファイル名にしておくとよいであろう.

モデルファイルができたら,ターミナル,Windowsならコマンドプロンプトで次のように打つ.

> glpsol -m LP.mod.txt -o LP.out.txt
すると,LP.out.txtというファイルに結果が書き込まれる.LP.out.txtの内容は次のようになっている.
Problem:    LP
Rows:       4
Columns:    2
Non-zeros:  8
Status:     OPTIMAL
Objective:  z = 30 (MAXimum)

   No.   Row name   St   Activity     Lower bound   Upper bound    Marginal
------ ------------ -- ------------- ------------- ------------- -------------
     1 z            B             30                             
     2 st1          NU            24                          24           0.5
     3 st2          NU            48                          48         0.375
     4 st3          B             18                          22 

   No. Column name  St   Activity     Lower bound   Upper bound    Marginal
------ ------------ -- ------------- ------------- ------------- -------------
     1 x1           B              6             0               
     2 x2           B              6             0    
以下略

このページのトップへ

感度分析を行うには,次のように打つ.

> glpsol -m LP.mod.txt --ranges LP.sens.txt
すると,LP.sens.txtというファイルに結果が書き込まれる.LP.sens.txtの内容は次のようになっている.
GLPK 4.65 - SENSITIVITY ANALYSIS REPORT                                                                         Page   1

Problem:    LP
Objective:  z = 30 (MAXimum)

   No. Row name     St      Activity         Slack   Lower bound       Activity      Obj coef  Obj value at Limiting
                                          Marginal   Upper bound          range         range   break point variable
------ ------------ -- ------------- ------------- -------------  ------------- ------------- ------------- ------------
     1 z            BS      30.00000     -30.00000          -Inf       26.00000      -1.00000        .      st1
                                            .               +Inf       30.00000          +Inf          +Inf

     2 st1          NU      24.00000        .               -Inf       16.00000       -.50000      26.00000 st3
                                            .50000      24.00000       36.00000          +Inf      36.00000 x1

     3 st2          NU      48.00000        .               -Inf       32.00000       -.37500      24.00000 x1
                                            .37500      48.00000       54.40000          +Inf      32.40000 st3

     4 st3          BS      18.00000       4.00000          -Inf        8.00000       -.60000      19.20000 st2
                                            .           22.00000       24.00000       1.00000      48.00000 st1

GLPK 4.65 - SENSITIVITY ANALYSIS REPORT                                                                         Page   2

Problem:    LP
Objective:  z = 30 (MAXimum)

   No. Column name  St      Activity      Obj coef   Lower bound       Activity      Obj coef  Obj value at Limiting
                                          Marginal   Upper bound          range         range   break point variable
------ ------------ -- ------------- ------------- -------------  ------------- ------------- ------------- ------------
     1 x1           BS       6.00000       2.00000        .                -Inf       1.00000      24.00000 st2
                                            .               +Inf       10.00000       3.00000      36.00000 st1

     2 x2           BS       6.00000       3.00000        .             2.00000       2.00000      24.00000 st1
                                            .               +Inf        8.00000       6.00000      48.00000 st2

End of report

このページのトップへ
Page 1の表は制約式の右辺に関する分析である. Page 2の表は目的関数の係数に関する分析である.
このページのトップへ

整数最適化法

先ほどの線形最適化問題を決定変数が非負整数をとる整数最適化問題に変更する.
最大化z = 2x1 + 3x2
制約条件1x1 + 3x2 ≤ 24
4x1 + 4x2 ≤ 48
2x1 + 1x2 ≤ 22
x1, x2 = 0, 1, 2, ...

この整数最適化問題のモデルファイルは,線形最適化問題のモデルファイルを次のように変更すればよい. ダウンロードはこちら

/* IP.mod.txt */

var x1 , integer, >= 0 ;
var x2 , integer, >= 0 ;

maximize z: 2*x1 + 3*x2 ;
s.t. st1: x1 + 3*x2 <= 24 ;
s.t. st2: 4*x1 + 4*x2 <= 48 ;
s.t. st3: 2*x1 + x2 <= 22 ;

end;
0-1変数の場合は,integer の代わりに binary と指定する.その場合は不等号は不要で,単に
var x1, binary ;
と書けばよい.コマンドラインでのコマンドは同じである.
> glpsol -m LP.mod.txt -o LP.out.txt
ただし,整数最適化法では感度分析は使えない.
このページのトップへ