Или вместо и ограничений

В целом решатели берут ограничения с неявной И:

Ограничения 1 И ограничения 2 И ограничения 3 выполняются.

Однако иногда вы хотите ИЛИ:

ограничение 1 ИЛИ ограничение 2 ИЛИ ограничение 3 выполнено.

Эти композиции не являются логически эквивалентными, и обычно нет способа выразить ограничения ИЛИ с точки зрения ограничений И.

Совет

К счастью, нелинейные ограничения чрезвычайно гибки. Вы получаете ограничения OR просто путем установки нелинейной функции ограничения на минимум функций ограничения.

Причина того, что вы можете задать минимум как ограничение, связана с природой Нелинейных Ограничений: вы даете их как набор функций, которые должны быть отрицательными в допустимой точке. Если ваши ограничения

F 1 (x) ≤ 0 OR F 2 (x) ≤ 0 OR F 3 (x) ≤ 0,

затем установите нелинейную функцию ограничения неравенства c (x) как:

c (x) = мин (F 1 (x), F 2 (x), F 3 (x)).

c (x) не является плавным, что является общим требованием к ограничительным функциям, из-за минимума. Тем не менее, метод часто работает.

Примечание

Вы не можете использовать обычные ограничения и линейные ограничения в ограничении OR. Вместо этого преобразуйте ограничения и линейные ограничения в нелинейные функции ограничений, как в этом примере.

Например, предположите, что Ваша выполнимая область - L-образная область: x находится в  прямоугольнике-1  <reservedrangesplaceholder4>      (1) ≤ 1,  0 ≤ <reservedrangesplaceholder3>      (2), ≤ 1 ИЛИ x находится в прямоугольнике 0  <reservedrangesplaceholder1> (1) ≤ 1,-1 ≤ <reservedrangesplaceholder0> (2) ≤ 1.

 Код для создания рисунка

Чтобы представлять прямоугольник как нелинейное ограничение, вместо как связанные ограничения, строят функцию, которая отрицательна в прямоугольнике <reservedrangesplaceholder5>  <reservedrangesplaceholder4>        (1) ≤ <reservedrangesplaceholder3>, <reservedrangesplaceholder2> ≤ <reservedrangesplaceholder1> (2) ≤ <reservedrangesplaceholder0>:

function cout = rectconstr(x,a,b,c,d)
% Negative when  x is in the rectangle [a,b][c,d]
% First check that a,b,c,d are in the correct order

if (b <= a) || (d <= c)
    error('Give a rectangle a < b, c < d')
end

cout = max([(x(1)-b),(x(2)-d),(a-x(1)),(c-x(2))]);

Следуя предписанию использования минимума нелинейных ограничительных функций, для L-образной области нелинейная ограничительная функция является:

function [c,ceq] = rectconstrfcn(x)

ceq = []; % no equality constraint
F(1) = rectconstr(x,-1,1,0,1); % one rectangle
F(2) = rectconstr(x,0,1,-1,1); % another rectangle
c = min(F); % for OR constraints

 Код для создания рисунка

Предположим, что ваша целевая функция

fun = @(x)exp(x(1)) * (4*x(1)^2 + 2*x(2)^2 + 4*x(1)*x(2) + 2*x(2) + 1);

Минимизируйте fun по L-образной области:

opts = optimoptions(@fmincon,'Algorithm','interior-point','Display','off');
x0 = [-.5,.6]; % an arbitrary guess
[xsol,fval,eflag] = fmincon(fun,x0,[],[],[],[],[],[],@rectconstrfcn,opts)
xsol =

    0.4998   -0.9996


fval =

   2.4650e-07


eflag =

     1

Очевидно, что решение xsol находится внутри L-образной области. Выходной флаг 1, что указывает на то, что xsol является локальным минимумом.

См. также

Похожие темы