Простой ответ, поскольку вам просто нужны ограничения неотрицательности параметров, — использовать lsqnonneg. lsqlin вообще не нужен для этой задачи, а так как lsqnonneg является частью MATLAB, оптимизация TB не нужна.
A = [60 90 120; 30 120 90];
b = [67.5; 60];
x = lsqnonneg(A,b)
x =
0
0.178571428571428
0.428571428571429
Мы можем проверить результат, чтобы увидеть, решил ли он исходную проблему.
A*x - b
ans =
0
0
Конечно, вы МОГЛИ использовать lsqlin, но зачем?
На самом деле есть проблема, которую мы должны рассмотреть, поскольку недоопределенная система имеет бесконечно много решений. Мы можем добавить к нашему решению любое количество нулевого пространства массива A. В этом случае это нулевое пространство имеет ранг 1. Здесь оно характеризуется вектором N:
N = null(A)
N =
-0.792593923901216
-0.22645540682892
0.566138517072299
Простой способ понять это — узнать, что означает нулевое пространство A. N является вектором (или набором базисных векторов, которые охватывают подпространство в случае, если нулевое пространство имеет размерность выше 1), такой что
A*N = 0
По сути, N — это вектор, ортогональный всем строкам A. Если нулевое пространство имеет размерность выше 1, то N может быть любой линейной комбинацией базисных векторов нулевого пространства. Следовательно, если X — ЛЮБОЕ решение недоопределенной системы
A*x = b
тогда должно быть верно, что x+c*N также является решением для любой произвольной константы c. (Помните, что A*N будет равно нулю.)
Так, например, я выберу произвольный коэффициент для N:
x2 = x + N*(-.1)
x2 =
0.0792593923901216
0.20121696925432
0.371957576864199
Опять же, x2 также является решением. Он также имеет полностью положительные коэффициенты. (Вы можете легко найти такой диапазон значений коэффициента при N, чтобы решение было полностью положительным.)
A*x2 - b
ans =
-1.4210854715202e-14
-7.105427357601e-15
(Обратите внимание, что это фактически нули, с точностью до мусора двойной точности, встречающегося в арифметике с плавающей запятой.)
Итак, ЕСЛИ мы хотим это сделать, достаточно легко начать с решения lsqnonneg, обратной косой черты или pinv и найти полный набор решений для вашей системы, так что коэффициенты будут полностью положительными. Подсказка: все, что вам нужно сделать, это рассмотреть векторы x и N, а затем искать решения проблемы
(x + c*N) > 0
где c — некоторая скалярная константа. Ясно, что C не может быть положительным, иначе первый элемент суммы будет отрицательным.
C = -x./N
C =
0
0.78855
-0.75701
x + C(1)*N
ans =
0
0.17857
0.42857
x + C(3)*N
ans =
0.6
0.35
0
Как мы видим, когда c является любым значением в закрытом интервале [-.75701,0], мы получаем полностью положительное решение проблемы в виде (x+c*N). Если пойти дальше этих пределов, то один или несколько элементов в решении будут отрицательными.
В некоторых задачах вообще не будет решения, которое дает точное решение со всеми положительными элементами вектора решения. Это вполне возможно. Например, предположим, что мы изменили исходную задачу на:
A = [60 90 120; 30 120 90];
b = [-67.5; -60];
Что происходит, когда мы применяем lsqnonneg?
lsqnonneg(A,b)
ans =
0
0
0
В результате получается нулевое решение. Поскольку это решение явно не может точно решить исходную проблему, должно быть верно, что такого положительного решения не существует.
person
Community
schedule
03.05.2013