主要内容

本页采用了机器翻译。点击此处可查看英文原文。

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

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

问题定义

假设您有以下约束:

(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 it is unable to find a point locally that satisfies
the constraints 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: 144
               funcCount: 318
         constrviolation: 1.4609
                stepsize: 2.9443e-10
               algorithm: 'interior-point'
           firstorderopt: 0
            cgiterations: 300
                 message: '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.↵↵<stopping criteria details>↵↵Optimization stopped because the constraint violations are locally stationary ↵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

另请参阅

主题