いものやま。

雑多な知識の寄せ集め

PICOSで2次計画問題を解いてみた。

前回はPythonのPICOSというライブラリで計量学習の半正定値計画問題を解いてみた。

このPICOSを使って数理最適化 Advent Calendar 2023の1日目に扱われていた2次計画問題を解いてみる。

これは数理最適化 Advent Calendar 2023の5日目の記事です。

はてなブログの数式表示がちょっとおかしいかも。。。

扱う問題

扱う問題は次のようなもの(※添え字は0, 1, 2としている):

\left|
\begin{array}{rl}
\mathrm{min.} & 100(x_0 - 0.1)^2 + 50(x_1 - 0.15)^2 + 10(x_2 - 0.25)^2 \\
\mathrm{sub.\ to} & x_0 \le x_1,\; x_1 \le x_2 \\
& x_1 - x_0 \ge x_2 - x_1 \\
& 0 \le x_0 \le 1,\; 0 \le x_1 \le 1,\; 0 \le x_2 \le 1 \\
\end{array}
\right.

元の記事ではこれを変形して2次計画の標準的な形に直してCVXOPTに行列の形で入力を与えていた。 ただ、PICOSを使うとこれは自然と書くことができる:

import picos
import numpy as np

problem = picos.Problem()

x = picos.RealVariable("x", shape=(3, 1), lower=0, upper=1)

problem.add_constraint(x[0] <= x[1])
problem.add_constraint(x[1] <= x[2])
problem.add_constraint(x[1] - x[0] >= x[2] - x[1])

objective = 100 * (x[0] - 0.1) ** 2 + 50 * (x[1] - 0.15) ** 2 + 10 * (x[2] - 0.25) ** 2
problem.set_objective("min", objective)

solution = problem.solve()

print(np.array(x))  # => [0.09736844 0.16052628 0.22368412]

サクッと書けて正しく解けてるのが分かると思う(ソルバーはCVXOPTで同じなので)。

ちなみにPICOSは線形計画問題も扱えるし(ソルバーでCBCが使えないけど)、インタフェースとなるライブラリを使えばCPLEXやGurobi、SCIPなどのソルバーも使える(らしい;ライセンス持ってないので実際に使ったことはない)ので、なかなか便利だと思う。

今日はここまで!