使用具有约束的linalg求解系统

时间:2015-06-28 09:40:41

标签: python numpy matrix equation-solving

我想使用linalg以矩阵的形式解决一些系统,但是得到的解决方案应该总和为1.例如,假设有3个未知数,x,y,z。解决系统后,它们的值应总计为1,如.3,.5,.2。谁能告诉我怎么做到这一点?

目前,我使用result = linalg.solve(A, B)之类的内容,其中AB是矩阵。但是这不会返回[0, 1]范围内的解决方案。

3 个答案:

答案 0 :(得分:8)

Per the docs

  

linalg.solve用于计算"精确"解决方案,x,   确定的,即满秩,线性矩阵方程ax = b

被 线性,最多可以有一个解决方案。如果您找到的解决方案没有 总计为1,然后添加额外约束将不会产生解决方案。

但是,你可以使用 scipy.optimize.minimize 找到最小化数量的约束平面上的点 ||Ax-b||^2

def f(x):
    y = np.dot(A, x) - b
    return np.dot(y, y)

cons = ({'type': 'eq', 'fun': lambda x: x.sum() - 1})
res = optimize.minimize(f, [0, 0, 0], method='SLSQP', constraints=cons, 
                        options={'disp': False})

例如,给定这个方程组

import numpy as np
import numpy.linalg as LA
import scipy.optimize as optimize

A = np.array([[1, 3, 4], [5, 6, 9], [1, 2, 3]])
b = np.array([1, 2, 1])
x = LA.solve(A, b)

解决方案不等于1:

print(x)
# [-0.5 -1.5  1.5]

但您可以尝试最小化f

def f(x):
    y = np.dot(A, x) - b
    return np.dot(y, y)

受约束cons

的约束
cons = ({'type': 'eq', 'fun': lambda x: x.sum() - 1})
res = optimize.minimize(f, [0, 0, 0], method='SLSQP', constraints=cons, 
                        options={'disp': False})
xbest = res['x']
# array([ 0.30000717,  1.89998823, -1.1999954 ])

xbest总和为1:

print(xbest.sum())
1

差异A·xbest - b是:

print(np.dot(A, xbest) - b)
# [ 0.19999026  0.10000663 -0.50000257]

和差异的平方和(也可以计算为f(xbest))是:

print(res['fun'])
0.30000000014542572

在满足约束条件时,x的其他任何值都不会使此数量最小化。

答案 1 :(得分:0)

你可以在A中添加由1组成的行,然后在B中添加一行。之后使用 result = linalg.lstsq(A,B)[0]

或者您可以将A行中的一行替换为由1组成的行,也将B中的值替换为同一行中的一行。然后用 result = linalg.solve(A,B)

答案 2 :(得分:0)

作为替代方案,您可以将numpy.linalg.lstsq与新行结合使用到A矩阵:[1, 1, 1]B矩阵[1]

import numpy as np
A = np.array([[1, 0, 1],
              [0, 1, 1],
              [1, 1, 0],
              [1, 1, 1]]
B = np.array([[0.5, 0.7, 0.8, 1.0]]).T
x, _, _, _ = np.linalg.lstsq(A, B)

这将x设为[[0.3], [0.5], [0.2]]