我希望做一个艰苦的优化,其中我使用SciPy来优化债券现金流的贴现因子(应用程序不那么重要,但如果感兴趣的话)。所以本质上我取多个已知值‘P’,其中P[I]是C[I]已知常数的函数,数组X(X[j]=X(t),其中X是时间的函数)。其中C[i]与X的和积=P
希望这是有意义的,但本质上为了得到一个合理的结果,我想设置一个约束,其中X(我的X值数组)有一个约束,即X[j]<;X[j-1],即X的单调递减。在
下面是优化函数的代码片段:
在[400]:
import numpy as np
import pandas as pd
import scipy as s
def MyOptimization(X):
P=np.array([99.,100.,105.,110.]) #just example known "P" array, in reality closer to 40 values
c=np.array([1.25,4.,3.1,2.5]) #Cash flows for each P
t=np.array([[1.2,2.,4.,10.0],[0.5,1.],[2.3,5.,10.5],[1.7]]) #time t of each cash flow, multiple per 'P'
#remember P=X(t)*c[i] and x(t) where x[i+1]<x[i]
tlist=[] #t's will be used as index, so pulling individual values
for i in t:
for j in i:
tlist.append(j)
df=pd.DataFrame(data=X,index=tlist).drop_duplicates().sort() #dataframe to hold t (index) and x, x(t), and P(x,c) where c is known
#print df
sse=0
for i in range(0,len(P)):
pxi = np.sum(df.loc[t[i],0].values*c[i])+100*df.loc[t[i][-1],0]
sse=sse+(pxi-P[i])**2 #want to minimize sum squared errors between calculated P(x,c) and known P
return sse
cons=({'type':'ineq','fun': lambda x: x[1] < x[0]}) #trying to define constraint that x is decreasing with t
opti=s.optimize.minimize(MyOptimization,x0=[0.90,0.89,0.88,0.87,0.86,0.85,0.84,0.83,0.82,0.81],bounds=([0,1],)*10,constraints=cons)
在[401]中:
^{pr2}$出局[401]:
status: 0
success: True
njev: 4
nfev: 69
fun: 5.445290696814009e-15
x: array([ 0.90092322, 0.89092322, 0.88092322, 0.94478062, 0.86301329,
0.92834564, 0.84444848, 0.83444848, 0.96794781, 1.07317073])
message: 'Optimization terminated successfully.'
jac: array([ -7.50609263e-05, -7.50609263e-05, -7.50609263e-05,
-5.92906077e-03, 3.46914830e-04, 9.17475767e-03,
-4.89504256e-04, -4.89504256e-04, -1.61263312e-02,
8.35321580e-03, 0.00000000e+00])
nit: 4
很明显,在结果中,x数组没有减少。(也尝试添加(0,1)边界,但结果失败,所以现在集中讨论这个问题。在
对于我不确定的约束,这里最重要的一行是:
cons=({'type':'ineq','fun': lambda x: x[1] < x[0]})
我试着按照文档进行操作,但显然没有效果。在
任何想法都值得赞赏。在
我不能评论下面的帖子,但你需要有一个
i=i
在那里。。。tuple([{'type':'ineq', 'fun': lambda x,i=i: x[i] - x[i+1]} for i in range(9)] + [{'type':'eq', 'fun': lambda x,i=i: 0 if x[j] != x[j+1] else 1} for j in range(9)])
我们试试看
这应该会拒绝那些没有按照你想要的方式设置的列表,但是我不确定scipy是否会喜欢它。在
相关问题 更多 >
编程相关推荐