Main Content

このページは機械翻訳を使用して翻訳されました。元の英語を参照するには、ここをクリックします。

パターン検索を使用した目的関数のコーディングと最小化

この例では、パターン検索を使用して目的関数を作成し、最小化する方法を示します。

目的関数

この問題では、最小化する目的関数は 2 次元変数 x の単純な関数です。

simple_objective(x) = (4 - 2.1*x(1)^2 + x(1)^4/3)*x(1)^2 + x(1)*x(2) + (-4 + 4*x(2)^2)*x(2)^2;

この機能は、L.C.W. DixonとG.P. Szego [1]で説明されているように、「カム」として知られています。

目的関数をコード化する

次のコードを含む simple_objective.m という名前の MATLAB® ファイルを作成します。

type simple_objective
function y = simple_objective(x)
%SIMPLE_OBJECTIVE Objective function for PATTERNSEARCH solver

%   Copyright 2004 The MathWorks, Inc.  

x1 = x(1);
x2 = x(2);
y = (4-2.1.*x1.^2+x1.^4./3).*x1.^2+x1.*x2+(-4+4.*x2.^2).*x2.^2;

patternsearch などのソルバーは単一の入力 x を受け入れます。ここで、x には問題内の変数の数と同じ数の要素があります。目的関数は、目的関数のスカラー値を計算し、それを単一の出力引数 y で返します。

patternsearch を使用して最小化

目的関数を関数ハンドルとして指定します。

ObjectiveFunction = @simple_objective;

ソルバーの初期ポイントを指定します。

x0 = [0.5 0.5];   % Starting point

最適点 x と最適点 fval における関数値を要求して、ソルバーを呼び出します。

[x,fval] = patternsearch(ObjectiveFunction,x0)
Optimization terminated: mesh size less than options.MeshTolerance.
x = 1×2

   -0.0898    0.7127

fval = -1.0316

追加引数の使用を最小限に抑える

場合によっては、目的関数に、最適化中に定数として機能する追加の引数が含まれることがあります。たとえば、simple_objective では、定数 4、2.1、および 4 を変数パラメーターとして指定して、目的関数のファミリを作成することができます。

simple_objective を書き直して、最適化中に定数として機能する 3 つの追加パラメーター (p1p2、および p3) を取得します (これらは最小化の一部として変更されません)。目的関数の計算を実装するために、MATLAB ファイル parameterized_objective.m には次のコードが含まれています。

type parameterized_objective
function y = parameterized_objective(x,p1,p2,p3)
%PARAMETERIZED_OBJECTIVE Objective function for PATTERNSEARCH solver

%   Copyright 2004 The MathWorks, Inc.
  
x1 = x(1);
x2 = x(2);
y = (p1-p2.*x1.^2+x1.^4./3).*x1.^2+x1.*x2+(-p3+p3.*x2.^2).*x2.^2;

patternsearch は、 x という 1 つの引数のみを使用して目的関数を呼び出しますが、パラメーター化された目的関数には、 xp1p2、および p3 という 4 つの引数があります。匿名関数を使用して、追加の引数 p1p2、および p3 の値を取得します。1 つの入力 x を受け取り、xp1p2、および p3 を使用して parameterized_objective を呼び出す匿名関数への関数ハンドル ObjectiveFunction を作成します。関数ハンドル ObjectiveFunction を作成すると、変数 p1p2、および p3 には匿名関数に格納される値が設定されます。詳細については、追加パラメーターの受け渡し を参照してください。

p1 = 4; p2 = 2.1; p3 = 4;    % Define constant values
ObjectiveFunction = @(x) parameterized_objective(x,p1,p2,p3);
[x,fval] = patternsearch(ObjectiveFunction,x0)
Optimization terminated: mesh size less than options.MeshTolerance.
x = 1×2

   -0.0898    0.7127

fval = -1.0316

目的関数をベクトル化する

デフォルトでは、patternsearch は一度に 1 つのポイントを目的関数に渡します。場合によっては、目的関数を ベクトル化 して点のセットを取得し、関数値のセットを返すことで、ソルバーを高速化できます。

たとえば、ソルバーが目的関数を 1 回呼び出して 5 つのポイントのセットを評価するには、ソルバーは 5 行 2 列のサイズのマトリックス (2 は変数の数) で目的関数を呼び出します。詳細については、目的関数と制約関数をベクトル化する を参照してください。

parameterized_objective をベクトル化するには、次のコードを使用します。

type vectorized_objective
function y = vectorized_objective(x,p1,p2,p3)
%VECTORIZED_OBJECTIVE Objective function for PATTERNSEARCH solver

%   Copyright 2004-2018 The MathWorks, Inc.

x1 = x(:,1); % First column of x
x2 = x(:,2);
y = (p1 - p2.*x1.^2 + x1.^4./3).*x1.^2 + x1.*x2 + (-p3 + p3.*x2.^2).*x2.^2;

この目的関数のベクトル化されたバージョンは、任意の数の点(xの行)を持つ行列xを受け取り、長さがxの行数である列ベクトルyを返します。

ベクトル化された目的関数を活用するには、UseVectorized オプションを true に設定し、UseCompletePoll オプションを true に設定します。patternsearch では、ベクトル化された方法で計算するために、これら両方のオプションが必要です。

options = optimoptions(@patternsearch,'UseVectorized',true,'UseCompletePoll',true);

目的関数を指定し、options 引数を含めて patternsearch を呼び出します。tic/toc を使用して解決時間を評価します。

ObjectiveFunction = @(x) vectorized_objective(x,4,2.1,4);
tic
[x,fval] = patternsearch(ObjectiveFunction,x0,[],[],[],[],[],[],[],options)
Optimization terminated: mesh size less than options.MeshTolerance.
x = 1×2

   -0.0898    0.7127

fval = -1.0316
toc
Elapsed time is 0.027503 seconds.

比較のために、ベクトル化されていない解決時間を評価します。

tic
[x,fval] = patternsearch(ObjectiveFunction,x0)
Optimization terminated: mesh size less than options.MeshTolerance.
x = 1×2

   -0.0898    0.7127

fval = -1.0316
toc
Elapsed time is 0.027502 seconds.

この場合、ベクトル化は解析時間に大きな影響を与えません。

参照

[1] ディクソン、L.C.W.、G.P.Szego(編著)。グローバル最適化に向けて 2.北ホラント州:エルゼビアサイエンス社、アムステルダム、1978年。

関連するトピック