Редактировать 2: Метод, описанный в Jive Dadson, - лучший способ сделать это. Я оставляю свой ответ, поскольку его легче реализовать, если скорость не слишком большая проблема.
Использовать форму двоичного поиска в сочетании с аппроксимацией числовых производных.
Учитывая интервал [a, b], пусть x = (a + b) / 2
Пусть эпсилон будет чем-то очень маленьким.
Является ли (f (x + эпсилон) - f (x)) положительным? Если да, функция все еще растет в точке x, поэтому вы рекурсивно ищите интервал [x, b]
В противном случае ищите интервал [a, x].
Может быть проблема, если максимальное значение лежит между x и x + epsilon, но вы можете попробовать это.
Редактировать: Преимущество этого подхода состоит в том, что он использует известные свойства рассматриваемой функции. То есть, я предположил, что «n» -образный, вы имели в виду, увеличивая-макс-уменьшая. Вот код Python, который я написал для проверки алгоритма:
def f(x):
return -x * (x - 1.0)
def findMax(function, a, b, maxSlope):
x = (a + b) / 2.0
e = 0.0001
slope = (function(x + e) - function(x)) / e
if abs(slope) < maxSlope:
return x
if slope > 0:
return findMax(function, x, b, maxSlope)
else:
return findMax(function, a, x, maxSlope)
Набрав findMax(f, 0, 3, 0.01)
, вы получите 0.504
, если хотите.