How can I write bounds of parameters by using basinhopping?

前端 未结 2 655
佛祖请我去吃肉
佛祖请我去吃肉 2021-01-16 22:39

I have difficulty with writing the bounds of parameters in basinhopping.

(x0)=(a, b, c )

a = (0, 100)

b = (0, 0.100)

c = (0, 10)

from scipy.         


        
相关标签:
2条回答
  • 2021-01-16 23:09

    There are multiple approaches for this, each potentially behaving differently (common in non-convex global-optimization). The best approach always takes a-priori information about the optimization-problem into consideration!

    The most robust general approach (and in my opinion the best) would be a combination of:

    • A: inner level: bound-constrained local-search
    • B: outer level: bound-constrained steps

    The original author of this optimizer says, relying only on A (as done in both other answers as of now) might fail!

    Code:

    import numpy as np
    from scipy.optimize import basinhopping
    
    
    """ Example problem
        https://docs.scipy.org/doc/scipy-0.19.1/reference/generated/scipy.optimize.basinhopping.html
    """
    def func2d(x):
        f = np.cos(14.5 * x[0] - 0.3) + (x[1] + 0.2) * x[1] + (x[0] + 0.2) * x[0]
        df = np.zeros(2)
        df[0] = -14.5 * np.sin(14.5 * x[0] - 0.3) + 2. * x[0] + 0.2
        df[1] = 2. * x[1] + 0.2
        return f, df
    
    """ Example bounds """
    bx0 = (-0.175, 1.)
    bx1 = (-0.09, 1.)
    bounds = [bx0, bx1]
    
    """ Solve without bounds """
    minimizer_kwargs = {"method":"L-BFGS-B", "jac":True}
    x0 = [1.0, 1.0]
    ret = basinhopping(func2d, x0, minimizer_kwargs=minimizer_kwargs, niter=200)
    print(ret.message)
    print("unconstrained minimum: x = [%.4f, %.4f], f(x0) = %.4f" % (ret.x[0], ret.x[1],ret.fun))
    
    
    """ Custom step-function """
    class RandomDisplacementBounds(object):
        """random displacement with bounds:  see: https://stackoverflow.com/a/21967888/2320035
            Modified! (dropped acceptance-rejection sampling for a more specialized approach)
        """
        def __init__(self, xmin, xmax, stepsize=0.5):
            self.xmin = xmin
            self.xmax = xmax
            self.stepsize = stepsize
    
        def __call__(self, x):
            """take a random step but ensure the new position is within the bounds """
            min_step = np.maximum(self.xmin - x, -self.stepsize)
            max_step = np.minimum(self.xmax - x, self.stepsize)
    
            random_step = np.random.uniform(low=min_step, high=max_step, size=x.shape)
            xnew = x + random_step
    
            return xnew
    
    bounded_step = RandomDisplacementBounds(np.array([b[0] for b in bounds]), np.array([b[1] for b in bounds]))
    
    """ Custom optimizer """
    minimizer_kwargs = {"method":"L-BFGS-B", "jac":True, "bounds": bounds}
    
    """ Solve with bounds """
    x0 = [1.0, 1.0]
    ret = basinhopping(func2d, x0, minimizer_kwargs=minimizer_kwargs, niter=200, take_step=bounded_step)
    print(ret.message)
    print("constrained minimum: x = [%.4f, %.4f], f(x0) = %.4f" % (ret.x[0], ret.x[1],ret.fun))
    

    Output:

    ['requested number of basinhopping iterations completed successfully']
    unconstrained minimum: x = [-0.1951, -0.1000], f(x0) = -1.0109
    ['requested number of basinhopping iterations completed successfully']
    constrained minimum: x = [-0.1750, -0.0900], f(x0) = -0.9684
    
    0 讨论(0)
  • 2021-01-16 23:12

    You should use "bounds" parameter in minimizer_kwargs which is passing to scipy.optimize.minimize(). Here is an example:

    bnds = ((1, 100), (1, 100), (1,100))# your bounds
    
    def rmse(X):# your function
        a,b,c = X[0],X[1],X[2]
        return a**2+b**2+c**2
    
    x0 = [10., 10., 10.]
    minimizer_kwargs = { "method": "L-BFGS-B","bounds":bnds }
    ret = basinhopping(rmse, x0, minimizer_kwargs=minimizer_kwargs,niter=10)
    print("global minimum: a = %.4f, b = %.4f c = %.4f | f(x0) = %.4f" % (ret.x[0], ret.x[1], ret.x[2], ret.fun))
    

    The result is

    global minimum: a = 1.0000, b = 1.0000 c = 1.0000 | f(x0) = 3.0000

    Without boundaries it is (clear) 0,0,0

    0 讨论(0)
提交回复
热议问题