【问题标题】:python optimising multiple functions with common variablespython用公共变量优化多个函数
【发布时间】:2014-03-13 06:05:04
【问题描述】:

我试图(全局)最小化 3 个使用公共变量的函数,我试图将它们组合成一个函数并使用 L-BFGS-B 最小化它(我需要为变量设置边界),但事实证明它是很难用权重平衡每个参数,即当一个参数被最小化时,另一个不会被最小化。我还尝试使用SLSQP 方法来最小化其中一个,同时将其他设置为约束,但这些约束通常被忽略/不满足。 以下是需要最小化的内容,所有数学运算都在 meritscalculation 中完成,meritoflengthmeritofROCmeritofproximityheightorderreturned 从计算中作为全局变量返回。

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(带边界)作为自变量来最小化所有这些,有没有办法实现这一点?

【问题讨论】:

    标签: scipy mathematical-optimization minimization


    【解决方案1】:

    这是你想做的吗?

    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() 之一比其他的要大? Plots 代替 prints 也很简单。

    总结:
    1) 在纸上清楚地表述问题,如顶部
    2) 将其翻译成 python。

    【讨论】:

    • 是的,这就是我想做的,所以这基本上是将权重纳入优化过程并让计算机进行平衡,对吧?而且每个merit() 函数之间也存在很大差异(大约1000 的顺序),这对a、b、c 的边界有何影响?还是[0.1, inf] 还是别的什么?无论如何,我现在正在测试这个方法,非常感谢你的努力,你一直很有帮助
    【解决方案2】:

    这是一些缩放和加权的结果

    目标函数:

    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)
    

    【讨论】:

    • tol = 1 ??试试 1e-4。仔细阅读basinhopping doc:“为了获得最佳结果T 应该与局部最小值之间的分离(函数值)相当”——它可能对 x0、stepsize ... 也很敏感。并且“权重倾向于保持在界限的最小值”:它们必须总和为 1 ?否则增加惩罚因子 100。
    • 我设置 tol=1 的原因是为了以较低的精度扫描更大的域(否则尝试最小化一个大值会浪费很多时间),然后我使用了第二个 minimize函数将第一次最小化返回的最小值提高到更高的精度
    • 对于高维问题,使用未知参数的工具,您不能期望在接近 0 的运行时间中获得良好的最小值。我建议从一个您知道答案的小问题开始,以获得有关函数值/运行时权衡的一些经验。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多