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

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

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

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

(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]
     objectivederivative: "closed-form"
    constraintderivative: "forward-AD"
                  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: 140
               funcCount: 299
         constrviolation: 1.4609
                stepsize: 1.5248e-10
               algorithm: 'interior-point'
           firstorderopt: 0
            cgiterations: 281
                 message: '...'
            bestfeasible: []
     objectivederivative: "closed-form"
    constraintderivative: "forward-AD"
                  solver: 'fmincon'

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

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

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

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

Чтобы визуализировать ограничения, постройте график точек, где каждая функция ограничений равна нулю, используя fimplicit. The 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

Figure contains an axes. The axes contains 3 objects of type implicitfunctionline.

warning(s);

Допустимая область находится внутри красного контура и ниже черно-синих линий. Допустимая область находится в нижнем правом углу красного контура.

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

Этот код создает evaluateExpr вспомогательная функция.

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

См. также

Похожие темы