2022年 11月 6日

python3凸优化

目录

简介

全局最优化

局部优化

有约束优化问题

代码实现


简介

凸优化,或叫做凸最优化凸最小化,是数学最优化的一个子领域,研究定义于凸集中的凸函数最小化的问题。

在金融学和经济学中,凸优化起着重要作用,这方面的例子包括市场数据校准和期权定价模型,或者效用函数的优化。

我们对下列函数fm进行这种优化

  1. #coding:UTF-8
  2. import numpy as np
  3. from mpl_toolkits.mplot3d import Axes3D
  4. import matplotlib.pyplot as plt
  5. import matplotlib as mpl
  6. import scipy.optimize as spo
  7. def fm(*args):
  8. return (np.sin(args[0])+0.05*args[0]**2+np.sin(args[1])+0.05*args[1]**2)
  9. x = np.linspace(-10,10,50)
  10. y = np.linspace(-10,10,50)
  11. x,y = np.meshgrid(x,y)
  12. z = fm(x,y)
  13. fig = plt.figure(figsize=(9,6))
  14. ax = fig.gca(projection='3d')
  15. surf = ax.plot_surface(x,y,z,rstride=2,cstride=2,cmap=mpl.cm.coolwarm,linewidth=0.5,antialiased=True)
  16. ax.set_xlabel('x')
  17. ax.set_ylabel('y')
  18. ax.set_zlabel('f(x,y)')
  19. fig.colorbar(surf,shrink=0.5,aspect=5)
  20. plt.show()

全局最优化

  1. def fo(*args):
  2. x = args[0][0]
  3. y = args[0][1]
  4. z = np.sin(x) + 0.05*x**2 + np.sin(y) + 0.05*y**2
  5. #print(x,y,z)
  6. return z
  7. opt = spo.brute(fo,((-10,10,0.1),(-10,10,0.1)),finish=None)
  8. print(opt)
  9. print(fm(opt[0],opt[1]))
  1. [-1.4 -1.4]
  2. -1.7748994599769203
  3. Process finished with exit code 0

最优化参数现在是x=y=-1.4,全局最小化的最小函数大约-1.7749

局部优化

  1. opt2 = spo.fmin(fo,(2.0,2.0),maxiter=250)
  2. print(opt2)
  3. print(fm(opt2[0],opt2[1]))
  1. Optimization terminated successfully.
  2. Current function value: 0.015826
  3. Iterations: 46
  4. Function evaluations: 86
  5. [4.2710728 4.27106945]
  6. 0.0158257532746805
  7. Process finished with exit code 0

有约束优化问题

现实中的问题往往是有约束条件的,在条件允许内,制定最优的解决方案,从而获得最好的结果。

例如如下情景:你可以选择投资两种证券,如何分配才能取得最大化收益呢?

已知假设如下,两种证券现价格为Q_{a} =Q_{b}  = 10,收益受到u,d两种状态影响,一年后,u状态下的收益分别为15和5,而d下则为5和12,假设两种状态出现的概率相同,用P_{u}=P_{d}  = 0.5表示,而他们的收益则用R_{a},R_{b}表示

你的预算为W_{0} = 100,

未知假设:未来财富率的效用函数如下如下U_{w} = \sqrt{w},a,b是投资者购买的证券数量,则如下公式成立

  • \underset{a,b}{max}-E(U(_{w1})) = p\sqrt{_{w1a}}+(1-p)\sqrt{_{w1b}}   
  • W_{1} =W_{1a}+W_{1b}= aR_{a} + bR_{b}       总收益公式
  • W_{0} \geq aQ_{a} + bQ_{b}                               总投资收到预算的约束
  • a,b\geq 0                                               每种证券的投资数量收到非负数约束

现在我们将数值带入,反向求解

  • \underset{a,b}{min}-E(U(_{w1})) =-\left ( 0.5*\sqrt{_{w1a}}+0.5*\sqrt{_{w1b}}\right )     函数1
  • W_{1a} = a*15+b*5
  • W_{1b} = a*5 + b*12
  • 100\geq a*10+b*10                        条件1
  • a,b\geq 0                                               条件2

代码实现

  1. import scipy.optimize as spo
  2. from math import sqrt
  3. def Eu(*args): #函数一
  4. a = args[0][0]
  5. b = args[0][1]
  6. return -(0.5*sqrt(a*15+b*5)+0.5*sqrt(a*5+b*12))
  7. cons = ({'type':'ineq','fun':lambda a: 100-a[0]*10-a[1]*10 }) #条件一
  8. bnds = ((0,1000),(0,1000)) #条件二
  9. result = spo.minimize(Eu,[5,5],method='SLSQP',bounds=bnds,constraints=cons)
  10. print(result)
  1. fun: -9.700883611487832
  2. jac: array([-0.48508096, -0.48489535])
  3. message: 'Optimization terminated successfully.'
  4. nfev: 21
  5. nit: 5
  6. njev: 5
  7. status: 0
  8. success: True
  9. x: array([8.02547122, 1.97452878])
  10. Process finished with exit code 0

结果如上,你要购买8个a证券和2个b证券。