我正在实现一个简单的二次优化问题:
def objective(x):
Q = DF.cov() # Covariance matrix
# Penalty Function method
penalty1 = 0.0005 * abs(np.sum(x)-1) # Large for sum(x) <> 1
penalty2 = 0.05 * abs(R_min - np.matmul(Mus.transpose(), x)) # Large for returns <> R_min
return np.matmul(x.transpose(),np.matmul(Q,x)) + penalty1 + penalty2
现在,我希望使用其他优化算法(特别是 BFGS 和 Newton-CG),它们需要目标函数的梯度和 Hessian。我已经在无约束情况下实现了导数函数,但是通过将惩罚项添加到目标(以及惩罚的导数到梯度函数)优化失败并出现以下错误:
Warning: Desired error not necessarily achieved due to precision loss.
Current function value: 0.000056
Iterations: 0
Function evaluations: 780
Gradient evaluations: 96
(以前迭代将是几百)。这严格发生在惩罚 1 中,但不是惩罚 2 本身,所以我的导数对于惩罚 1 是错误的:
penalty1_der = np.sign(x)
或者我不能以这种方式使用L1规范吗?我还尝试用更平滑的二次近似替换约束:
penalty1 = np.matmul((x - vector_ones).transpose(), (x - vector_ones))
但不幸的是,尽管这可以防止错误,但 Minimize() 似乎完全忽略了我的惩罚函数(即使参数大大增加)。
如何实现我的约束,以便我可以使用 BFGS/Newton-CG 解决问题?