2012-05-02 14 views
3

私の日常的な仕事の中で、私はfminsearchを使って特定の関数を最大にしなければなりません。コードは次のとおりです。fminsearchで関数を最大化

clc 
clear all 
close all 

f = @(x,c,k) -(x(2)/c)^3*(((exp(-(x(1)/c)^k)-exp(-(x(2)/c)^k))/((x(2)/c)^k-(x(1)/c)^k))-exp(-(x(3)/c)^k))^2; 
c = 10.1; 
k = 2.3; 
X = fminsearch(@(x) f(x,c,k),[4,10,20]); 

私は期待どおりそれは、正常に動作しますが、問題が来ているではない:私は一定の範囲内でバウンドXに必要な、よう:

4 < x(1) < 5 
10 < x(2) < 15 
20 < x(3) < 30 

適切な結果を達成するために私は残念ながら手にすることのできない最適化ツールボックスを使うべきです。

fminsearchだけを使用して同じ分析を行う方法はありますか?

答えて

2

ファイル交換からfminsearchbndをダウンロードしたい場合は、fminsearchを直接使用しないでください。 fminsearchbndは、一般目的関数の束縛された最小限の制約を、fminsearchのオーバーレイとして実行します。それはあなたのためにfminsearchを呼び出し、問題に限界を適用します。

本質的に、あなたの目的関数が拘束された問題を解決しているかのようにあなたの問題を変換することです。それは完全に透明です。関数、パラメータ空間の開始点、下限と上限のセットを使用してfminsearchbndを呼び出します。

たとえば、rosenbrock関数を最小化すると、fminsearchによって[1,1]に最小値が返されます。しかし、各変数に対して2の問題に対して純粋に下限を適用すると、fminsearchbndは[2,4]で束縛された制約付き解を見つけます。あなたは、変数には制約がない場合は

rosen = @(x) (1-x(1)).^2 + 105*(x(2)-x(1).^2).^2; 

fminsearch(rosen,[3 3])  % unconstrained 
ans = 
    1.0000 1.0000 

fminsearchbnd(rosen,[3 3],[2 2],[])  % constrained 
ans = 
    2.0000 4.0000 

、それに対応するバウンドとして-infやinfファイルを提供します。

fminsearchbnd(rosen,[3 3],[-inf 2],[]) 
ans = 
     1.4137   2 
1

xをバインドする最も素朴な方法は、範囲内にないxに対して大きなペナルティを与えます。例えば

function res = f(x,c,k) 
     if x(1)>5 || x(1)<4 
      penalty = 1000000000000; 
     else 
      penalty = 0; 
     end 
     res = penalty - (x(2)/c)^3*(((exp(-(x(1)/c)^k)-exp(-(x(2)/c)^k))/((x(2)/c)^k-(x(1)/c)^k))-exp(-(x(3)/c)^k))^2; 
    end 

あなたはよりスムーズな方法でペナルティを与えることによって、このアプローチを向上させることができます。

1

アンドレイは正しい考えを持っており、ペナルティを提供するスムーズな方法が難しいことではありません。ただ方程式に距離を追加します。

匿名関数使用して保持するには:

f = @(x,c,k, Xmin, Xmax) -(x(2)/c)^3*(((exp(-(x(1)/c)^k)-exp(-(x(2)/c)^k))/((x(2)/c)^k-(x(1)/c)^k))-exp(-(x(3)/c)^k))^2 ... 
+ (x< Xmin)*(Xmin' - x' + 10000) + (x>Xmax)*(x' - Xmax' + 10000) ;