2016-09-21 28 views
1

我期待做一个剧烈的优化,我使用SciPy来优化债券现金流的折扣因素(应用程序不太重要,但如果感兴趣)。所以基本上我取多个已知值'P',其中P [i]是C [i]已知常数的函数,而数组X(X [j] = x(t)其中x是时间的函数)。其中C [i]和X = P的积和产品。我希望在X(我的x值数组)中有一个约束条件约束x [j] < x [j-1],即x的单调递减。SciPy最小化与单调减少Xs约束

这里是我的最优化函数的代码片段:

在[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]:

opti 

出[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]})

我试过下面的文件,但很明显,没有工作。

任何想法不胜感激。

+0

值是否正确,您想更改顺序?或者这些不是你期待的价值。如果数字是好的,但顺序错误,你可以调用'sorted(my_list,reverse = True)'将它们按递减顺序排列 –

+0

对我来说,好像它们不可能是正确的,因为它们不满足约束x [i] Vlox

+0

我正在阅读scipy.optimize.minimize的文档,看起来你应该设置你的约束它会传递一个非负数。也许尝试'lambda x:x [0] - x [1]' –

回答

0

让我们尝试

def con(x): 
    for i in range(len(x)-1): 
     if x[i] <= x[i+1]: 
      return -1 
    return 1 

cons=({'type':'ineq','fun': con}) 

这应该拒绝没有设置好像你想要的列表,但我不确定是scipy会喜欢它。

+0

不幸的是,它仍然“解决”,但看起来像它不使用约束 – Vlox

+0

我可能已经接近类似的东西: 'constest = [] 我在范围内(0,9): constest .append({'type':'ineq','fun':lambda x:x [i] -x [i + 1]}) constest = tuple(constest)'但仍然不会返回递减的x值... – Vlox

+0

给你什么问题? –