Scipy.optimize.minimize 函数导致错误的结果。等于初始值,1次迭代后停止
Scipy.optimize.minimize function results in wrong results. Equal to inital values, stops after 1 iteration
我正在尝试从 Scipy 执行最小化函数,但是我收到了错误的答案,并且在一次迭代后停止。
问题介绍:
当我得到这段代码时 运行 我想优化反应器的大小,因此变量基于此,但优化功能在这种情况下用于练习。它 returns 将所有变量作为函数求和时所有变量的最小值。但是,当将公式调整为 1/(所有变量)时,我期望所有变量的范围最大值,但我收到初始猜测值。
问题:
谁能解释一下我犯了什么错误以及如何使 minimize() 起作用,以便我可以在更复杂的情况下应用相同的方法?
提前致谢!爱可
编码:
def Optimization2(INPUT):
return 1/(INPUT[0]+INPUT[1]+INPUT[2]+INPUT[3]+INPUT[4])
# bounds
feed_bound = (1,150) #molar feed
P_bound = (1,93) #pressure
T_bound = (900,1150) #Temperature
L_bound = (0.1,4.5) #Length of reactor
D_bound = (0.01,0.2) #Diameter of reactor
bnds = (feed_bound, P_bound,T_bound,L_bound,D_bound)
# initial guesses
feed = 100# np.mean(feed_bound)
P = 93#np.mean(P_bound)
T = 1050
L = np.mean(L_bound)
D = np.mean(D_bound)
INPUT_0= [feed,P,T,L,D]
print(INPUT_0)
Initial = Optimization2(INPUT_0)
# show initial objective
print('Initial Objective: ' + str(Optimization2(INPUT_0)))
solution = minimize(Optimization2,bounds=bnds,method='SLSQP',\
x0=INPUT_0)
INPUT = solution.x
print(solution)
错误结果:
fun: 0.0008029516502663793
jac: array([-6.4472988e-07, -6.4472988e-07, -6.4472988e-07, -6.4472988e-07,
-6.4472988e-07])
message: 'Optimization terminated successfully'
nfev: 6
nit: 1
njev: 1
status: 0
success: True
x: array([1.00e+02, 9.30e+01, 1.05e+03, 2.30e+00, 1.05e-01])
如果您查看最小化文档,您会发现 a numerical tolerance argument tol
。将其设置为 1e-16
会使您的函数 运行 进行多次迭代,转换为每个变量的每个上限。
数值公差的默认值对于你的例子来说显然太高了,这意味着当例程试图估计导数时,它发现函数值的差异太小以至于它无法关心,所以它终止了优化循环。
回避这个问题的另一种方法是将可最小化函数乘以 1e9
的一个因子。想一想为什么把它作为练习是有意义的 ;)
我正在尝试从 Scipy 执行最小化函数,但是我收到了错误的答案,并且在一次迭代后停止。
问题介绍:
当我得到这段代码时 运行 我想优化反应器的大小,因此变量基于此,但优化功能在这种情况下用于练习。它 returns 将所有变量作为函数求和时所有变量的最小值。但是,当将公式调整为 1/(所有变量)时,我期望所有变量的范围最大值,但我收到初始猜测值。
问题:
谁能解释一下我犯了什么错误以及如何使 minimize() 起作用,以便我可以在更复杂的情况下应用相同的方法?
提前致谢!爱可
编码:
def Optimization2(INPUT):
return 1/(INPUT[0]+INPUT[1]+INPUT[2]+INPUT[3]+INPUT[4])
# bounds
feed_bound = (1,150) #molar feed
P_bound = (1,93) #pressure
T_bound = (900,1150) #Temperature
L_bound = (0.1,4.5) #Length of reactor
D_bound = (0.01,0.2) #Diameter of reactor
bnds = (feed_bound, P_bound,T_bound,L_bound,D_bound)
# initial guesses
feed = 100# np.mean(feed_bound)
P = 93#np.mean(P_bound)
T = 1050
L = np.mean(L_bound)
D = np.mean(D_bound)
INPUT_0= [feed,P,T,L,D]
print(INPUT_0)
Initial = Optimization2(INPUT_0)
# show initial objective
print('Initial Objective: ' + str(Optimization2(INPUT_0)))
solution = minimize(Optimization2,bounds=bnds,method='SLSQP',\
x0=INPUT_0)
INPUT = solution.x
print(solution)
错误结果:
fun: 0.0008029516502663793
jac: array([-6.4472988e-07, -6.4472988e-07, -6.4472988e-07, -6.4472988e-07,
-6.4472988e-07])
message: 'Optimization terminated successfully'
nfev: 6
nit: 1
njev: 1
status: 0
success: True
x: array([1.00e+02, 9.30e+01, 1.05e+03, 2.30e+00, 1.05e-01])
如果您查看最小化文档,您会发现 a numerical tolerance argument tol
。将其设置为 1e-16
会使您的函数 运行 进行多次迭代,转换为每个变量的每个上限。
数值公差的默认值对于你的例子来说显然太高了,这意味着当例程试图估计导数时,它发现函数值的差异太小以至于它无法关心,所以它终止了优化循环。
回避这个问题的另一种方法是将可最小化函数乘以 1e9
的一个因子。想一想为什么把它作为练习是有意义的 ;)