数理計画

【数理最適化】SCIP8 + AMPL のインストール【CentOS7】

はじめに

SCIPとは数理最適化ソルバーの一つで、特徴として非線形最適化問題も解くことができます。
今回、CentOS7の環境でインストールするのに大分手こずりましたので、記事にしました。
CentOSではなく、Macなどでインストールする場合は、こちらが参考になると思います。
・SCIPをMacにインストール
・最適化ソルバーSCIP,モデリング言語Pyomoを使ってPythonで最適化問題を解いてみた

SCIPのダウンロード

公式のサイトからソースファイルをダウンロードします。
左メニューのDownLoadからOSをLinuxに選択し、「scipoptsuite-8.0.0.tgz」を選択。
8.00は2022/06/01時点では、Beta版の扱いですので、ひとつ前の7.0.3でも問題ありません。
(注)非商用利用の場合は無料ですが、商用利用の場合は有料となります。

【補足】8.00を選んだ理由
8.0.0から、AMPLのIFを標準搭載しており、 「.nl」拡張子のファイルを使う事ができます。
7.0.3以前でも可能なのですが、実行モジュールがAMPL用とそれ以外の部分(LP等)で別れてしまうので8.0.0にしました。
※同じ実行モジュールで、.nlファイルも.lpファイルもソルバーにかけたいという方向けです。

インストールの前準備

ここからが大変だったのですが、SCIPをそのままインストールしようとしても、ライブラリが全然足りませんでした。
yumなどのコマンドで、簡単にインストールできれば良かったのですが、glibも上げる必要性があり、色々とコンパイルを行ってインストールしていきました。
※私はあまりLinuxのパッケージ管理に詳しくなく、本当はもっと良いやり方が有るかもしれません。

yumでのインストール

まずはコマンドで簡単にできるところからです。

#yumにてライブラリをインストール
yum install centos-release-scl devtoolset-10 gcc-gfortran libgfortran lapack-devel

#gcc10のコンパイル設定
scl enable devtoolset-10 bash

#リポジトリ追加
yum install http://mirror.ghettoforge.org/distributions/gf/gf-release-latest.gf.el7.noarch.rpm

#readlineをインストール
yum --enablerepo=gf install readline.x86_64
yum --enablerepo=gf install readline-devel

boost

次はboostです。公式サイトからダウンロードし、インストールを行います。
下記は、boost_1_77_0.tar.gzをダウンロードした結果となります。

#ダウンロードしたファイルを解凍
tar xvfz boost_1_77_0.tar.gz

cd ./boost_1_77_0
#コンパイル
./bootstrap.sh  --prefix=/usr/local/

#インストール
./b2 install

#共有ライブラリのPATH設定
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib/

GMP

GMPとは多倍長整数などの任意精度の算術ライブラリです。
同じく、コンパイルしてインストールしていきます。

#ダウンロード
wget https://gmplib.org/download/gmp/gmp-6.2.1.tar.xz
tar xvf gmp-6.2.1.tar.xz
cd gmp-6.2.1

#コンパイル&インストール
./configure --prefix=/usr/local/gmp/6_1_2
make

make check

make install

#ヘッダを/usr/local/include/にシンボリックリンク
ln -s /usr/local/gmp/6_1_2/include/gmp.h /usr/local/include/

#共有ライブラリを/usr/local/lib/シンボリックリンク
ll /usr/local/lib
ln -s /usr/local/gmp/6_1_2/lib/libgmp.a /usr/local/lib/
ln -s /usr/local/gmp/6_1_2/lib/libgmp.la /usr/local/lib/
ln -s /usr/local/gmp/6_1_2/lib/libgmp.so /usr/local/lib/
ln -s /usr/local/gmp/6_1_2/lib/libgmp.so.10 /usr/local/lib/
ln -s /usr/local/gmp/6_1_2/lib/libgmp.so.10.4.1 /usr/local/lib/

zlib

zlibは圧縮用のライブラリです。
同様に、公式サイトからソースをダウンロードします。
※ダウンロードしたバージョンは1.2.11となります。

同様にコンパイルおよびインスト―ルを行います。

#解凍
tar xvzf zlib-1.2.11.tar.gz
cd zlib-1.2.11

#コンパイルとインストール
./configure --shared --prefix=/usr

make

make test

make install

glibのバージョンアップ2.23

glibのバージョンアップを行います。
glibはOSの基礎的なライブラリであり、変更時は慎重に実施いただくようお願いします。
本記事では2.17から2.23へのバージョンアップの内容となりますが、利用環境によってはうまく動かなくなる可能性もありますのでご注意ください。

・SCIPの標準的な機能を使いたい場合は、glibバージョンアップおよび上述のコンパイル(boost,GMP,zlib)作業は不要です。AMPLを使う場合に必要になります。

・コンパイル時では上述でインストールしたgcc10を使わずに、旧バージョンで実施します。
※gcc10だと、configure時にエラーになるため、10未満である必要性があります。

#ダウンロード
wget --no-check-certificate https://ftp.gnu.org/gnu/glibc/glibc-2.23.tar.gz
tar fzxv glibc-2.23.tar.gz
cd glibc-2.23

mkdir build
cd build
#事前にgcc -v でバージョン確認して、10になっていたら、一度ログアウトして昔のgccのバージョンに戻すこと
../configure --prefix=/usr --disable-profile --enable-add-ons --with-headers=/usr/include --with-binutils=/usr/bin

#コンパイル
make

make install

#エラーが出た場合、共有ライブラリの向き先を修正
# →出ない場合もあります。詳細は参考サイトを確認ください。
cd /lib64
unlink libm.so.6
ln -s libm-2.23.so libm.so.6

#再度実施
cd /home/****/glibc-2.23/build

make install

SCIPのインストール

最後にSCIPのインストールとなります。
前述でダウンロードした「scipoptsuite-8.0.0.tgz」 を利用します。
make時のオプションですが、「TPI=tny」を指定することで、マルチプロセスでの実行が可能となります。
詳細については公式サイトを確認ください。
また、glibをバージョンアップせずに、SCIPの標準的な機能のみを利用したい場合は
「BOOST=false ZIMPL=false」のオプションを指定すれば実行可能です。
※このオプションのみだと、マルチプロセスや「.nl」ファイルの実行ができません。

#解凍
tar fzxv scipoptsuite-8.0.0.tgz
cd scipoptsuite-8.0.0

#コンパイル設定
scl enable devtoolset-10 bash

#TPI付きでコンパイル&インストール
make TPI=tny

#glibをバージョアップせずに利用したい場合
#make BOOST=false ZIMPL=false

#インストール後、tny拡張子でscipがいることを確認
ll scip/bin/scip-8.0.0.linux.x86_64.gnu.opt.spx2.tny

#実行モジュールを/usr/local/binにコピー
#PATHが通る場所にコピーしているだけのため、実施しなくても問題ありません。
cp /home/centos/scipoptsuite-8.0.0/scip/bin/scip /usr/local/bin/scip

実行確認

実際に、scipの実行モジュールを開くと、以下のようなメッセージが表示されます。
※「External libraries」の内容はmake時のオプションによって異なります。

#SCIP起動
/usr/local/bin/scip

SCIP version 8.0.0 [precision: 8 byte] [memory: block] [mode: optimized] [LP solver: SoPlex 6.0.0] [GitHash: a740f0891e]
Copyright (C) 2002-2021 Konrad-Zuse-Zentrum fuer Informationstechnik Berlin (ZIB)

External libraries:
  Readline 6.2         GNU library for command line editing (gnu.org/s/readline)
  SoPlex 6.0.0         Linear Programming Solver developed at Zuse Institute Berlin (soplex.zib.de) [GitHash: 71a5873d]
  CppAD 20180000.0     Algorithmic Differentiation of C++ algorithms developed by B. Bell (github.com/coin-or/CppAD)
  ZLIB 1.2.11          General purpose compression library by J. Gailly and M. Adler (zlib.net)
  GMP 6.2.1            GNU Multiple Precision Arithmetic Library developed by T. Granlund (gmplib.org)
  ZIMPL 3.5.1          Zuse Institute Mathematical Programming Language developed by T. Koch (zimpl.zib.de)
  AMPL/MP 4e2d45c4     AMPL .nl file reader library (github.com/ampl/mp)
  TinyCThread          Small, portable implementation of the C11 threads API (tinycthread.github.io)

user parameter file <scip.set> not found - using default parameters

SCIP>

① read <ファイル名>
② optimize
③ display solution
の順で実行を行います。 
※マルチプロセスでの実行を行う場合は、「optimize」ではなく「concurrentopt」となります。

#ファイル読み込み
SCIP> read solver.lp

read problem <solver.lp>
============

original problem has 18811 variables (18810 bin, 0 int, 0 impl, 1 cont) and 6255 constraints

#実行
SCIP> optimize

presolving:
(round 1, fast)       2065 del vars, 1030 del conss, 0 add conss, 2066 chg bounds, 2 chg sides, 2301 chg coeffs, 0 upgd conss, 0 impls, 11421 clqs
(round 2, fast)       2085 del vars, 1049 del conss, 0 add conss, 2086 chg bounds, 2 chg sides, 2373 chg coeffs, 0 upgd conss, 0 impls, 11704 clqs
~省略~
 time | node  | left  |LP iter|LP it/n|mem/heur|mdpt |vars |cons |rows |cuts |sepa|confs|strbr|  dualbound   | primalbound  |  gap   | compl.
p 8.4s|     1 |     0 |  2037 |     - | vbounds|   0 |  16k|1842 |1841 |   0 |  0 |   0 |   0 | 1.105164e+08 | 5.998354e+06 |1742.45%| unknown
  8.8s|     1 |     0 |  5588 |     - |   174M |   0 |  16k|1852 |1841 |   0 |  0 |  10 |   0 | 6.311273e+06 | 5.998354e+06 |   5.22%| unknown
 10.6s|     1 |     0 |  6045 |     - |   193M |   0 |  16k| 747 | 852 | 127 | 20 |  10 |   0 | 6.310844e+06 | 6.310818e+06 |   0.00%| unknown
 10.6s|     1 |     0 |  6046 |     - |   194M |   0 |  16k| 747 | 831 | 128 | 21 |  10 |   0 | 6.310835e+06 | 6.310818e+06 |   0.00%| unknown
 10.7s|     1 |     0 |  6046 |     - |   194M |   0 |  16k| 747 | 831 | 128 | 21 |  10 |   0 | 6.310835e+06 | 6.310818e+06 |   0.00%| unknown

SCIP Status        : problem is solved [optimal solution found]
Solving Time (sec) : 11.37
Solving Nodes      : 1 (total of 2 nodes in 2 runs)
Primal Bound       : +6.31081760000000e+06 (19 solutions)
Dual Bound         : +6.31081760000000e+06
Gap                : 0.00 %

#結果確認
SCIP> display solution

objective value:                            6310817.6
x64                                                 1   (obj:4500)
x90                                                 1   (obj:4500)
~省略~
x18772                                              1   (obj:24000)
ONE_VAR_CONSTANT                                    1   (obj:0)

SCIP>

【補足】Pythonライブラリ利用時の注意点

PythonでLPファイル等を作成する際は、PuLPやPyomoのライブラリが比較的広く周知されていますが、SCIPはバージョンによって、動作しない場合があります。
私は以下のサイトを参考にしました。

▽PuLP
 PuLPからSCIPを利用するためのモジュールを書いてみた
▽Pyomo
 https://github.com/Pyomo/pyomo/issues/2226

ABOUT ME
Fukunaga
Fukunaga
リードエンジニアしてます。フロントからサーバサイドまで、フルスタックで担当。 DBチューニングが得意。最近はキントーン開発、AI/分析作業など従事しています。