Scipy 未能最小化目标函数

问题描述

我正在尝试使用 scipy.optimize.minimize 来解决非线性系统。目标是输出金额的隐含价格与输入“价格”数组中指定的非零值相匹配,也就是

all(result==desired for result,desired in zip(amttoprice(results.x),prices) if desired>0)  

这是我的 MRE:

from scipy import optimize
import numpy as np
#Sample input values
before=np.array([10,20,30,40,50])
C=np.array([1,1,1])
prices=[0,.2,.3,0]
filter=[x<=0 for x in prices]

#Define objective function
def pdif(amts,prices,conversion):
    implied=amttoprice(amts,C) 
    return sum(abs(p-i) for p,i in zip(prices,implied) if p>0)

def amttoprice(amts,conversion):
    return 1/(conversion/amts).sum()/amts

#Define constraints (product constrain and buying constraint)
pc=scipy.optimize.NonlinearConstraint(np.prod,np.prod(before),np.prod(before))
bc=scipy.optimize.NonlinearConstraint(lambda x:np.std((x[filter]-before[filter])/C[filter]),0)

#Minimize
results=optimize.minimize(pdif,before,(prices,C),'trust-constr',constraints=[pc,bc])

#Test results
[(output,desired) for output,desired in zip(amttoprice(results.x,prices) if desired>0]
>>>>[(0.21897810218978103,0.2),(0.145985401459854,0.3)]
#Not good

#Let's try a different method
#Define constraints (product constrain and buying constraint)
pc={'type':'eq','fun':lambda x:abs(np.prod(x)-np.prod(before))}
bc={'type':'eq','fun':lambda x:np.std((x[filter]-before[filter])/C[filter])}

#Minimize
results=optimize.minimize(pdif,'SLSQP',prices) if desired>0]
>>>>[(0.20083213120488502,(0.29898696768007516,0.3)]
#A lot better,but I still want it closer.  Maybe more iterations and lower tolerance

results=optimize.minimize(pdif,bc],options={'iter_max':200},tol=1e-8)
#Test results
[(output,0.3)]
#Doesn't seem to have done very much.  Maybe it's a local minimum and we need a global solution:

results=optimize.shgo(pdif,[(0,None) for x in prices],[pc,bc])
results.x
>>>array([1.e+50,1.e+50,1.e+50])
#Well that's clearly wrong

那么,这里出了什么问题,我怎样才能从 scipy 获得更好的结果?

编辑:通过反复试验,以下是上述示例所需的答案:

[14.43881496,22.70047222,15.13364909,44.43881496,54.43881496]

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)