我想优化具有许多变量的函数。
我在几个求解器中使用了optimize.minimize函数。 例如Nelder-Mead'(请参阅此处)
“鲍威尔”(见此处)
“ CG”(请参阅此处)
“ BFGS”(请参阅此处)
“牛顿-CG”(请参见此处)
'L-BFGS-B'(请参阅此处)
“ TNC”(请参见此处)
“ COBYLA”(请参阅此处)
导入scipy.optimize为优化 将numpy导入为np
""" test no 146"""
A = 0.1/730 # WACC / days
OI_init = 800
WAMC_init = 690
n=28
def f(params):
# print(params) # <-- you'll see that params is a NumPy array
y=np.zeros(n) #need to define first
x=np.zeros(n)
z=np.zeros(n)
OI=np.zeros(n)
OI[0] = OI_init
cons = np.ones(n)*100
wamc = np.ones(n)*690
#WAMC[0] = WAMC_init
x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7],x[8],x[9],x[10],x[11],x[12],x[13],\
x[14],x[15],x[16],x[17],x[18],x[19],x[20],x[21],x[22],x[23],x[24],x[25],x[26],x[27],\
y[0],y[1],y[2],y[3],y[4],y[5],y[6],y[7],y[8],y[9],y[10],y[11],y[12],y[13],\
y[14],y[15],y[16],y[17],y[18],y[19],y[20],y[21],y[22],y[23],y[24],y[25],y[26],y[27],\
z[0],z[1],z[2],z[3],z[4],z[5],z[6],z[7],z[8],z[9],z[10],z[11],z[12],z[13],\
z[14],z[15],z[16],z[17],z[18],z[19],z[20],z[21],z[22],z[23],z[24],z[25],z[26],z[27],\
= params # <-- for readability you may wish to assign names to the component variables
return A*((2*OI[0] + x[0] + y[0] + z[0] - cons[0])/\
(OI_init + x[0] + y[0]+z[0]) * (OI_init*wamc[0] + 688*x[0] \
+ 713*y[0]+627*z[0])) + 688*x[0] + 713*y[0]+627*z[0] \
+ sum ([A*(((2*(OI[i-1] + x[i-1] + y[i-1] + z[i-1] - cons[i-1]) + x[i] + y[i] + z[i] - cons[i]))/\
((OI[i-1] + x[i-1] + y[i-1] + z[i-1] - cons[i-1]) + x[i] + y[i]+z[i]) * ((OI[i-1] + x[i-1] + y[i-1] + z[i-1] - cons[i-1])*wamc[i-1] + 688*x[i] \
+ 713*y[i]+627*z[i])) + 688*x[i] + 713*y[i]+627*z[i] for i in range (1,n)])
a = (0,250) #bounds x
b = (0,300) #bounds y
c = (0,300) #bounds z
d = (a*28+b*28+c*28)
e=[(d[a], d[a+1]) for a in range(0,len(d),2)]
bnds = tuple(e)
initial_guess = np.ones(n*3)
cons = ({'type': 'ineq', 'fun': lambda x: x[0] + x[1] + x[2]+ x[3] + x[4] + \
x[5] + x[6] + x[7] + x[8] + x[9] + x[10] +x[11] +x[12]+x[13]+x[14]+ \
x[15]+x[16]+x[17]+x[18]+x[19]+x[20]+x[21] +x[22]+x[23] +x[24]+x[25] +x[26]+x[27]- 1800},\
{'type': 'ineq', 'fun': lambda y: y[0] + y[1] + y[2]+ y[3] + y[4] + \
y[5] + y[6] + y[7] + y[8] + y[9] + y[10] +y[11] +y[12]+y[13]+y[14]+ \
y[15]+y[16]+y[17]+y[18]+y[19]+y[20]+y[21] +y[22]+y[23] +y[24]+y[25] +y[26]+y[27] - 600},
{'type': 'ineq', 'fun': lambda z: z[0] + z[1] + z[2]+ z[3] + z[4] + \
z[5] + z[6] + z[7] + z[8] + z[9] + z[10] +z[11] +z[12]+z[13]+z[14]+ \
z[15]+z[16]+z[17]+z[18]+z[19]+z[20]+z[21] +z[22]+z[23] +z[24]+z[25] +z[26]+z[27] - 600})
result = optimize.minimize(f, initial_guess,method='COBYLA', bounds=bnds,constraints=cons,options={'rhobeg': 1.0, 'maxiter': 50000, 'disp': False, 'catol': 0.0002})
#result = optimize.minimize(f, initial_guess,method='Nelder-Mead' , bounds=bnds,constraints=cons)
if result.success:
fitted_params = result.x
print(fitted_params)
else:
raise ValueError(result.message)
我希望每个参数的值都在指定的范围之间(例如,对于x为0-250,对于y为0-300,等等) 但是,返回的值如下:
[64.36575819 64.36140615 64.1978667 64.19795296 66.70698926 64.19744574 64.1996505 64.20011174 64.19866534 64.19939097 64.19847749 64.19755442 64.19784017 64.78815603 64.19936531 64.19992768 64.19953347 64.19936411 64.10321118 64.1992067 64.19952948 64.19959002 64.19906142 64.19570926 64.19864776 64.19758665 64.19937635 64.16204073 -220.54936485 -220.5465085 -220.81683226 -220.25854439 -220.82215693 -220.44374353 -220.6326799 -218.76761632 -220.88232356 -221.06507529 -220.90425765 -220.44294542 -220.60071103 -221.05849399 -220.70571828 -221.12106582 -221.1196567 -221.53333488 -220.82655726 -220.59355591 -221.58765192 -221.04768086 -220.90414376 -220.25808954 -220.71251054 -221.34281041 -222.89489171 -220.46492692 -193.80092262 -193.83038434 -193.52419382 -193.6330308 -193.80679929 -194.88399831 -194.1795782 -193.8016101 -194.17360397 -194.06095671 -194.19153064 -193.76369698 -194.12841897 -193.46745685 -193.77441914 -194.17699638 -193.92509365 -193.70122136 -193.971702 -194.11101313 -194.17535903 -193.98580005 -193.47109855 -193.47078731 -193.41173464 -193.52010863 -195.12203737 -193.3681346]
即只有x在边界内,而y则z变为负值。
任何帮助将不胜感激。预先感谢。