Этот пример показывает, как найти точку, которая удовлетворяет всем ограничениям в задаче, без целевой функции, чтобы минимизировать.
Например, предположим, что у вас есть следующие ограничения:
Делайте все точки удовлетворить все ограничения?
Создайте задачу оптимизации, которая имеет только ограничения, нет целевой функции.
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
warning(s);
Допустимая область находится внутри красного контура и ниже черно-синих линий. Допустимая область находится в нижнем правом углу красного контура.
Этот код создает evaluateExpr
вспомогательная функция.
function p = evaluateExpr(expr,x,y) pt.x = x; pt.y = y; p = evaluate(expr,pt); end
Рабочий процесс оптимизации на основе проблем