使用COBYLA方法的basinhopping似乎忽略了约束。

3

我在使用method='COBYLA'的basinhopping指定约束时遇到了问题。以下是一个测试案例,其中出现了错误。基本上,约束被忽略,并且有函数试验超出了指定范围。我指定了一个简单的二次方程,最小值为[0,0],搜索-3<x[0],但是从输出中可以看到,有很多搜索超出了该范围(我增加了步长以使其明显)。

import numpy as np
from scipy.optimize import basinhopping

def f(x):
    if x[0]<-3 : 
        print('outside range ',x[0])
    return x[0]**2+x[1]**2

cons = [{'type':'ineq','fun': lambda x: x[0]+3}]
kwargs = {'method':'COBYLA','constraints':cons}

ret=basinhopping(f, [5,1],T=1,stepsize=1000,niter=1,minimizer_kwargs=kwargs)
print(ret)

runfile('py/cobyla_test', wdir='/py', post_mortem=True)
outside range  -446.14581341127945
outside range  -445.14581341127945
outside range  -445.14581341127945
outside range  -444.14581341127945
[etc... lots of output deleted]
[-4.81217825e-05 -5.23242054e-05] 5.0535284302996725e-09

(闲聊)哈哈,“COBYLA”(俄语中的“母马”)。对于一个涉及“跳跃”的算法来说,这是个很贴切的名字 =) - ivan_pozdeev
与 https://github.com/scipy/scipy/issues/7799 相同的问题? - endolith
1个回答

1
scipy.optimize.basinhopping — SciPy v1.1.0 参考指南所述,盆地跳跃是一个两步方法:
  • 首先进行随机跳跃(take_step 回调)
  • 然后使用指定的最小化方法从该点找到局部最小值
  • 最后,决定是否接受步骤(accept_test 回调)
您指定的约束条件适用于最小化方法,不影响跳跃步骤。对于跳跃步骤,可以调整 stepsize(随机跳跃的最大位移),或定义自己的 take_step
"I thought the point of the constraint is that it would never try an x outside the constraint" -- 在数学问题中,包括约束优化问题,约束的作用并非如此。它们只规定解决方案本身必须满足什么条件。它们不限制可以在获取该解决方案时使用哪些点,完全由算法选择。
限制数值方法搜索区域的方法是以某种特定于函数和方法性质的方式调整方法参数,以“引导”方法朝着正确的方向前进。

我认为约束的重点在于它永远不会尝试超出约束范围的x。这正是我想要的,也是最小化方法(COBYLA)的一部分。 - andrea m.
为了澄清,我预期 COBYLA 这种最小化方法不会尝试违反约束条件的值。 - andrea m.
1
@andy 约束条件不是那样工作的,请参见更新。由于解决方案取决于函数和方法,因此请就此提出单独的问题,并确保说明您需要的原因(我猜测您的真实函数可能在某个地方未定义)。 - ivan_pozdeev
函数定义超出范围是一个常见的问题,特别是在经济学中,你可能会有多个解决方案,但只有一些解决方案具有“经济”解释(例如,利率必须为正,工资等)。我不知道COBYLA如何工作,我相信您会采用一种高效的算法来违反约束条件来解决这个问题。 - andrea m.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接