fsolve
решает систему нелинейных уравнений. Однако это не позволяет включать какие-либо ограничения, даже связанные ограничения. Так как можно решить систему нелинейных уравнений, когда у вас есть ограничения?
Решение, удовлетворяющее вашим ограничениям, не гарантировано. На самом деле, задача может не иметь никакого решения, даже такого, которое не удовлетворяет вашим ограничениям. Однако существуют методы, которые помогают вам искать решения, которые удовлетворяют вашим ограничениям.
Чтобы проиллюстрировать методы, рассмотрим, как решить уравнения
где компоненты должно быть неотрицательным. Уравнения имеют четыре решения:
Только одно решение удовлетворяет ограничениям, а именно .
The fbnd
helper функция в конце этого примера вычисляет численно.
Как правило, система уравнения в переменные имеют изолированные решения, что означает, что каждое решение не имеет ближайших соседей, которые также являются решениями. Итак, один из способов поиска решения, удовлетворяющего некоторым ограничениям, - это сгенерировать ряд начальных точек x0
, а затем запустите fsolve
начиная с каждого x0
.
В данном примере, чтобы найти решение системы уравнений , взять 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
пытается минимизировать сумму квадратов компонентов в функции вектора . Поэтому он пытается решить уравнение . Кроме того, 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 Использование lsqcurvefit или lsqnonlin (Global Optimization Toolbox).
fmincon
ОграниченияМожно переформулировать задачу и использовать fmincon
следующим образом:
Задайте постоянную целевую функцию, такую как @(x)0
, который вычисляет значение 0 для каждого x
.
Установите fsolve
цель функционирует как нелинейные ограничения равенства в fmincon
.
Дайте любые другие ограничения в обычном fmincon
синтаксис.
The fminconstr
Функция helper в конце этого примера реализует нелинейные ограничения. Решите ограниченную задачу.
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