抑郁症健康,内容丰富有趣,生活中的好帮手!
抑郁症健康 > 基于投资组合问题的凸二次规划模型及求解——Gurobi求解器+高阶牛顿法(python)

基于投资组合问题的凸二次规划模型及求解——Gurobi求解器+高阶牛顿法(python)

时间:2020-12-26 14:01:31

相关推荐

本学期上了最优化课程,学习到了一些凸优化的知识,想要尝试将这些优化理论应用到实际中。

这里基于均值-方差分析方法,针对以确定收益水平下的最小化风险为目标的投资组合问题建立了具有等式约束的凸二次规划模型,并分别利用GUROBI求解器和一种高阶牛顿算法对其进行求解。

模型描述如下(公式太多的地方就直接贴图片了):

分别利用Gurobi求解器和高阶牛顿法求解:

Gurobi:Gurobi是美国Gurobi Optimization公司开发的大规模优化求解器,目前已经成为综合能力全球领先的数学规划求解器,作为一个全局优化器,Gurobi支持的模型类型包括:连续和混合整数线性问题、凸目标或约束连续和混合整数二次问题、含有指对数、三角函数、高阶多项式目标和约束以及任何形式的分段约束的非线性问题等。另外,Gurobi提供了方便轻巧的API接口,支持C++、Java、Python等多种语言,同时支持包括Windows、Linux以及OS在内的多种平台。

基于绝对值光华逼近的高阶牛顿法(公式真的多我是真的懒,依旧贴图片):

代码如下:

from gurobipy import GRB, GurobiErrorimport gurobipy as gpfrom numpy import *import mathimport pandas as pdc=array([[0],[0],[0]])Q=array([[0.2,0.3,-0.01],[0.3,2.4,0.5],[-0.01,0.5,1.1]])A=array([[0.06,0.12,0.09],[1,1,1]])b=array([[0.06],[1]])c=array([[0],[0],[0]])x=array([[0],[0],[0]])y=array([[0],[0]])k=1000e=0.000001def guroby_solver(Q,A,b,c):try:m = gp.Model("QP_guroby")var = []constr = 0obj = 0for i in range(len(A[0])):var.append(m.addVar(lb=0, vtype=GRB.CONTINUOUS, name='var[%d]' % i)) #定义变量for i in range(len(A)):constr = 0for j in range(len(A[0])):if A[i][j] != 0:constr = constr + A[i][j] * var[j]m.addConstr(constr == b[i][0], name='constraint %d' % i)#添加约束for i in range(len(A[0])):for j in range(len(A[0])):obj = obj + Q[i][j] * var[i] * var[j]for i in range(len(A[0])):obj = obj + c[i][0] * var[i]m.setObjective(obj, GRB.MINIMIZE) #添加目标函数m.optimize()variable=[]for v in m.getVars():print(v.varName, v.x)variable.append(v.x)print('Obj:', m.objVal)except GurobiError:print('Error reported')return variable,m.objVal#GUROBI求解器求解函数def newton(x,y,e,k,Q,A,b,c):def cal_pk(m):x_pk=zeros((len(m),1))for i in range(len(m)):x_pk[i][0]=math.sqrt(m[i][0]**2+1/(k**2))return x_pkdef cal_Fk(X,m):x_split=X[:m,:]y_split=X[m:,:]Fk_up=dot(A,cal_pk(x_split)-x_split)-bFk_down=cal_pk(x_split)+x_split+ \dot(A.T,y_split)+dot(Q,x_split)-dot(Q,cal_pk(x_split))-cFk=vstack((Fk_up,Fk_down))return Fkdef cal_Fk_grad(X,m,n):x_split=X[:m,:]Dk=zeros((m,m))for i in range(m):Dk[i][i]=x_split[i][0]/math.sqrt(x_split[i][0]**2+1/(k**2))O=zeros((n,n))Fk_grad_up=hstack((dot(A,Dk-identity(3)),O))Fk_grad_down=hstack((Dk+identity(3)+dot(Q,identity(3)-Dk),A.T))Fk_grad=vstack((Fk_grad_up,Fk_grad_down))return Fk_gradX=vstack((x,y))while True:if dot(cal_Fk(X,len(x)).T,cal_Fk(X,len(x)))<e:breakU=X-0.5*dot(linalg.inv(cal_Fk_grad(X,len(x),len(y))),cal_Fk(X,len(x)))V=X-dot(linalg.inv(cal_Fk_grad(U,len(x),len(y))),cal_Fk(X,len(x)))X=V+dot(linalg.inv(cal_Fk_grad(X,len(x),len(y))) \-2*linalg.inv(cal_Fk_grad(U,len(x),len(y))),cal_Fk(V,len(x)))re_x=X[:len(x),:]z=zeros((len(x),1))for i in range(len(x)):z[i][0]=abs(re_x[i][0])-re_x[i][0]mid=dot(Q,z)obj_fuc=dot(z.T,mid)+dot(c.T,z)print('高阶牛顿法的最优解为:',z)print('目标函数值为:',obj_fuc)return z,obj_fuc #牛顿法求解函数df=pd.DataFrame(index=range(13),columns=['rp','z1_g','z2_g', \'z3_g','obj_g','z1_n', \'z2_n','z3_n','obj_n'])for i in range(13):b[0][0]=0.06+i*0.005m,n=guroby_solver(Q,A,b,c)p,q=newton(x,y,e,k,Q,A,b,c)df['rp'][i]=b[0][0]df['z1_g'][i]=m[0]df['z2_g'][i]=m[1]df['z3_g'][i]=m[2]df['obj_g'][i]=ndf['z1_n'][i]=p[0][0]df['z2_n'][i]=p[1][0]df['z3_n'][i]=p[2][0]df['obj_n'][i]=q[0][0]df.to_csv('Result.csv')#将计算结果导入excel

参考文献:

雍龙泉,贾伟,黎延海.基于光滑逼近函数的高阶牛顿法求解凸二次规划[J].科学技术与工程,,21(06):2151-2156.

如果觉得《基于投资组合问题的凸二次规划模型及求解——Gurobi求解器+高阶牛顿法(python)》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。