basinhopping#
- scipy.optimize.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)[Quelle]#
Findet das globale Minimum einer Funktion mithilfe des Basin-Hopping-Algorithmus.
Basin-Hopping ist eine zweiphasige Methode, die einen globalen Schrittalgorithmus mit einer lokalen Minimierung in jedem Schritt kombiniert. Sie wurde entwickelt, um den natürlichen Prozess der Energie minimization von Atomclustern zu imitieren, und eignet sich gut für ähnliche Probleme mit „trichterförmigen, aber rauen“ Energielandschaften [5].
Da die Schrittauswahl, die Schrittakzeptanz und die Minimierungsmethoden alle anpassbar sind, kann diese Funktion auch zur Implementierung anderer zweiphasiger Methoden verwendet werden.
- Parameter:
- funccallable
f(x, *args) Zu optimierende Funktion.
argskann als optionales Element im Dict minimizer_kwargs übergeben werden.- x0array_like
Anfangsschätzung.
- niterinteger, optional
Die Anzahl der Basin-Hopping-Iterationen. Insgesamt werden
niter + 1Durchläufe des lokalen Minimierers durchgeführt.- Tfloat, optional
Der „Temperatur“-Parameter für das Akzeptanz- oder Ablehnkriterium. Höhere „Temperaturen“ bedeuten, dass größere Sprünge im Funktionswert akzeptiert werden. Für beste Ergebnisse sollte T vergleichbar mit der Trennung (im Funktionswert) zwischen lokalen Minima sein.
- stepsizefloat, optional
Maximale Schrittgröße für die zufällige Verschiebung.
- minimizer_kwargsdict, optional
Zusätzliche Schlüsselwortargumente, die an den lokalen Minimierer
scipy.optimize.minimizeübergeben werden. Einige wichtige Optionen könnten sein:- methodstr
Die Minimierungsmethode (z. B.
"L-BFGS-B").- argstuple
Zusätzliche Argumente, die an die Zielfunktion (func) und ihre Ableitungen (Jakobi-Matrix, Hesse-Matrix) übergeben werden.
- take_stepcallable
take_step(x), optional Ersetzt die Standard-Schrittroutine durch diese Routine. Die Standard-Schrittroutine ist eine zufällige Verschiebung der Koordinaten, aber andere Schrittalgorithmen können für einige Systeme besser geeignet sein. take_step kann optional das Attribut
take_step.stepsizehaben. Wenn dieses Attribut vorhanden ist, passtbasinhoppingtake_step.stepsizean, um die globale Minimumsuche zu optimieren.- accept_testcallable,
accept_test(f_new=f_new, x_new=x_new, f_old=fold, x_old=x_old), optional Definiert einen Test, der verwendet wird, um zu beurteilen, ob ein Schritt akzeptiert werden soll. Dieser wird zusätzlich zum Metropolis-Test basierend auf der „Temperatur“ T verwendet. Akzeptable Rückgabewerte sind True, False oder
"force accept". Wenn einer der Tests False zurückgibt, wird der Schritt abgelehnt. Im letzteren Fall werden alle anderen Tests überschrieben, um den Schritt zu akzeptieren. Dies kann beispielsweise verwendet werden, um aus einem lokalen Minimum auszubrechen, in dembasinhoppinggefangen ist.- callbackcallable,
callback(x, f, accept), optional Eine Callback-Funktion, die für alle gefundenen Minima aufgerufen wird.
xundfsind die Koordinaten und der Funktionswert des getesteten Minimums, undacceptgibt an, ob dieses Minimum akzeptiert wurde. Dies kann beispielsweise verwendet werden, um die N niedrigsten gefundenen Minima zu speichern. Außerdem kann callback verwendet werden, um ein benutzerdefiniertes Abbruchkriterium anzugeben, indem optional True zurückgegeben wird, um diebasinhopping-Routine zu stoppen.- intervalinteger, optional
Intervall, wie oft die stepsize aktualisiert werden soll.
- dispbool, optional
Auf True setzen, um Statusmeldungen auszugeben.
- niter_successinteger, optional
Beendet den Lauf, wenn der globale Kandidaten-Minimum für diese Anzahl von Iterationen unverändert bleibt.
- rng{None, int,
numpy.random.Generator}, optional Wenn rng als Schlüsselwort übergeben wird, werden andere Typen als
numpy.random.Generatorannumpy.random.default_rngübergeben, um einenGeneratorzu instanziieren. Wenn rng bereits eineGenerator-Instanz ist, dann wird die bereitgestellte Instanz verwendet. Geben Sie rng für reproduzierbares Funktionsverhalten an.Wenn dieses Argument positionsabhängig übergeben wird oder seed als Schlüsselwort übergeben wird, gilt das Legacy-Verhalten für das Argument seed.
Wenn seed None ist (oder
numpy.random), wird die Singleton-Instanz vonnumpy.random.RandomStateverwendet.Wenn seed eine Ganzzahl ist, wird eine neue
RandomState-Instanz mit seed verwendet.Wenn seed bereits eine
Generator- oderRandomState-Instanz ist, dann wird diese Instanz verwendet.
Geändert in Version 1.15.0: Als Teil des SPEC-007-Übergangs von der Verwendung von
numpy.random.RandomStatezunumpy.random.Generatorwurde dieses Schlüsselwort von seed zu rng geändert. Für eine Übergangszeit werden beide Schlüsselwörter weiterhin funktionieren, obwohl nur eines gleichzeitig angegeben werden kann. Nach der Übergangszeit geben Funktionsaufrufe mit dem Schlüsselwort seed Warnungen aus. Das Verhalten von seed und rng wird oben skizziert, aber nur das rng-Schlüsselwort sollte in neuem Code verwendet werden.Die generierten Zufallszahlen beeinflussen nur den Standard-Metropolis-Test accept_test und die Standard-Schrittroutine take_step. Wenn Sie Ihre eigene take_step und accept_test bereitstellen und diese Funktionen Zufallszahlengenerierung verwenden, sind diese Funktionen für den Zustand ihres Zufallszahlengenerators verantwortlich.
- target_accept_ratefloat, optional
Die Zielakzeptanzrate, die zur Anpassung der stepsize verwendet wird. Wenn die aktuelle Akzeptanzrate höher als das Ziel ist, wird die stepsize erhöht. Andernfalls wird sie verringert. Bereich ist (0, 1). Standard ist 0,5.
Hinzugefügt in Version 1.8.0.
- stepwise_factorfloat, optional
Die stepsize wird bei jeder Aktualisierung mit diesem schrittweisen Faktor multipliziert oder dividiert. Bereich ist (0, 1). Standard ist 0,9.
Hinzugefügt in Version 1.8.0.
- funccallable
- Rückgabe:
- resOptimizeResult
Das Optimierungsergebnis, dargestellt als
OptimizeResult-Objekt. Wichtige Attribute sind:xdas Lösungsarray,funder Funktionswert an der Lösung undmessage, das den Abbruchgrund beschreibt. Das von dem ausgewählten Minimierer am niedrigsten Minimum zurückgegebeneOptimizeResult-Objekt ist ebenfalls in diesem Objekt enthalten und über das Attributlowest_optimization_resultzugänglich.lowest_optimization_resultwird nur aktualisiert, wenn eine lokale Minimierung erfolgreich war. SieheOptimizeResultfür eine Beschreibung anderer Attribute.
Siehe auch
minimierenDie lokale Minimierungsfunktion, die einmal pro Basin-Hopping-Schritt aufgerufen wird. minimizer_kwargs wird an diese Routine übergeben.
Hinweise
Basin-Hopping ist ein stochastischer Algorithmus, der versucht, das globale Minimum einer glatten skalaren Funktion einer oder mehrerer Variablen zu finden [1] [2] [3] [4]. Der Algorithmus in seiner aktuellen Form wurde von David Wales und Jonathan Doye beschrieben [2] http://www-wales.ch.cam.ac.uk/.
Der Algorithmus ist iterativ, wobei jeder Zyklus aus folgenden Merkmalen besteht:
zufällige Störung der Koordinaten
lokale Minimierung
Akzeptieren oder Ablehnen der neuen Koordinaten basierend auf dem minimierten Funktionswert.
Der hier verwendete Akzeptanztest ist das Metropolis-Kriterium von Standard-Monte-Carlo-Algorithmen, obwohl es viele andere Möglichkeiten gibt [3].
Diese globale Minimierungsmethode hat sich für eine breite Palette von Problemen in Physik und Chemie als äußerst effizient erwiesen. Sie ist besonders nützlich, wenn die Funktion viele Minima aufweist, die durch große Barrieren getrennt sind. Siehe die Cambridge Cluster Database für Datenbanken molekularer Systeme, die hauptsächlich mit Basin-Hopping optimiert wurden. Diese Datenbank enthält Minimierungsprobleme mit über 300 Freiheitsgraden.
Siehe das kostenlose Softwareprogramm GMIN für eine Fortran-Implementierung von Basin-Hopping. Diese Implementierung bietet viele Variationen des oben beschriebenen Verfahrens, einschließlich fortschrittlicherer Schrittalgorithmen und alternativer Akzeptanzkriterien.
Für stochastische globale Optimierung gibt es keine Möglichkeit zu bestimmen, ob das wahre globale Minimum tatsächlich gefunden wurde. Stattdessen kann als Konsistenzprüfung der Algorithmus von einer Anzahl verschiedener zufälliger Startpunkte aus ausgeführt werden, um sicherzustellen, dass das in jedem Beispiel gefundene niedrigste Minimum zum globalen Minimum konvergiert ist. Aus diesem Grund wird
basinhoppingstandardmäßig einfach für die Anzahl der Iterationen niter ausgeführt und gibt das gefundene niedrigste Minimum zurück. Es liegt am Benutzer, sicherzustellen, dass dies tatsächlich das globale Minimum ist.Auswahl von stepsize: Dies ist ein entscheidender Parameter in
basinhoppingund hängt vom zu lösenden Problem ab. Der Schritt wird in jeder Dimension gleichmäßig im Bereich von x0-stepsize bis x0+stepsize gewählt. Idealerweise sollte er vergleichbar mit dem typischen Abstand (in Argumentwerten) zwischen lokalen Minima der zu optimierenden Funktion sein.basinhoppingpasst stepsize standardmäßig an, um einen optimalen Wert zu finden, dies kann jedoch viele Iterationen dauern. Sie erzielen schnellere Ergebnisse, wenn Sie einen sinnvollen Anfangswert fürstepsizefestlegen.Auswahl von T: Der Parameter T ist die „Temperatur“, die im Metropolis-Kriterium verwendet wird. Basin-Hopping-Schritte werden immer akzeptiert, wenn
func(xnew) < func(xold). Andernfalls werden sie mit der Wahrscheinlichkeit akzeptiert:exp( -(func(xnew) - func(xold)) / T )
Für beste Ergebnisse sollte T daher mit dem typischen Unterschied (in Funktionswerten) zwischen lokalen Minima vergleichbar sein. (Die Höhe der „Mauern“ zwischen lokalen Minima ist irrelevant.)
Wenn T 0 ist, wird der Algorithmus zu Monotonic Basin-Hopping, bei dem alle Schritte, die die Energie erhöhen, abgelehnt werden.
Hinzugefügt in Version 0.12.0.
Referenzen
[1]Wales, David J. 2003, Energy Landscapes, Cambridge University Press, Cambridge, UK.
[2] (1,2)Wales, D J, and Doye J P K, Global Optimization by Basin-Hopping and the Lowest Energy Structures of Lennard-Jones Clusters Containing up to 110 Atoms. Journal of Physical Chemistry A, 1997, 101, 5111.
[3] (1,2)Li, Z. and Scheraga, H. A., Monte Carlo-minimization approach to the multiple-minima problem in protein folding, Proc. Natl. Acad. Sci. USA, 1987, 84, 6611.
[4]Wales, D. J. and Scheraga, H. A., Global optimization of clusters, crystals, and biomolecules, Science, 1999, 285, 1368.
[5]Olson, B., Hashmi, I., Molloy, K., and Shehu1, A., Basin Hopping as a General and Versatile Optimization Framework for the Characterization of Biological Macromolecules, Advances in Artificial Intelligence, Volume 2012 (2012), Article ID 674832, DOI:10.1155/2012/674832
Beispiele
Das folgende Beispiel ist ein 1-D-Minimierungsproblem mit vielen lokalen Minima, die auf einer Parabel überlagert sind.
>>> 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.]
Basinhopping verwendet intern einen lokalen Minimierungsalgorithmus. Wir werden den Parameter minimizer_kwargs verwenden, um basinhopping mitzuteilen, welcher Algorithmus verwendet werden soll und wie dieser Minimierer konfiguriert werden soll. Dieser Parameter wird an
scipy.optimize.minimizeübergeben.>>> minimizer_kwargs = {"method": "BFGS"} >>> ret = basinhopping(func, x0, minimizer_kwargs=minimizer_kwargs, ... niter=200) >>> # the global minimum is: >>> ret.x, ret.fun -0.1951, -1.0009
Betrachten wir nun ein 2-D-Minimierungsproblem. Dieses Mal werden wir auch Gradienteninformationen verwenden, um die Suche erheblich zu beschleunigen.
>>> 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
Wir werden auch einen anderen lokalen Minimierungsalgorithmus verwenden. Außerdem müssen wir dem Minimierer mitteilen, dass unsere Funktion sowohl Energie als auch Gradient (Jakobi-Matrix) zurückgibt.
>>> 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)) global minimum: x = [-0.1951, -0.1000], f(x) = -1.0109
Hier ist ein Beispiel für die Verwendung einer benutzerdefinierten Schrittroutine. Stellen Sie sich vor, Sie möchten, dass die erste Koordinate größere Schritte als die übrigen Koordinaten macht. Dies kann wie folgt implementiert werden:
>>> 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
Da
MyTakeStep.stepsizeexistiert, wird basinhopping die Größe von stepsize anpassen, um die Suche zu optimieren. Wir verwenden dieselbe 2-D-Funktion wie zuvor.>>> 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)) global minimum: x = [-0.1951, -0.1000], f(x) = -1.0109
Nun ein Beispiel mit einer benutzerdefinierten Callback-Funktion, die den Wert jedes gefundenen Minimums ausgibt.
>>> def print_fun(x, f, accepted): ... print("at minimum %.4f accepted %d" % (f, int(accepted)))
Wir werden diesmal nur für 10 Basin-Hopping-Schritte laufen.
>>> rng = np.random.default_rng() >>> ret = basinhopping(func2d, x0, minimizer_kwargs=minimizer_kwargs, ... niter=10, callback=print_fun, rng=rng) at minimum 0.4159 accepted 1 at minimum -0.4317 accepted 1 at minimum -1.0109 accepted 1 at minimum -0.9073 accepted 1 at minimum -0.4317 accepted 0 at minimum -0.1021 accepted 1 at minimum -0.7425 accepted 1 at minimum -0.9073 accepted 1 at minimum -0.4317 accepted 0 at minimum -0.7425 accepted 1 at minimum -0.9073 accepted 1
Das Minimum bei -1,0109 ist tatsächlich das globale Minimum, das bereits in der 8. Iteration gefunden wurde.