Nehmen wir an, ich habe eine Funktion f
definiert im Intervall [0,1]
, die glatt ist und bis zu einem gewissen Punkt a
ansteigt, nach dem es anfängt zu sinken. Ich habe ein Gitter x[i]
in diesem Intervall, z.B. mit einer konstanten Schrittgröße von dx = 0.01
, und ich würde gerne herausfinden, welcher dieser Punkte den höchsten Wert hat, indem ich im Worst-Case-Szenario die kleinste Anzahl von Bewertungen von f
mache. Ich denke, dass ich viel besser als eine erschöpfende Suche tun kann, indem ich etwas anwende, das mit gradientenartigen Methoden inspiriert ist. Irgendwelche Ideen? Ich dachte an etwas wie eine binäre Suche vielleicht oder parabolische Methoden.Finde das globale Maximum in der letzten Anzahl der Berechnungen
Dies ist eine Halbierungsartige Methode I codiert:
def optimize(f, a, b, fa, fb, dx):
if b - a <= dx:
return a if fa > fb else b
else:
m1 = 0.5*(a + b)
m1 = _round(m1, a, dx)
fm1 = fa if m1 == a else f(m1)
m2 = m1 + dx
fm2 = fb if m2 == b else f(m2)
if fm2 >= fm1:
return optimize(f, m2, b, fm2, fb, dx)
else:
return optimize(f, a, m1, fa, fm1, dx)
def _round(x, a, dx, right = False):
return a + dx*(floor((x - a)/dx) + right)
Die Idee ist: Finden Sie die Mitte des Intervalls und berechnen m1
und m2
- die Punkte nach rechts und links von ihm. Wenn die Richtung dort zunimmt, gehen Sie für das rechte Intervall und machen Sie dasselbe, andernfalls gehen Sie nach links. Wenn das Intervall zu klein ist, vergleichen Sie einfach die Zahlen an den Enden. Dieser Algorithmus verwendet jedoch immer noch nicht die Stärke der Ableitungen an den von mir berechneten Punkten.
Vielleicht möchten Sie in etwas wie Nickel Met oder Simulated Annealing schauen – iedoc
@iedoc: Nein, das wäre eine schreckliche Overkill, wie die Funktion bekannt ist unimodal zu sein. –
Wie viele Gitterpunkte gibt es? –