使用带约束的 linalg 求解系统
Solving system using linalg with constraints
我想使用 linalg
以矩阵形式求解某个系统,但所得解的总和应为 1。例如,假设有 3 个未知数 x、y、z。求解系统后,它们的值总和应为 1,例如 .3、.5、.2。谁能告诉我该怎么做?
目前,我正在使用类似 result = linalg.solve(A, B)
的东西,其中 A
和 B
是矩阵。但这不是 return 范围内的解决方案 [0, 1]
.
linalg.solve
is used to compute the "exact" solution, x
, of the
well-determined, i.e., full rank, linear matrix equation 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 值在满足约束条件的同时更能最小化此数量。
您可以在 A 中添加一行,在 B 中添加一个。之后使用
结果 = linalg.lstsq(A, B)[0]
或者您可以将 A 的其中一行替换为由 1 组成的行,也可以将 B 中的值替换为同一行中的一个。然后使用
结果 = linalg.solve(A, B)
作为替代方案,您可以将 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]]
。
我想使用 linalg
以矩阵形式求解某个系统,但所得解的总和应为 1。例如,假设有 3 个未知数 x、y、z。求解系统后,它们的值总和应为 1,例如 .3、.5、.2。谁能告诉我该怎么做?
目前,我正在使用类似 result = linalg.solve(A, B)
的东西,其中 A
和 B
是矩阵。但这不是 return 范围内的解决方案 [0, 1]
.
linalg.solve
is used to compute the "exact" solution,x
, of the well-determined, i.e., full rank, linear matrix equationax = 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 值在满足约束条件的同时更能最小化此数量。
您可以在 A 中添加一行,在 B 中添加一个。之后使用 结果 = linalg.lstsq(A, B)[0]
或者您可以将 A 的其中一行替换为由 1 组成的行,也可以将 B 中的值替换为同一行中的一个。然后使用 结果 = linalg.solve(A, B)
作为替代方案,您可以将 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]]
。