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

Dan*_*nia 4 python numpy matrix equation-solving

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

目前,我正在使用类似result = linalg.solve(A, B),在哪里AB是矩阵.但这并没有返回范围内的解决方案[0, 1].

unu*_*tbu 9

根据文档,

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

例如,给定这个方程组

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

该解决方案不等于1:

print(x)
# [-0.5 -1.5  1.5]
Run Code Online (Sandbox Code Playgroud)

但你可以尝试最小化f:

def f(x):
    y = np.dot(A, x) - b
    return np.dot(y, y)
Run Code Online (Sandbox Code Playgroud)

受限制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 ])
Run Code Online (Sandbox Code Playgroud)

xbest 总和为1:

print(xbest.sum())
1
Run Code Online (Sandbox Code Playgroud)

不同之处 A·xbest - b是:

print(np.dot(A, xbest) - b)
# [ 0.19999026  0.10000663 -0.50000257]
Run Code Online (Sandbox Code Playgroud)

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

print(res['fun'])
0.30000000014542572
Run Code Online (Sandbox Code Playgroud)

在满足约束条件时,x的其他值不会使该数量最小化.