Алгоритм нахождения экстремумов унимодальной функции
Тернарный алгоритм поиска [1] — это метод в информатике для нахождения минимума или максимума унимодальной функции .
Функция
Предположим, что мы ищем максимум и знаем, что максимум лежит где-то между и . Для того, чтобы алгоритм был применим, должно быть некоторое значение , такое что
- для всех с , мы имеем , и
- для всех с , имеем .
Алгоритм
Пусть будет унимодальной функцией на некотором интервале . Возьмем любые две точки и на этом отрезке: . Тогда есть три возможности:
- если , то искомый максимум не может быть расположен слева – . Значит, максимум далее имеет смысл искать только в интервале
- если , то ситуация аналогична предыдущей с точностью до симметрии. Теперь требуемый максимум не может находиться в правой части – , поэтому переходим к отрезку
- если , то поиск следует вести в , но этот случай можно отнести к любому из двух предыдущих (в целях упрощения кода). Рано или поздно длина отрезка станет немного меньше заданной константы, и процесс можно будет остановить.
Точки выбора и :
- Порядок выполнения во времени
Рекурсивный алгоритм
def ternary_search ( f , left , right , absolute_precision ) -> float : """Слева и справа — текущие границы; максимум находится между ними. """ if abs ( right - left ) < absolute_precision : return ( left + right ) / 2 левая_третья = ( 2 * левая + правая ) / 3 правая_третья = ( левая + 2 * правая ) / 3 если f ( left_third ) < f ( right_third ): вернуть ternary_search ( f , left_third , right , absolute_precision ) иначе : вернуть ternary_search ( f , left , right_third , absolute_precision )
Итеративный алгоритм
def ternary_search ( f , left , right , absolute_precision ) -> float : """Найти максимум унимодальной функции f() в пределах [left, right]. Чтобы найти минимум, поменяйте местами оператор if/else или сравнение. """ while abs ( right - left ) >= absolute_precision : left_third = left + ( right - left ) / 3 right_third = right - ( right - left ) / 3 если f ( левая_третья ) < f ( правая_третья ): левая = левая_третья иначе : правая = правая_третья # Слева и справа — текущие границы; максимум между ними return ( слева + справа ) / 2
Смотрите также
Ссылки
- ^ "Тернарный поиск". cp-algorithms.com . Получено 21 августа 2023 г. .