Scipy.Optimize.Minimize 的矩阵约束

Matrix Constraints with Scipy.Optimize.Minimize

我正在尝试使用 python 的 scipy.optimize 来使用 SLSQP 算法最小化某些函数。优化似乎在不受约束且具有一个矩阵约束的情况下运行良好,但是当我添加第二个矩阵约束时出现错误。

import nlopt
import numpy as np
from scipy.optimize import minimize

n = 3
n_sim = 10000
risk_aversion = 5

Y = np.random.normal(loc=0, scale=1, size=(n_sim, n))

mu_Y = np.mean(Y, axis=0).reshape(1, n)
sigma_Y = np.cov(Y, rowvar=0, bias=1)

x0 = np.ones((n, 1)) / n

Aeq = np.ones((1, n))
beq = 1
A =  np.array([[1, 1, 0], [-1, -1, 0]])
b = np.array([[0.25], [-0.5]])

def func(x, mu, sigma, risk_aversion):
    return -np.dot(mu, x) + 0.5 * risk_aversion * np.dot(np.dot(x.T, sigma), x)
def func_deriv(x, sigma, risk_aversion):
    return risk_aversion * np.dot(sigma, x)

c_ = {'type': 'eq', 'fun' : lambda x: np.dot(Aeq, x) - beq, 'jac' : lambda x: Aeq}
b_ = [(0,1) for i in range(n)]

这个带有一个约束和边界的版本工作正常

res = minimize(lambda x: func(x, mu_Y, sigma_Y, risk_aversion), x0, 
               jac=lambda x: func_deriv(x, sigma_Y, risk_aversion), 
               constraints=c_, bounds=b_, method='SLSQP', options={'disp': True})

然而,两个约束版本给我一个错误

d_ = (c_,
        {'type': 'ineq', 'fun' : lambda x: np.dot(A, x) - b, 'jac' : lambda x: A})

res2 = minimize(lambda x: func(x, mu_Y, sigma_Y, risk_aversion), x0, 
                jac=lambda x: func_deriv(x, sigma_Y, risk_aversion), 
                constraints=d_, bounds=b_, method='SLSQP', options={'disp': True})

如果我使用

A =  np.array([-1, -1, 0])
b = -0.5

而不是我原来的优化工作。这表明我不能做一个约束矩阵(就像我在 Matlab 中使用 fmincon 一样),除非有人可以另外确认。但是,我可以继续添加约束以使其正常工作。约束必须是字典元组的形式,所以我放在一起

d = []
for i in range(0, b.size):
    d.append({'type': 'ineq', 'fun' : lambda x: np.dot(A[i, ], x) - b[i], 'jac' : lambda x: A[i, ]})
d_ = tuple(d)
c_tuple = c_,
d_ = d_ + c_tuple

这似乎工作正常。