このページは、nAGライブラリのJupyterノートブックExampleの日本語翻訳版です。オリジナルのノートブックはインタラクティブに操作することができます。
グローバル最適化
関数の絶対的な最大値または最小値を見つけることは難しい場合があります。数十個の変数と境界制約のみを持つ問題に対しては、nAGソルバーglopt.bnd_mcs_solve
(Huyer
and Neumaierによるマルチレベル座標探索)が効果的なルーチンです。
glopt.bnd_mcs_solve
の簡単なデモンストレーションとして、2次元の’peaks’関数のグローバル最小値を見つけます。この関数は(ソルバーのobjfun
引数に適した形式で)以下のようになります:
from math import exp
= lambda x, _nstate: (
objfun 3.*(1. - x[0])**2*exp(-x[0]**2 - (x[1] + 1.)**2)
- (10.*(x[0]/5. - x[0]**3 - x[1]**5)*exp(-x[0]**2 - x[1]**2))
- 1./3.0*exp(-(x[0] + 1.)**2 - x[1]**2)
)
最適化はボックス
= 2
n = [-3.]*n
bl = [3.]*n bu
ibound
引数は、境界を明示的に自分たちで提供していることをソルバーに伝えます。
= 0 ibound
このサンプルのプロットは、オプティマイザーが反復処理を行う際に考慮する探索ボックスを表示します。関数のモニタリングコールバックを使用して、訪れたボックスを保存することができます
from matplotlib.patches import Rectangle
= []
boxes
def monit(
_ncall, _xbest, _icount, _inlist, _numpts,
_initpt, _xbaskt, boxl, boxu, _nstate,
):*(boxu - boxl))) boxes.append(Rectangle(boxl,
オプティマイザーを呼び出す前に、その通信状態を初期化する必要があります
from naginterfaces.library import glopt
= glopt.bnd_mcs_init() comm
/tmp/ipykernel_709387/730370878.htm:2: NagDeprecatedWarning: (nAG Python function naginterfaces.library.glopt.bnd_mcs_init)
This function is deprecated.
There is no replacement for this routine.
comm = glopt.bnd_mcs_init()
最適化を実行します。モニタリング関数はオプションのキーワード引数です。この例では、返されるデータにアクセスする必要はありません。
= glopt.bnd_mcs_solve(objfun, ibound, bl, bu, comm, monit=monit) _
/tmp/ipykernel_709387/1372224297.htm:1: NagDeprecatedWarning: (nAG Python function naginterfaces.library.glopt.bnd_mcs_solve)
This function is deprecated.
The following advice is given for making a replacement:
Please use handle_solve_mcs instead.
See also https://www.nag.com/numeric/py/nagdoc_latest/replace.html
_ = glopt.bnd_mcs_solve(objfun, ibound, bl, bu, comm, monit=monit)
プロット用に目的関数をグリッド化する
import numpy as np
= 0.025
delta = np.arange(bl[0], bu[0], delta)
x = np.arange(bl[1], bu[1], delta)
y = np.meshgrid(x, y)
X, Y = np.empty((len(X), len(Y)))
Z for i, x_i in enumerate(x):
for j, y_j in enumerate(y):
= objfun([x_i, y_j], None) Z[j, i]
最適化の開始点と終了点をプロットに含めるために保存します。ルーチンのデフォルトの’simple’初期化方法(iinit = 0
)では、開始点(initpt
)は原点にありました
= [0.]*n start_x
以下は問題の既知の大域的最小値です
= [0.23, -1.63] min_x
後続のプロットに含める検索ボックスを集計する
from matplotlib.collections import PatchCollection
= PatchCollection(
boxes_col
boxes,='b', facecolor='none', linewidth=0.2,
edgecolor )
# Jupyter の表示バックエンドを選択:
%matplotlib inline
プロットを組み立てる
from matplotlib import cm
import matplotlib.pyplot as plt
= plt.axes()
ax
ax.contour(
X, Y, Z,=[-6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 6, 8],
levels=cm.jet,
cmap
)0], start_x[1], 'rx')
ax.plot(start_x[0], min_x[1], 'go')
ax.plot(min_x['Start', 'Glob. min.'), loc='upper right')
ax.legend((
ax.add_collection(boxes_col)=bl[0], ymin=bl[1], xmax=bu[0], ymax=bu[1])
ax.axis(xminr'The Peaks Function and MCS Search Boxes')
ax.set_title( plt.show()