Почему MATLAB fmincon игнорирует нелинейные ограничения? - PullRequest
0 голосов
/ 04 мая 2019

Я хочу использовать функцию fmincon MATLABs для решения нелинейной задачи, о которой я знаю, что ее очень легко решить другим способом, но я хочу использовать fmincon (вам может не потребоваться следующая подробная информация о проблемено я предоставил их на всякий случай):

Функция f (x) - это квадратичная функция с вершиной в точке (5 | 1).

f(x)=0.1(x-5)^2+1 for 0<=x<=5

Функция g (x) является полиномом порядка 4 с вершиной в точке (c | 0).

g(x)=(x-c)^4 for 0<=x<=c

Функция h - это просто линия на оси x.

h=0 for c<=x<=5

image of the graphs

Я хочу минимизировать Площадь между функцией f (x) и двумя связанными функциями g (x)) и h, в интервале [0,5]

minimize A=2*(int(f,[0,5])-int(g,[0,c]))=55/3 - (2*c^5)/5

Также у меня есть ограничение, что f (x) всегда должна быть на 1 единицу выше функций g (x) иh.

Из графика я знаю, что переменная c должна быть между 0 и 2 (просто диапазон для функции fmincon).

Это мой файл .m:

clc
clear

format long;
options = optimoptions(@fmincon, 'Display', 'iter', 'Algorithm', 'interior-point');

fun=@(x)55/3 - (2*(x(1))^5)/5;

lb = [0];
ub = [2];

[x,fval] = fmincon(fun,[0.1],[],[],[],[],lb,ub,@cons_Q6,options)

Файл ограничений выглядит следующим образом (я вставил много значений для x с шагом 0,1):

function [c,ceq]=cons_Q6(x)
c=[(0.0-x(1))^4-0.1*(0.0-5)^2
(0.1-x(1))^4-0.1*(0.1-5)^2
(0.2-x(1))^4-0.1*(0.2-5)^2
(0.3-x(1))^4-0.1*(0.3-5)^2
(0.4-x(1))^4-0.1*(0.4-5)^2
(0.5-x(1))^4-0.1*(0.5-5)^2
(0.6-x(1))^4-0.1*(0.6-5)^2
(0.7-x(1))^4-0.1*(0.7-5)^2
(0.8-x(1))^4-0.1*(0.8-5)^2
(0.9-x(1))^4-0.1*(0.9-5)^2
(1.0-x(1))^4-0.1*(1.0-5)^2
(1.1-x(1))^4-0.1*(1.1-5)^2
(1.2-x(1))^4-0.1*(1.2-5)^2
(1.3-x(1))^4-0.1*(1.3-5)^2
(1.4-x(1))^4-0.1*(1.4-5)^2
(1.5-x(1))^4-0.1*(1.5-5)^2
(1.6-x(1))^4-0.1*(1.6-5)^2
(1.7-x(1))^4-0.1*(1.7-5)^2
(1.8-x(1))^4-0.1*(1.8-5)^2
(1.9-x(1))^4-0.1*(1.9-5)^2
(2.0-x(1))^4-0.1*(2.0-5)^2
(2.1-x(1))^4-0.1*(2.1-5)^2
(2.2-x(1))^4-0.1*(2.2-5)^2
(2.3-x(1))^4-0.1*(2.3-5)^2
(2.4-x(1))^4-0.1*(2.4-5)^2
(2.5-x(1))^4-0.1*(2.5-5)^2
(2.6-x(1))^4-0.1*(2.6-5)^2
(2.7-x(1))^4-0.1*(2.7-5)^2
(2.8-x(1))^4-0.1*(2.8-5)^2
(2.9-x(1))^4-0.1*(2.9-5)^2
(3.0-x(1))^4-0.1*(3.0-5)^2
(3.1-x(1))^4-0.1*(3.1-5)^2
(3.2-x(1))^4-0.1*(3.2-5)^2
(3.3-x(1))^4-0.1*(3.3-5)^2
(3.4-x(1))^4-0.1*(3.4-5)^2
(3.5-x(1))^4-0.1*(3.5-5)^2
(3.6-x(1))^4-0.1*(3.6-5)^2
(3.7-x(1))^4-0.1*(3.7-5)^2
(3.8-x(1))^4-0.1*(3.8-5)^2
(3.9-x(1))^4-0.1*(3.9-5)^2
(4.0-x(1))^4-0.1*(4.0-5)^2
(4.1-x(1))^4-0.1*(4.1-5)^2
(4.2-x(1))^4-0.1*(4.2-5)^2
(4.3-x(1))^4-0.1*(4.3-5)^2
(4.4-x(1))^4-0.1*(4.4-5)^2
(4.5-x(1))^4-0.1*(4.5-5)^2
(4.6-x(1))^4-0.1*(4.6-5)^2
(4.7-x(1))^4-0.1*(4.7-5)^2
(4.8-x(1))^4-0.1*(4.8-5)^2
(4.9-x(1))^4-0.1*(4.9-5)^2
(5.0-x(1))^4-0.1*(5.0-5)^2
];
ceq=[];

Как видите, я установил границы для неизвестногопеременная, так что x(1)=[0,2] и я установил ограничения в диапазоне [0,5], хотя они мне понадобятся только в диапазоне [0,2] из-за ограничений для x (1).Теперь, когда я решаю это таким образом, я получаю решение, которое не соответствует всем ограничениям.Но когда я удаляю ненужные ограничения в диапазоне] 2; 5]

function [c,ceq]=cons_Q6(x)
c=[(0.0-x(1))^4-0.1*(0.0-5)^2
(0.1-x(1))^4-0.1*(0.1-5)^2
(0.2-x(1))^4-0.1*(0.2-5)^2
(0.3-x(1))^4-0.1*(0.3-5)^2
(0.4-x(1))^4-0.1*(0.4-5)^2
(0.5-x(1))^4-0.1*(0.5-5)^2
(0.6-x(1))^4-0.1*(0.6-5)^2
(0.7-x(1))^4-0.1*(0.7-5)^2
(0.8-x(1))^4-0.1*(0.8-5)^2
(0.9-x(1))^4-0.1*(0.9-5)^2
(1.0-x(1))^4-0.1*(1.0-5)^2
(1.1-x(1))^4-0.1*(1.1-5)^2
(1.2-x(1))^4-0.1*(1.2-5)^2
(1.3-x(1))^4-0.1*(1.3-5)^2
(1.4-x(1))^4-0.1*(1.4-5)^2
(1.5-x(1))^4-0.1*(1.5-5)^2
(1.6-x(1))^4-0.1*(1.6-5)^2
(1.7-x(1))^4-0.1*(1.7-5)^2
(1.8-x(1))^4-0.1*(1.8-5)^2
(1.9-x(1))^4-0.1*(1.9-5)^2
(2.0-x(1))^4-0.1*(2.0-5)^2
];
ceq=[];

, тогда я получаю правильный результат.Кто-нибудь знает, почему это происходит и почему MATLAB не соблюдает ограничения, когда я выставляю их для всего диапазона [0,5]? ​​

1 Ответ

1 голос
/ 04 мая 2019
   -Your problem is more related to calculus than matlab tool
   constraints like 
   function [c]=cons_Q6(x)
   c=[x < 0; x > 0]; are just ignored by fmincon, because they are not logical 

   Technically you need to know the optimum c before solving 
   this optimization problem


   - Another issue A = int(f,[0,5])-int(g,[0,c]) = 55/6 - c^5/5 instead of 
                   A = 2*(int(f,[0,5])-int(g,[0,c])) = 55/3 - (2*c^5)/5

   Factor 2 is used whether for even whether for odd function (like cosine or since). 
   Even for those kind of function the integration interval is reduced by half

I updated your optimization function and the solution c is as follow

x = [0, c], constraint is g(x)-f(x)-1<= 0--> (x-c)^4 -0.1(x-5)^2 <=0
x = [c, 5], constraint is h(x)-f(x)-1<= 0--> -0.1(x-5)^2 <=0

c must be predefined or guessed in advance, here I supposed c = 2 
because your upper bound ub = 2

В результате

x = [0, 2], --> (x-c)^4 -0.1(x-5)^2 <=0
x = [2, 5], --> -0.1(x-5)^2 <=0

cons_Q6 (x) выглядит следующим образом

function [c,ceq]=cons_Q6(x)
c=[(0.0-x)^4-0.1*(0.0-5)^2;
(0.1-x)^4-0.1*(0.1-5)^2;
(0.2-x)^4-0.1*(0.2-5)^2;
(0.3-x)^4-0.1*(0.3-5)^2;
(0.4-x)^4-0.1*(0.4-5)^2;
(0.5-x)^4-0.1*(0.5-5)^2;
(0.6-x)^4-0.1*(0.6-5)^2;
(0.7-x)^4-0.1*(0.7-5)^2;
(0.8-x)^4-0.1*(0.8-5)^2;
(0.9-x)^4-0.1*(0.9-5)^2;
(1.0-x)^4-0.1*(1.0-5)^2;
(1.1-x)^4-0.1*(1.1-5)^2;
(1.2-x)^4-0.1*(1.2-5)^2;
(1.3-x)^4-0.1*(1.3-5)^2;
(1.4-x)^4-0.1*(1.4-5)^2;
(1.5-x)^4-0.1*(1.5-5)^2;
(1.6-x)^4-0.1*(1.6-5)^2;
(1.7-x)^4-0.1*(1.7-5)^2;
(1.8-x)^4-0.1*(1.8-5)^2;
(1.9-x)^4-0.1*(1.9-5)^2;
(2.0-x)^4-0.1*(2.0-5)^2;
-0.1*(2.1-5)^2;
-0.1*(2.2-5)^2;
-0.1*(2.3-5)^2;
-0.1*(2.4-5)^2;
-0.1*(2.5-5)^2;
-0.1*(2.6-5)^2;
-0.1*(2.7-5)^2;
-0.1*(2.8-5)^2;
-0.1*(2.9-5)^2;
-0.1*(3.0-5)^2;
-0.1*(3.1-5)^2;
-0.1*(3.2-5)^2;
-0.1*(3.3-5)^2;
-0.1*(3.4-5)^2;
-0.1*(3.5-5)^2;
-0.1*(3.6-5)^2;
-0.1*(3.7-5)^2;
-0.1*(3.8-5)^2;
-0.1*(3.9-5)^2;
-0.1*(4.0-5)^2;
-0.1*(4.1-5)^2;
-0.1*(4.2-5)^2;
-0.1*(4.3-5)^2;
-0.1*(4.4-5)^2;
-0.1*(4.5-5)^2;
-0.1*(4.6-5)^2;
-0.1*(4.7-5)^2;
-0.1*(4.8-5)^2;
-0.1*(4.9-5)^2;
-0.1*(5.0-5)^2;
];

ceq=[];

The constraints in the range ]2;5] are very necessary keep them

clc
clear

format long;
options = optimoptions(@fmincon, 'Display', 'iter', 'Algorithm',... 
'interior-point');

fun=@(x)55/6 - (x^5)/5;

lb = [0];
ub = [2];

[c, A] = fmincon(fun,[0.1],[],[],[],[],lb,ub,@cons_Q6,options)

решение:

c = 1.257432726024430


A = 8.537951710969493
...