我对matlab有点新鲜,很抱歉,如果这非常简单。
考虑以下问题:
查找x_1, x_2, x_3 > 0
以便
67.5 = 60*x_1 + 90*x_2 + 120*x_3 and
60 = 30*x_1 + 120*x_2 + 90*x_3
在这种情况下,我想要解决方案
0 < x_3 < 3/7,
x_2 = 7/20 - 4/10*x_3, and
x_1 = 2/5 - 7/5*x_3
是否有一种简单的方法可以让Matlab为我解决这样的问题?
答案 0 :(得分:8)
简单的答案,因为你只需要对参数进行非负性约束,就是使用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
那么对于任何任意常数c,x + c * N也必须是一个解。 (请记住,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
产生全零解决方案。由于该解决方案显然不能完全解决原始问题,因此不存在这样的正解决方案。
答案 1 :(得分:1)
A = [60 90 120; 30 120 90];
b = [67.5; 60];
您可以使用
获得Ax = b的解xx = A\b;
或
x = pinv(A)*b;
但是如果你想要x的约束,你将不得不使用类似lsqlin的东西:
lsqlin(A,b,[],[],[],[],[0; 0; 0],[])
(在这种情况下给出与pinv解决方案相同的结果)