根据 Erwin 的 建议(在评论中),这里是使用 cvxpy 的解决方案。
请记住,您有两个相互竞争的目标!这意味着,您要么必须平衡这些(哪一个是多么重要),要么将其中之一作为固定约束(例如,方差差异低于某个给定常数)。这是前者的一些代码。
另一个说明:虽然您的原始方差项是 平方和,但我在这里使用 欧几里得范数,这在求解 (不错 SOCP problem-formulation)并且在与 alpha 的平衡方面也可能更有趣,因为两者的增长相同(渐近)。
使用的默认求解器是ECOS(开源)。
代码
import numpy as np
from cvxpy import *
""" Random data """
M = 10
N = 10
A = np.random.rand(M,N)
B = np.random.rand(N)
C = np.random.rand(M)
""" Solve """
alpha = 0.01 # Regularization
factor -> multiple objectives
X = Variable(B.shape[0])
component_A, component_B = norm(A * X - C), norm(X - B) # norm more useful than sum_of_squares
objective = Minimize(component_A + alpha * component_B)
problem = Problem(objective, []) # [] = no constraints
problem.solve(verbose=False)
print(problem.value)
print('A*X: ', A.dot(X.value).T.flatten())
print('C: ', C)
print('X: ', X.value.T.flatten())
print('B: ', B)
输出 alpha=0.1 -> 与 A*X=C 相比,variance-diff 并不重要
0.02115062805819827
A*X: [[ 0.08126681 0.61685533 0.51072777 0.62493694 0.33443435 0.70281179
0.89593751 0.34521676 0.16157952 0.62992064]]
C: [ 0.08126681 0.61685533 0.51072777 0.62493694 0.33443435 0.70281179
0.89593751 0.34521676 0.16157952 0.62992064]
X: [[-0.03327532 -0.32668216 -0.44441417 0.75708529 -0.00958777 -0.33155358
0.60025503 0.52237198 0.3052468 -0.14709605]]
B: [ 0.89801455 0.50875127 0.77806572 0.17184964 0.06610118 0.27861303
0.40513181 0.85778655 0.86835541 0.32786036]
输出 alpha=10 -> 与 A*X=C 相比,方差更重要
5.3146149509187195
A*X: [[ 1.87714559 2.11056115 1.74268386 1.68503155 2.59590194
1.9540973 2.37874233 2.07600857 1.6713983 1.2590621 ]]
C: [ 0.18125564 0.33469345 0.63367096 0.0075308 0.19983206 0.76975212
0.22084296 0.35758024 0.0214036 0.42501635]
X: [[ 0.25227884 0.4022509 0.17074389 0.22068181 0.04595178 0.85354537
0.1039422 0.76882144 0.85936741 0.14723398]]
B: [ 0.25227884 0.4022509 0.17074389 0.22068181 0.04595178 0.85354537
0.1039422 0.76882144 0.85936741 0.14723398]
一个随机的密集 1000x1000 问题在我的机器上使用 ECOS 花费了 15 秒(商业求解器 MOSEK 将在大约 1 秒内完成)。也可以使用求解器SCS,它可以更快,但精度略有降低(并且可以在 GPU 上以两种配置之一运行 -> 间接模式)。
如果您的问题稀疏,这两个求解器都可以获得很多。