Main Content

求解基于问题的非线性可行性问题

此示例说明如何找到满足问题中所有约束的点,而无需最小化目标函数。

问题定义

假设您有以下约束:

(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,其中包含字段 xy

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.

<stopping criteria details>
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: '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.↵↵<stopping criteria details>↵↵Optimization completed: The relative first-order optimality measure, 0.000000e+00,↵is less than options.OptimalityTolerance = 1.000000e-06, and the relative maximum constraint↵violation, 0.000000e+00, is less than options.ConstraintTolerance = 1.000000e-06.'
            bestfeasible: [1×1 struct]
     objectivederivative: "closed-form"
    constraintderivative: "forward-AD"
                  solver: 'fmincon'

求解器找到一个可行点。

起点的重要性

从某些初始点开始时,求解器可能无法找到解。设定初始点 x0.x = –1x0.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 the size of the current step is less than
the value of the step size tolerance but constraints are not
satisfied to within the value of the constraint tolerance.

<stopping criteria details>

Consider enabling the interior point method feasibility mode.
sol2 = struct with fields:
    x: -2.1266
    y: -4.6657

exitflag2 = 
    NoFeasiblePointFound

output2 = struct with fields:
              iterations: 129
               funcCount: 283
         constrviolation: 1.4609
                stepsize: 1.3726e-10
               algorithm: 'interior-point'
           firstorderopt: 0
            cgiterations: 265
                 message: 'Converged to an infeasible point.↵↵fmincon stopped because the size of the current step is less than↵the value of the step size tolerance but constraints are not↵satisfied to within the value of the constraint tolerance.↵↵<stopping criteria details>↵↵Optimization stopped because the relative changes in all elements of x are↵less than options.StepTolerance = 1.000000e-10, but the relative maximum constraint↵violation, 1.521734e-01, exceeds options.ConstraintTolerance = 1.000000e-06.'
            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

cons1cons3 在解 sol2 处都是不可行的。结果强调了使用多个起点来调查和求解可行性问题的重要性。

可视化约束

为了可视化约束,使用 fimplicit 绘制每个约束函数为零的点。fimplicit 函数将数值传递给其函数,而 evaluate 函数需要结构。要将这些函数绑定在一起,请使用 evaluateExpr 辅助函数,它出现在本示例的末尾。此函数只是将传递的值放入具有适当名称的结构中。

注意:确保 evaluateExpr 辅助函数的代码包含在脚本末尾或路径上的文件中。

避免由于 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 object. The axes object 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

另请参阅

相关主题