2012-05-02 2 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]); 

Он отлично работает, как я ожидал, но не проблема придумывает: мне нужно грань х в определенных пределах, как:

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

Для достижения соответствующих результатов , Я должен использовать панель инструментов оптимизации, которую я, к сожалению, не могу передать.

Есть ли способ получить такой же анализ, используя только fminsearch?

ответ

2

Ну, не используя fminsearch напрямую, но если вы хотите скачать fminsearchbnd из обмена файлами, то да. fminsearchbnd выполняет ограниченную ограниченную минимизацию общей целевой функции в качестве наложения на fminsearch. Он вызывает fminsearch для вас, применяя ограничения на проблему.

По сути, идея состоит в том, чтобы превратить вашу проблему в вашу задачу таким образом, чтобы ваша целевая функция воспринимала, как будто она решает ограниченную проблему. Это абсолютно прозрачно. Вы вызываете fminsearchbnd с функцией, начальной точкой в ​​пространстве параметров и набором нижних и верхних границ.

Например, минимизация функции rosenbrock возвращает минимум в [1,1] с помощью fminsearch. Но если мы применяем чисто нижние оценки к задаче 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 или инф как соответствующая оценка.

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) ; 
Смежные вопросы