bundles / scipy 1.17.1 / scipy / optimize / _basinhopping / basinhopping
function
scipy.optimize._basinhopping:basinhopping
Signature
def basinhopping ( func , x0 , niter = 100 , T = 1.0 , stepsize = 0.5 , minimizer_kwargs = None , take_step = None , accept_test = None , callback = None , interval = 50 , disp = False , niter_success = None , rng = None , * , target_accept_rate = 0.5 , stepwise_factor = 0.9 , seed = None ) Summary
Find the global minimum of a function using the basin-hopping algorithm.
Extended Summary
Basin-hopping is a two-phase method that combines a global stepping algorithm with local minimization at each step. Designed to mimic the natural process of energy minimization of clusters of atoms, it works well for similar problems with "funnel-like, but rugged" energy landscapes [5].
As the step-taking, step acceptance, and minimization methods are all customizable, this function can also be used to implement other two-phase methods.
Parameters
func: callable ``f(x, *args)``Function to be optimized.
argscan be passed as an optional item in the dictminimizer_kwargsx0: array_likeInitial guess.
niter: integer, optionalThe number of basin-hopping iterations. There will be a total of
niter + 1runs of the local minimizer.T: float, optionalThe "temperature" parameter for the acceptance or rejection criterion. Higher "temperatures" mean that larger jumps in function value will be accepted. For best results
Tshould be comparable to the separation (in function value) between local minima.stepsize: float, optionalMaximum step size for use in the random displacement.
minimizer_kwargs: dict, optionalExtra keyword arguments to be passed to the local minimizer scipy.optimize.minimize Some important options could be:
method
method
args
args
take_step: callable ``take_step(x)``, optionalReplace the default step-taking routine with this routine. The default step-taking routine is a random displacement of the coordinates, but other step-taking algorithms may be better for some systems.
take_stepcan optionally have the attributetake_step.stepsize. If this attribute exists, then basinhopping will adjusttake_step.stepsizein order to try to optimize the global minimum search.accept_test: callable, ``accept_test(f_new=f_new, x_new=x_new, f_old=fold, x_old=x_old)``, optionalDefine a test which will be used to judge whether to accept the step. This will be used in addition to the Metropolis test based on "temperature"
T. The acceptable return values are True, False, or"force accept". If any of the tests return False then the step is rejected. If the latter, then this will override any other tests in order to accept the step. This can be used, for example, to forcefully escape from a local minimum that basinhopping is trapped in.callback: callable, ``callback(x, f, accept)``, optionalA callback function which will be called for all minima found.
xandfare the coordinates and function value of the trial minimum, andacceptis whether that minimum was accepted. This can be used, for example, to save the lowest N minima found. Also,callbackcan be used to specify a user defined stop criterion by optionally returning True to stop the basinhopping routine.interval: integer, optionalinterval for how often to update the
stepsizedisp: bool, optionalSet to True to print status messages
niter_success: integer, optionalStop the run if the global minimum candidate remains the same for this number of iterations.
rng: {None, int, `numpy.random.Generator`}, optionalIf
rngis passed by keyword, types other than numpy.random.Generator are passed to numpy.random.default_rng to instantiate aGenerator. Ifrngis already aGeneratorinstance, then the provided instance is used. Specifyrngfor repeatable function behavior.If this argument is passed by position or
seedis passed by keyword, legacy behavior for the argumentseedapplies:If
seedis None (or numpy.random), the numpy.random.RandomState singleton is used.If
seedis an int, a newRandomStateinstance is used, seeded withseed.If
seedis already aGeneratororRandomStateinstance then that instance is used.
The random numbers generated only affect the default Metropolis
accept_testand the defaulttake_step. If you supply your owntake_stepandaccept_test, and these functions use random number generation, then those functions are responsible for the state of their random number generator.target_accept_rate: float, optionalThe target acceptance rate that is used to adjust the
stepsize. If the current acceptance rate is greater than the target, then thestepsizeis increased. Otherwise, it is decreased. Range is (0, 1). Default is 0.5.stepwise_factor: float, optionalThe
stepsizeis multiplied or divided by this stepwise factor upon each update. Range is (0, 1). Default is 0.9.
Returns
res: OptimizeResultThe optimization result represented as a OptimizeResult object. Important attributes are:
xthe solution array,funthe value of the function at the solution, andmessagewhich describes the cause of the termination. TheOptimizeResultobject returned by the selected minimizer at the lowest minimum is also contained within this object and can be accessed through thelowest_optimization_resultattribute.lowest_optimization_resultwill only be updated if a local minimization was successful. See OptimizeResult for a description of other attributes.
Notes
Basin-hopping is a stochastic algorithm which attempts to find the global minimum of a smooth scalar function of one or more variables [1] [2] [3] [4]. The algorithm in its current form was described by David Wales and Jonathan Doye [2] http://www-wales.ch.cam.ac.uk/.
The algorithm is iterative with each cycle composed of the following features
random perturbation of the coordinates
local minimization
accept or reject the new coordinates based on the minimized function value
The acceptance test used here is the Metropolis criterion of standard Monte Carlo algorithms, although there are many other possibilities [3].
This global minimization method has been shown to be extremely efficient for a wide variety of problems in physics and chemistry. It is particularly useful when the function has many minima separated by large barriers. See the Cambridge Cluster Database for databases of molecular systems that have been optimized primarily using basin-hopping. This database includes minimization problems exceeding 300 degrees of freedom.
See the free software program GMIN for a Fortran implementation of basin-hopping. This implementation has many variations of the procedure described above, including more advanced step taking algorithms and alternate acceptance criterion.
For stochastic global optimization there is no way to determine if the true global minimum has actually been found. Instead, as a consistency check, the algorithm can be run from a number of different random starting points to ensure the lowest minimum found in each example has converged to the global minimum. For this reason, basinhopping will by default simply run for the number of iterations niter and return the lowest minimum found. It is left to the user to ensure that this is in fact the global minimum.
Choosing stepsize: This is a crucial parameter in basinhopping and depends on the problem being solved. The step is chosen uniformly in the region from x0-stepsize to x0+stepsize, in each dimension. Ideally, it should be comparable to the typical separation (in argument values) between local minima of the function being optimized. basinhopping will, by default, adjust stepsize to find an optimal value, but this may take many iterations. You will get quicker results if you set a sensible initial value for stepsize.
Choosing T: The parameter T is the "temperature" used in the Metropolis criterion. Basinhopping steps are always accepted if func(xnew) < func(xold). Otherwise, they are accepted with probability
exp( -(func(xnew) - func(xold)) / T )So, for best results, T should to be comparable to the typical difference (in function values) between local minima. (The height of "walls" between local minima is irrelevant.)
If T is 0, the algorithm becomes Monotonic Basin-Hopping, in which all steps that increase energy are rejected.
Examples
The following example is a 1-D minimization problem, with many local minima superimposed on a parabola.import numpy as np from scipy.optimize import basinhopping func = lambda x: np.cos(14.5 * x - 0.3) + (x + 0.2) * x x0 = [1.]✓
minimizer_kwargs = {"method": "BFGS"} ret = basinhopping(func, x0, minimizer_kwargs=minimizer_kwargs, niter=200)✓
ret.x, ret.fun
✗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✓
minimizer_kwargs = {"method":"L-BFGS-B", "jac":True} x0 = [1.0, 1.0] ret = basinhopping(func2d, x0, minimizer_kwargs=minimizer_kwargs, niter=200) print("global minimum: x = [%.4f, %.4f], f(x) = %.4f" % (ret.x[0], ret.x[1], ret.fun))✓
class MyTakeStep: def __init__(self, stepsize=0.5): self.stepsize = stepsize self.rng = np.random.default_rng() def __call__(self, x): s = self.stepsize x[0] += self.rng.uniform(-2.*s, 2.*s) x[1:] += self.rng.uniform(-s, s, x[1:].shape) return x✓
mytakestep = MyTakeStep() ret = basinhopping(func2d, x0, minimizer_kwargs=minimizer_kwargs, niter=200, take_step=mytakestep) print("global minimum: x = [%.4f, %.4f], f(x) = %.4f" % (ret.x[0], ret.x[1], ret.fun))✓
def print_fun(x, f, accepted): print("at minimum %.4f accepted %d" % (f, int(accepted)))✓
rng = np.random.default_rng()
✓ret = basinhopping(func2d, x0, minimizer_kwargs=minimizer_kwargs, niter=10, callback=print_fun, rng=rng)✗
See also
- minimize
The local minimization function called once for each basinhopping step.
minimizer_kwargsis passed to this routine.
Aliases
-
scipy.optimize.basinhopping