Main Content

带约束的非线性系统

求解具有不等式约束的方程

fsolve 求解非线性方程组。但是,它不允许您包含任何约束,甚至是边界约束。那么,如何求解带约束的非线性方程组?

满足您的约束的解不一定存在。事实上,此问题可能没有任何解,哪怕是不满足约束的解。然而,有一些方法可以帮助您搜索满足约束的解。

为了说明这些方法,假设要设法求解以下方程

F1(x)=(x1+1)(10-x1)1+x221+x22+x2F2(x)=(x2+2)(20-x2)1+x121+x12+x1,

其中 x 的分量必须为非负值。这些方程有四个解:

x=(-1,-2)x=(10,-2)x=(-1,20)x=(10,20).

只有一个解满足约束,即 x = (10,20)

位于此示例末尾fbnd 辅助函数会以数值方式计算 F(x)

使用不同起点

一般情况下,包含 N 个变量、N 个方程的方程组有孤立的解,这意味着每个解都没有同为解的邻点。因此,搜索满足某些约束的解的一种方法是生成多个初始点 x0,然后从每个 x0 开始运行 fsolve

对于此示例,要寻找方程组 F(x)=0 的解,请取 10 个随机点,这些点呈正态分布,均值为 0,标准差为 100。

rng default % For reproducibility
N = 10; % Try 10 random start points
pts = 100*randn(N,2); % Initial points are rows in pts
soln = zeros(N,2); % Allocate solution
opts = optimoptions('fsolve','Display','off');
for k = 1:N
    soln(k,:) = fsolve(@fbnd,pts(k,:),opts); % Find solutions
end

列出满足约束的解。

idx = soln(:,1) >= 0 & soln(:,2) >= 0;
disp(soln(idx,:))
   10.0000   20.0000
   10.0000   20.0000
   10.0000   20.0000
   10.0000   20.0000
   10.0000   20.0000

使用不同算法

fsolve 有三种算法。每种算法可能得到不同的解。

例如,采用 x0 = [1,9] 并检查每个算法返回的解。

x0 = [1,9];
opts = optimoptions(@fsolve,'Display','off',...
    'Algorithm','trust-region-dogleg');
x1 = fsolve(@fbnd,x0,opts)
x1 = 1×2

   -1.0000   -2.0000

opts.Algorithm = 'trust-region';
x2 = fsolve(@fbnd,x0,opts)
x2 = 1×2

   -1.0000   20.0000

opts.Algorithm = 'levenberg-marquardt';
x3 = fsolve(@fbnd,x0,opts)
x3 = 1×2

    0.9523    8.9941

此处,对于同一个初始点,三种算法得到的解各不相同。都不满足约束。报告的“解”x3 甚至不是解,而只是局部平稳点。

使用带边界的 lsqnonlin

lsqnonlin 尝试最小化向量函数 F(x) 中各分量的平方和。因此,它尝试求解方程 F(x) = 0。此外,lsqnonlin 接受边界约束。

针对 lsqnonlin 构造示例问题并对其求解。

lb = [0,0];
rng default
x0 = 100*randn(2,1);
[x,res] = lsqnonlin(@fbnd,x0,lb)
Local minimum found.

Optimization completed because the size of the gradient is less than
the value of the optimality tolerance.
x = 2×1

   10.0000
   20.0000

res = 2.4783e-25

在本例中,lsqnonlin 收敛于满足约束的解。您可以结合使用 lsqnonlin 和 Global Optimization Toolbox MultiStart 求解器,自动基于多个初始点进行搜索。请参阅MultiStart Using lsqcurvefit or lsqnonlin (Global Optimization Toolbox)

将方程和不等式设置为 fmincon 约束

您可以按照以下方式重新表示问题并使用 fmincon

  • 给出常数目标函数,如 @(x)0,该函数对每个 x 的计算结果为 0。

  • fsolve 目标函数设置为 fmincon 中的非线性等式约束。

  • 以通常的 fmincon 语法给出任何其他约束。

此示例末尾fminconstr 辅助函数实现非线性约束。求解约束问题。

lb = [0,0]; % Lower bound constraint
rng default % Reproducible initial point
x0 = 100*randn(2,1);
opts = optimoptions(@fmincon,'Algorithm','interior-point','Display','off');
x = fmincon(@(x)0,x0,[],[],[],[],lb,[],@fminconstr,opts)
x = 2×1

   10.0000
   20.0000

在本例中,fmincon 从起点求解问题。

辅助函数

以下代码会创建 fbnd 辅助函数。

function F = fbnd(x)

F(1) = (x(1)+1)*(10-x(1))*(1+x(2)^2)/(1+x(2)^2+x(2));
F(2) = (x(2)+2)*(20-x(2))*(1+x(1)^2)/(1+x(1)^2+x(1));
end

以下代码会创建 fminconstr 辅助函数。

function [c,ceq] = fminconstr(x)

c = []; % No nonlinear inequality
ceq = fbnd(x); % fsolve objective is fmincon nonlinear equality constraints
end

另请参阅

| |

相关主题