找到欠定线性方程组的正解

Hen*_*rik 4 matlab mathematical-optimization equation-solving

我对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
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我想要解决方案

0 < x_3 < 3/7,
x_2 = 7/20 - 4/10*x_3, and
x_1 = 2/5  -  7/5*x_3
Run Code Online (Sandbox Code Playgroud)

是否有一种简单的方法可以让Matlab为我解决这样的问题?

小智 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
Run Code Online (Sandbox Code Playgroud)

我们可以测试结果,看看它是否解决了原始问题.

A*x - b
ans =
     0
     0
Run Code Online (Sandbox Code Playgroud)

当然你可以使用lsqlin,但为什么要这么麻烦?

事实上,我们必须考虑一个问题,因为一个未确定的系统有无限多的解决方案.我们可以在我们的解决方案中添加任意数量的数组A的零空间.在这种情况下,零空间具有秩1.它的特征在于向量N:

N = null(A)
N =
        -0.792593923901216
         -0.22645540682892
         0.566138517072299
Run Code Online (Sandbox Code Playgroud)

理解它的一个简单方法是识别A的零空间意味着什么.N是一个向量(或一组基本向量,如果零空间的维度大于1,则跨越子空间),这样

A*N = 0
Run Code Online (Sandbox Code Playgroud)

本质上,N是与A的所有行正交的向量.如果零空间的维度大于1,则N可以是零空间的基向量的任何线性组合.因此,如果X是确定系统的任何解决方案

A*x = b
Run Code Online (Sandbox Code Playgroud)

那么对于任何任意常数c,x + c*N也必须是一个解.(请记住,A*N将为零.)

例如,我将为N选择一个任意系数:

x2 = x + N*(-.1)
x2 =
        0.0792593923901216
          0.20121696925432
         0.371957576864199
Run Code Online (Sandbox Code Playgroud)

同样,x2也是一种解决方案.它也具有完全正系数.(您可以在N上找到系数的值范围,使解决方案完全正面.)

A*x2 - b
ans =
      -1.4210854715202e-14
       -7.105427357601e-15
Run Code Online (Sandbox Code Playgroud)

(注意,这些实际上是零,在浮点运算中找到的双精度垃圾中.)

因此,如果我们想要这样做,那么从lsqnonneg或反斜杠或pinv解决方案开始就很容易了,并为您的系统找到完整的解决方案集,使系数完全正.提示:您需要做的就是考虑向量x和N,然后寻找问题的解决方案

(x + c*N) > 0
Run Code Online (Sandbox Code Playgroud)

其中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
Run Code Online (Sandbox Code Playgroud)

正如我们所看到的,当c是闭区间[-.75701,0]中的任何值时,我们得到一个完全正解的问题,形式为(x + c*N).但是,除了这些限制之外,还有其他任何限制,解决方案中的一个或多个元素将为负数.

在一些问题上,根本没有解决方案可以得到解决方案向量的所有正元素的精确解.这是完全可能的.例如,假设我们将原始问题更改为:

A = [60 90 120; 30 120 90];
b = [-67.5; -60];
Run Code Online (Sandbox Code Playgroud)

现在当我们应用lsqnonneg时会发生什么?

lsqnonneg(A,b)
ans =
     0
     0
     0
Run Code Online (Sandbox Code Playgroud)

一个全零解决方案的结果.由于该解决方案显然不能完全解决原始问题,因此不存在这样的正解决方案.