scipy.optimize.basinhopping没有调用accept_test。为什么?

时间:2016-10-10 17:24:27

标签: python scipy mathematical-optimization

我正在尝试使用scipy basinhopping算法优化函数的输出。

def acceptance_criteria(self,**kwargs): 
    print "kwargs "
    print kwargs

    x = kwargs["x_new"]
    beta = x[0]
    alpha = [x[1],x[2],x[3],x[4],x[5],x[6]]
    print x
    inputnow= raw_input()
    beta_gamma_pass = beta != self.gamma
    beta_zero_pass = beta >= 0.0
    alpha1_pass = alpha[0] > 0.0
    alpha2_pass = alpha[1] > 0.0
    alpha3_pass = alpha[2] > 0.0
    alpha4_pass= alpha[3] > 0.0
    alpha5_pass= alpha[4] > 0.0
    alpha6_pass= alpha[5] > 0.0
    return  beta_gamma_pass,beta_zero_pass,alpha1_pass,alpha2_pass,alpha3_pass,alpha4_pass,alpha5_pass,alpha6_pass

def variational_calculation(self):
    minimizer_kwargs = {"method": "BFGS"}

    initial_paramater_guesses = [2,1.0,1.0/2.0,1.0/3.0,1.0/4.0,1.0/5.0,1.0/6.0]
    ret = basinhopping(self.Calculate, initial_paramater_guesses, minimizer_kwargs=minimizer_kwargs, niter=200, accept_test=self.acceptance_criteria)

我在计算函数中遇到了Nans和infs的问题。 这是由于使用了无效的参数值。 我试图通过使用验收标准来防止这种情况。 但是,购物流程不会调用accept_test函数。 因此,标准仍未完成。

任何人都可以帮助我解决为什么没有调整盆景来调用accept_test函数吗?

由于

编辑: 回应@ sascha的评论, 参数的分数幂和函数中的1 /参数项。 在这种情况下,不限制允许参数值的范围给出复数和inf值。 它实际上是一个特征值问题,我试图最小化一组18 * 18矩阵的特征值的轨迹。 矩阵元素以复杂的方式依赖于7个参数,具有许多非线性项。

我以前从未做过比多项式回归更复杂的事情,所以我对算法或它们的适用性一点也不熟悉。 但是,只要你避免在极点附近的参数值,我试图最小化的函数是平滑的;由1 /参数和1 /(参数^ n -constant)项引起。

EDIT2: 问题澄清 这里的问题与流域购物算法的适用性无关。

这就是为什么在2.7版本的python和scipy中,它的具体实现不会调用accept_test函数?

2 个答案:

答案 0 :(得分:1)

我无法说出为什么你的例子不起作用,但这里是一个类似但最小的例子,它调用了accept_test,也许你可以发现差异

NoMethodError: undefined method `success' for ...

答案 1 :(得分:1)

我知道这篇文章已经过时了,但谷歌仍然会出现这个问题。

我遇到了同样的问题,所以我通过稍微修改代码并添加计数器来进行测试。我的代码最小化了5个变量,但要求所有值都大于0.5

import numpy as np
from scipy.optimize import basinhopping
n = 0

def acceptance_criteria(**kwargs):
    print("in accept test")
    X = kwargs['x_new']
    for x in X:
        if x < .5:
            print('False!')
            return False
    return True

def f(x):
    global n
    print(n)
    n += 1
    return (x[0]**2-np.sin(x[1])*4+np.cos(x[2]**2)+np.sin(x[3]*5.0)-(x[4]**2 -3*x[4]**3))**2

if __name__ == '__main__':
    res = basinhopping(f,[.5]*5,accept_test=acceptance_criteria)

在进入acceptance_criteria函数之前需要大约100次迭代。

如果你正在优化一个需要很长时间才能运行的功能(就像我一样),那么你可能只需要给它更多的时间来进入acceptance_test。