※記事内に商品プロモーションを含むことがあります。
はじめに
Rust製の最適制御向け最適化ライブラリOpEnに入門するためチュートリアルの非線形計画問題を解いたので、備忘録を兼ねてまとめた。
Opengen basics · OpEn
OpEnは非凸最適化問題を解くためのライブラリである。
PANOC (Proximal-Averaged Newton-type method for Optimal Control) という最適化手法が実装されている。
最適化問題のソースコードをRustで出力・コンパイルして解くため、計算の実行速度は速い。
また、OpEnはPythonやMATLABのインターフェイスを備えているため、Rustの知識がなくても利用できる。
環境
本記事ではOpEnのインターフェイスはPython+CasADiとした。
環境は以下の通り。また、OSはWindows 10である。
- Rust 1.55.0
- Python 3.8.8
- opengen 0.6.9
- OpEn 0.7.1
- CasADi 3.5.5
2022/01/30追記 opengen v0.6.8以前ではPythonからOpEnを実行するとエラーが発生します。
最適制御向け最適化ライブラリOpEnのRust build of TCP interface failedエラーについて – Helve Tech Blog
OpEnのインストール方法は以下の記事を参照。
Rust製最適化ライブラリOpEnのインストール – Helve Tech Blog
また、CasADiは以下でインストールできる。
|
|
最適化問題の定義
ここからはチュートリアルの問題に沿って進める。
まず、CasADiとopengenをインポートする。
|
|
次に、変数と目的関数を定義する。目的関数はRosenbrock関数である。
$$\phi(u) = \sum_{i=0}^{4} \left\{ p_1 (u_{i+1}-u_i^2)^2 + (p_0 - u_i)^2 \right\}$$
|
|
u
は変数、p
はパラメータである。パラメータは最適化計算の実行時に指定する。
なお、OpEnは最適化制御を解くために開発されたため、制御工学で入力を表す記号u
を未知変数としていると思われる。
phi
は目的関数である。ここでは用意された関数og.functions.rosenbrock
を使っているが、自分で定義することも可能である。
例:
|
|
さらに、制約条件を定義する。
$$ u_1^2 + u_2^2 < 1.5^2, \\ -1 < u_3 < 0, -2 < u_4 < 10, -3 < u_5 < -1, $$
|
|
Ball2(None, 1.5)
は半径1.5の超球内に変数を収める制約である。最初の引数でNone
の代わりに数値を入れると、球の中心を指定できる。
Rectangle(xmin, xmax)
は最小値、最大値を指定する制約である。
また、segment_ids
で制約式を付加する変数のインデックスを指定している。
ビルドとソルバの設定
生成されるオプティマイザのメタ情報を設定する(省略可能)。
|
|
生成されたソースコードをRustでビルドときの設定を指定する。
with_build_mode
は"debug"
または"release"
を指定できる。"release"
を指定するとビルドは遅くなるが、最適化の実行は速くなる。
また、.with_tcp_interface_config
はソルバをPythonまたはMATLABから呼び出すときに必要。
|
|
ソルバの設定を行う。
|
|
最適化問題、メタ情報、ビルドとソルバの設定をbuilder
にまとめる。
|
|
最適化計算の実行
PythonとオプティマイザはTCPで通信するため、TCPサーバを起動する。
|
|
OptimizerTcpManager
には、meta
とbuild_config
で指定したオプティマイザのパスを指定する。
TCPサーバとの通信が確立できれば、print(pong)
で{'Pong': 1}
と表示される。
次に、最適化計算を実行する。call
にはパラメータの値を指定する。
|
|
最適化の結果を確認する。
|
|
response.get()
で最適化の結果が得られる。主なプロパティは以下の通り。
プロパティ | 説明 |
---|---|
solution |
最適解 |
exit_status |
状態(Converged など) |
solve_time_ms |
実行時間(ミリ秒) |
cost |
評価関数の値 |
num_outer_iterations |
反復回数 |
最後にTCPサーバを停止する。
|
|
最適化結果の確認
最後に、最適化結果を確認する。
|
|
u_star
は最適解である。また、計算時間は3.0322ミリ秒であった。