Python 单调递减Xs约束下的SciPy极小

Python 单调递减Xs约束下的SciPy极小,python,optimization,scipy,Python,Optimization,Scipy,我期待着做一个艰苦的优化,其中我使用SciPy优化债券现金流的贴现因子(应用程序不太重要,但如果有兴趣)。所以本质上我取多个已知值'P',其中P[I]是C[I]已知常数的函数,数组X(X[j]=X(t),其中X是时间的函数)。式中,C[i]和X的和积=P 希望这有点道理,但本质上为了得到一个合理的结果,我想设置一个约束,其中X(我的X值数组)具有X[j]

我期待着做一个艰苦的优化,其中我使用SciPy优化债券现金流的贴现因子(应用程序不太重要,但如果有兴趣)。所以本质上我取多个已知值'P',其中P[I]是C[I]已知常数的函数,数组X(X[j]=X(t),其中X是时间的函数)。式中,C[i]和X的和积=P

希望这有点道理,但本质上为了得到一个合理的结果,我想设置一个约束,其中X(我的X值数组)具有X[j] 下面是我的优化函数代码片段:

在[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)
Out[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]

我试着按照文档进行操作,但显然不起作用

非常感谢您的任何想法。

让我们试试

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})
def con(x):
对于范围内的i(len(x)-1):
如果x[i]让我们试试看

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})
def con(x):
对于范围内的i(len(x)-1):


如果x[i]我不能对下面的帖子发表评论,但是你需要在那里有一个
i=i
元组([{'type':'ineq',fun':lambda x,i=i:x[i]-x[i+1]}对于范围(9)内的i]+[{'type':'eq',fun':lambda x,i=i:0如果x[j]!=x[j+1],对于范围(9)内的j,i=1})
我不能对下面的帖子发表评论,但是你需要在那里有一个
I=I
元组([{'type':'ineq',fun':lambda x,I=I:x[I]-x[I+1]}对于范围(9)中的I)+[{'type':'eq',fun':lambda x,I=I:0如果x[j]!=x[j+1]对于范围(9)中的j,还有1}

值是否正确,您是否希望更改其顺序?或者这些值是否不是您期望的值。如果数字正确,但顺序错误,您可以调用
排序(my_list,reverse=True)
对我来说,将它们按降序排列似乎是不正确的,因为它们不满足x[i]lambda x:x[0]-x[1]
这可能允许通过相同值的数字,因此您可能需要另一个约束来处理这些数字。您返回的是布尔值。我认为您应该返回一个数字值。从文档中可以看出:等式约束意味着约束函数结果为零,而不等式意味着它为零n-否定值是否正确,您是否希望更改其顺序?或者这些值是否不是您期望的值。如果数字正确,但顺序错误,您可以调用
sorted(my_list,reverse=True)
对我来说,将它们按降序排列似乎是不正确的,因为它们不满足x[i]lambda x:x[0]-x[1]
这可能允许通过相同值的数字,因此您可能需要另一个约束来处理这些数字。您返回的是布尔值。我认为您应该返回一个数字值。从文档中可以看出:等式约束意味着约束函数结果为零,而不等式意味着它为零n-negativen不幸的是没有运气。它仍然“解决”了,但看起来好像没有使用约束。我可能更接近于这样的东西:
constest=[]对于范围(0,9)中的i:constest.append({'type':'ineq','fun':lambda x:x[i]-x[i+1]})constest=tuple(constest)
但仍然没有返回递减的x值…这给您带来了什么问题?
状态:0成功:真正的njev:6 nfev:87乐趣:2.4160614409943012e-07 x:array([0.90092506,0.89092506,0.88092506,0.94477693,0.8630145,0.92834855,-1.3189858,-1.09804772,1.07317062])
返回值与原始值不同,但不受我希望的约束,因为值不会减少如果我只是像你最初说的那样硬编码约束,那么我得到的所有值都相等(可能成功?)不确定为什么循环不起作用:
cons=({'type':'ineq','fun':lambda x:x[0]-x[1]},{'type':'ineq','fun':lambda x:x[1]-x[2]}[3]3[3]},,{类型“,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,(x[9]})
运气不好