我试图最小化函数0.5*(x^2+y^2)服从一系列(N=20)的不等式约束,形式为x a1+y a2+a3 z>;=1。溶液应在x=0.50251,y=-0.5846,z=0.36787左右。例程以消息“Optimization terminated successfully”终止,但超过一半的约束未得到遵守。我也尝试了不同的解决方案,结果是一样的。在
缩放目标函数会改变解,但不会收敛到预期的解。在
from scipy.optimize import minimize
import numpy as np
Pct=np.array([[-0.664, 3.179],[ 0.231, -2.044],[-2.493, 3.25 ],[ 0.497, -0.654],[-1.27, 1.248],[-1.185, 1.814],[-1.843, 4.386],[-1.616, 1.401],[ 0.052, -1.232],[-3.145, 0.404],[ 0.672, -1.655],[ 2.202, -1.888],[ 4.084, -1.067],[ 1.006, -1.671],[-2.255, 1.51 ],[-1.264, 1.663],[ 1.897, -2.217],[ 1.843, -1.276],[-1.693, 1.623],[ 2.297, -1.709]])
Sid=np.array([-1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1])
# func to be minimized
def OptFunc(x):
return 0.5*(x[0]**2+x[1]**2)
def JacOptFunc(x):
return np.array([x[0],x[1],0.0])
# Constraints
c=[]
for i in range(len(Sid)):
c+=[{'type': 'ineq', 'fun': lambda x: Sid[i]*(x[0]*Pct[i,0]+x[1]*Pct[i,1]+x[2])-1 }]
cons=tuple(c)
# start optimization
res = minimize(OptFunc,(0.3,-0.2,0.1),constraints=cons,method='SLSQP',jac=JacOptFunc)
#expected solution should be around
# [0.5025062702615434, -0.584685257866671, 0.36787016514022236]
print("-->",res.message)
print("solution ",res.x,flush=True)
print("Check Constraints")
cons=list(cons)
for i in range(len(cons)):
lokfun=c[i]['fun']
print("Constraint # ",i," value: ",lokfun(res.x))
预期结果就在附近 x=0.50251,y=-0.5846,z=0.36787 但我得到以下输出:
^{2}$
我对
scipy.optimize
知之甚少,但我可以发现一个问题问题是Python闭包是后期绑定的,这意味着每个约束中的
i
的值实际上是在循环完成后计算的。实际上,您实际上将相同(最后一个)约束施加了20次。见https://docs.python-guide.org/writing/gotchas/#late-binding-closures可能的解决方案:
^{pr2}$结果
相关问题 更多 >
编程相关推荐