[英]Optimization integer programming with covariance matrix
我正在嘗試做一個優化問題,該問題需要計算受實現中的變量影響的新協方差矩陣。
我可以通過在我的目標 function 中使用 numpy.cov 進行 scipy 優化最小化來做到這一點。但是,由於我需要有 integer 約束,所以我無法想出解決我的 cvxpy、gekko 問題的解決方案,因為大多數在線優化問題具有固定的協方差矩陣。
下面是我的 scipy 代碼:
room_revpar = np.array(df.iloc[:,1:10])
nla = np.array([753.2,1077.6, 1278.6,1463.9,1657.0,1990.6,2404.9,2754.6,3464.72])
min_nla = 270517.16
max_nla = 271270.359995
def objective(x, room_revpar,nla,sign = -1.0):
room_revenue = room_revpar * x
avg_revenue = np.mean(room_revenue, axis = 0)
total_revenue = sum(avg_revenue)
cov_matrix = np.cov(room_revenue.T)
total_nla = np.matmul(x.T, nla)
weights = x * nla / total_nla
portfolio_sd = np.sqrt(np.matmul(np.matmul(weights.T, cov_matrix), weights))
adj_risk = total_revenue / portfolio_sd
return sign * adj_risk
def constraint1(x, nla, min_nla):
total_nla = np.matmul(x.T, nla)
return total_nla - min_nla
def constraint2(x, nla, max_nla):
total_nla = np.matmul(x.T, nla)
return max_nla - total_nla
con1 = {'type': 'ineq', 'fun': constraint1, 'args': (nla, min_nla)}
con2 = {'type': 'ineq', 'fun': constraint2, 'args': (nla, max_nla)}
from scipy.optimize import minimize
x = np.ones(9)
sol = minimize(objective,x0 = x, args = (room_revpar, nla), constraints = (con1,con2), options = {'maxiter': 100000})
如果有人有解決方案,將不勝感激。 謝謝你。
xi
和yi
的協方差是使用np.cov()
顯式計算的。
import numpy as np
xi = [2.1,2.5,3.6,4.0]
yi = [8,10,12,14]
print(np.cov(xi,yi))
function np.cov(xi,yi)
返回一個 2x2 對稱矩陣
[[cov[xi,xi],cov[xi,yi]],
[cov[xi,yi],cov[yi,yi]]]
[[0.80333333 2.26666667]
[2.26666667 6.66666667]]
Gekko 需要用於基於梯度的優化器的協方差公式的符號形式。 下面是一個 function cov()
,它使用 Gekko 變量創建符號協方差計算。
import numpy as np
from gekko import GEKKO
def cov(m,x,y,ddof=1):
''' Calculate the covariance matrix of x, y
Inputs:
m: Gekko model
x: x vector of equal length to y
y: y vector of equal length to x
[ddof=1]: delta degrees of freedom
Returns:
c: covariance as a Gekko variable
'''
nx = len(x); ny = len(y) # length of x, y
if nx!=ny:
print('Error: mismatch of x and y')
xm = m.sum(x)/nx # mean of x
ym = m.sum(y)/ny # mean of y
c = m.Var() # covariance
m.Equation(c==(m.sum([(x[i]-xm)*(y[i]-ym) \
for i in range(nx)]))/(nx-ddof))
return c
m = GEKKO()
n = 4
x = m.Array(m.Param,n)
y = m.Array(m.Param,n)
xi = [2.1,2.5,3.6,4.0]
yi = [8,10,12,14]
for i in range(n):
x[i].value = xi[i]
y[i].value = yi[i]
c0 = cov(m,x,y,ddof=0)
c1 = cov(m,x,y)
m.solve(disp=False)
print('Covariance (Numpy) population cov: ', np.cov(xi,yi,ddof=0)[0,1])
print('Covariance (Numpy) sample cov: ', np.cov(xi,yi)[0,1])
print('Covariance (Gekko) population cov: ', c0.value[0])
print('Covariance (Gekko) sample cov: ', c1.value[0])
Gekko 和 Numpy 對於固定的xi
和yi
值產生相同的結果:
Covariance (Numpy) population cov: 1.7
Covariance (Numpy) sample cov: 2.2666666666666666
Covariance (Gekko) population cov: 1.7
Covariance (Gekko) sample cov: 2.2666666667
既然cov()
function 驗證通過了,你可以切換x
和y
來計算integer的值如:
x = m.Array(m.Var,n,lb=0,ub=10,integer=True)
y = m.Array(m.Var,n,lb=0,ub=5,integer=True)
要獲得 integer 解決方案,請在m.solve()
命令之前切換到m.options.SOLVER=1
(APOPT) 求解器。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.