我试图最小化(全局)3个使用公共变量的函数,我试图将它们组合成一个函数并使用L-BFGS-B
最小化(我需要为变量设置边界),但它已经显示非常难以平衡每个参数与权重,即当一个参数最小化而另一个参数不是。我还尝试使用SLSQP
方法来最小化其中一个,同时将其他设置为约束,但是通常会忽略/不满足约束。
以下是需要最小化的内容,所有数学都在meritscalculation
完成,meritoflength
,meritofROC
,meritofproximity
,heightorderreturned
从计算中返回为全局变量
def lengthmerit(x0):
meritscalculation(x0)
print meritoflength
return meritoflength
def ROCmerit(x0):
meritscalculation(x0)
print meritofROC
return meritofROC
def proximitymerit(x0):
meritscalculation(x0)
print meritofproximity+heightorder
return meritofproximity+heightorder
我希望使用常见的x0(带边界)作为自变量来最小化所有这些,有没有办法实现这个目标?
答案 0 :(得分:2)
这是你想要做的吗?
minimize a * amerit(x) + b * bmerit(x) + c * cmerit(x)
over a, b, c, x:
a + b + c = 1
a >= 0.1, b >= 0.1, c >= 0.1 (say)
x in xbounds
如果x
说[x0 x1 .. x9]
,请设置新变量abcx = [a b c x0 x1 .. x9]
,
约束a + b + c = 1
并在目标函数中添加惩罚项,
并尽量减少这个:
define fabc( abcx ):
""" abcx = a, b, c, x
-> a * amerit(x) + ... + penalty 100 (a + b + c - 1)^2
"""
a, b, c, x = abcx[0], abcx[1], abcx[2], abcx[3:] # split
fa = a * amerit(x)
fb = b * bmerit(x)
fc = c * cmerit(x)
penalty = 100 * (a + b + c - 1) ** 2 # 100 ?
f = fa + fb + fc + penalty
print "fabc: %6.2g = %6.2g + %6.2g + %6.2g + %6.2g a b c: %6.2g %6.2g %6.2g" % (
f, fa, fb, fc, penalty, a, b, c )
return f
和bounds = [[0.1, 0.5]] * 3 + xbounds
,即每个a b c in 0.1 .. 0.5
左右
长print
s应该显示为什么 a b c
中的一个接近0 -
也许amerit() bmerit() cmerit()
中的一个比其他人大?
Plot
而不是print
也很容易。
要点:
1)在纸上清楚地表述问题,如上图所示
2)将其转换为python。
答案 1 :(得分:0)
这是一些缩放和加权的结果
目标函数:
merit_function=wa*meritoflength*1e3+wb*meritofROC+wc*meritofproximity+wd*heightorder*10+1000 * (wa+wb+wc+wd-1) ** 2
输入:
abcdex=np.array(( 0.5, 0.5, 0.1, 0.3, 0.1...))
输出:
fun: array([ 7.79494644])
x: array([ 4.00000000e-01, 2.50000000e-01, 1.00000000e-01,
2.50000000e-01...])
meritoflength : 0.00465499380753. #target 1e-5, usually start at 0.1
meritofROC: 23.7317956542 #target ~1, range <33
Heightorder: 0 #target :strictly 0, range <28
meritofproximity : 0.0 #target:less than 0.02, range <0.052
我意识到经过几次运行后,所有的权重都倾向于保持在界限的最小值,并且我回到手动调整我开始的缩放问题。
我的优化功能是否有可能找不到真正的全局最小值?
这是我如何最小化它:
minimizer_kwargs = {"method": "L-BFGS-B", "bounds": bnds, "tol":1e0 }
ret = basinhopping(merit_function, abcdex, minimizer_kwargs=minimizer_kwargs, niter=10)
zoom = ret['x']
res = minimize(merit_function, zoom, method = 'L-BFGS-B', bounds=bnds, tol=1e-6)