Решите нелинейную задачу выполнимости, основанную на проблеме

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

Описание задачи

Например, предположите, что у вас есть следующие ограничения:

(y+x2)2+0.1y21yexp(-x)-3yx-4.

Сделайте любые точки (x,y) удовлетворить всем ограничениям?

Основанное на проблеме решение

Создайте задачу оптимизации, которая имеет только ограничения, никакую целевую функцию.

x = optimvar('x');
y = optimvar('y');
prob = optimproblem;
cons1 = (y + x^2)^2 + 0.1*y^2 <= 1;
cons2 = y <= exp(-x) - 3;
cons3 = y <= x - 4;
prob.Constraints.cons1 = cons1;
prob.Constraints.cons2 = cons2;
prob.Constraints.cons3 = cons3;
show(prob)
  OptimizationProblem : 

	Solve for:
       x, y

	minimize :

	subject to cons1:
       ((y + x.^2).^2 + (0.1 .* y.^2)) <= 1

	subject to cons2:
       y <= (exp(-x) - 3)

	subject to cons3:
       y - x <= -4
     

Создайте псевдослучайную структуру стартовой точки x0 с полями x и y для переменных оптимизации.

rng default
x0.x = randn;
x0.y = randn;

Решите задачу, начинающую с x0.

[sol,~,exitflag,output] = solve(prob,x0)
Solving problem using fmincon.

Local minimum found that satisfies the constraints.

Optimization completed because the objective function is non-decreasing in 
feasible directions, to within the value of the optimality tolerance,
and constraints are satisfied to within the value of the constraint tolerance.
sol = struct with fields:
    x: 1.7903
    y: -3.0102

exitflag = 
    OptimalSolution

output = struct with fields:
         iterations: 6
          funcCount: 9
    constrviolation: 0
           stepsize: 0.2906
          algorithm: 'interior-point'
      firstorderopt: 0
       cgiterations: 0
            message: '...'
       bestfeasible: [1x1 struct]
             solver: 'fmincon'

Решатель находит допустимую точку.

Начальная важность точки

Решатель может не найти решение при запуске с некоторых начальных точек. Установите начальную точку x0.x = -1, x0.y = -4 и решите задачу, начинающую с x0.

x0.x = -1;
x0.y = -4;
[sol2,~,exitflag2,output2] = solve(prob,x0)
Solving problem using fmincon.

Converged to an infeasible point.

fmincon stopped because it is unable to find a point locally that satisfies
the constraints within the value of the constraint tolerance.
sol2 = struct with fields:
    x: -2.1266
    y: -4.6657

exitflag2 = 
    NoFeasiblePointFound

output2 = struct with fields:
         iterations: 121
          funcCount: 279
    constrviolation: 1.4609
           stepsize: 1.9997e-10
          algorithm: 'interior-point'
      firstorderopt: 0
       cgiterations: 261
            message: '...'
       bestfeasible: []
             solver: 'fmincon'

Проверяйте infeasibilities в возвращенной точке.

inf1 = infeasibility(cons1,sol2)
inf1 = 1.1974
inf2 = infeasibility(cons2,sol2)
inf2 = 0
inf3 = infeasibility(cons3,sol2)
inf3 = 1.4609

Оба cons1 и cons3 неосуществимы в решении sol2. Результаты подсвечивают важность использования нескольких стартовых точек, чтобы исследовать и решить задачу выполнимости.

Визуализируйте ограничения

Чтобы визуализировать ограничения, постройте точки, где каждая ограничительная функция является нулем при помощи fimplicit. fimplicit функционируйте передает числовые значения его функциям, тогда как evaluate функция требует структуры. Чтобы связать эти функции, используйте evaluateExpr функция помощника, которая появляется в конце этого примера. Эта функция просто помещает переданные значения в структуру с соответствующими именами.

Примечание: Если вы используете файл live скрипта для этого примера, evaluateExpr функция уже включена в конце файла. В противном случае необходимо создать эту функцию в конце.m файла или добавить его как файл на пути MATLAB®.

Избегайте предупреждения, которое происходит потому что evaluateExpr функция не работает над векторизованными входными параметрами.

s = warning('off','MATLAB:fplot:NotVectorized');
cc1 = (y + x^2)^2 + 0.1*y^2 - 1;
fimplicit(@(a,b)evaluateExpr(cc1,a,b),[-2 2 -4 2],'r')
hold on
cc2 = y - exp(-x) + 3;
fimplicit(@(a,b)evaluateExpr(cc2,a,b),[-2 2 -4 2],'k')
cc3 = y - x + 4;
fimplicit(@(x,y)evaluateExpr(cc3,x,y),[-2 2 -4 2],'b')
hold off

warning(s);

Выполнимая область в красной схеме и ниже в синяках линии. Выполнимая область в нижнем правом углу красной схемы.

Функция помощника

Этот код создает evaluateExpr функция помощника.

function p = evaluateExpr(expr,x,y)
pt.x = x;
pt.y = y;
p = evaluate(expr,pt);
end

Смотрите также

Похожие темы