I am trying to do a optimization problem which requires the calculation of a new covariance matrix affected by the variable within the implementation.
I am able to do so with scipy optimization Minimize using numpy.cov within my objective function. However, as I need to have integer constraints, I am not able to think of a solution which tackles my issue with cvxpy, gekko since most of the optimization problem online have a fixed covariance matrix.
Below is my code for 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})
Would appreciate if anybody has a solution! Thank you.
The covariance of
xi
andyi
is calculated explicitly withnp.cov()
.The function
np.cov(xi,yi)
returns a 2x2 symmetric matrixGekko needs a symbolic form of the covariance formula for the gradient-based optimizer. Below is a function
cov()
that creates the symbolic covariance calculation with Gekko variables.Gekko and Numpy produce the same results for the fixed
xi
andyi
values:Now that the
cov()
function is verified, you can switchx
andy
to be calculated integer values such as:To obtain an integer solution, switch to
m.options.SOLVER=1
(APOPT) solver before them.solve()
command.