В этом примере показано, как найти точку, которая удовлетворяет всем ограничениям в проблеме без целевой функции, чтобы минимизировать.
Например, предположите, что у вас есть следующие ограничения:
Сделайте любые точки удовлетворить всем ограничениям?
Создайте задачу оптимизации, которая имеет только ограничения, никакую целевую функцию.
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'
Проверяйте 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
Основанный на проблеме рабочий процесс оптимизации