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