Тема: Тернарный поиск
Доброго времени суток.
Кто что может сказать по тернарному поиску? Нигде подробного описания не нашел, нашел только, что им можно находить минимумы и максимумы функций - в принципе это мне и надо, но интересен сам метод.
Вы не вошли. Пожалуйста, войдите или зарегистрируйтесь.
MAXimal :: φορυμ » Algo » Тернарный поиск
Страницы 1
Чтобы отправить ответ, вы должны войти или зарегистрироваться
Доброго времени суток.
Кто что может сказать по тернарному поиску? Нигде подробного описания не нашел, нашел только, что им можно находить минимумы и максимумы функций - в принципе это мне и надо, но интересен сам метод.
Пусть дана функция f(x), унимодальная на некотором отрезке [l;r] (т.е. сначала строго возрастает, потом достигает максимума (в одной точке или целом отрезке), потом строго убывает; или наоборот: убывает, достигает минимума, возрастает). Будем рассматривать первый вариант, с максимумом, второй будет симметричен ему.
Итак, требуется найти максимум функции на отрезке [l;r]. Тогда возьмём любые две точки в этом отрезке: l < m1 < m2 < r. Посчитаем значения функции f(m1) и f(m2).
Если окажется, что f(m1) < f(m2), то искомый максимум не может находиться в левой части, т.е. в части [l;m1].
Если наоборот f(m1) > f(m2), то искомый максимум не может находиться в правой части, т.е. в части [m2;r].
Ну если f(m1) = f(m2), то по определению унимодальности это будет означать, что и m1, и m2 - точки максимума, поэтому этот случай можно произвольно отнести к первому или второму случаю.
В первом случае мы получаем, что дальше искать максимум есть смысл только в отрезке [m1;r], а во втором случае - в [l;m2]. Вот мы и нашли итерационный переход: как от отрезка [l;r] перейти к новому отрезку [l';r']. Всё, берём этот новый отрезок, в нём всё повторяем, переходим к следующему отрезку, и т.д. Рано или поздно длина отрезка станет маленькой (< заранее определённого EPS), и процесс можно останавливать - считать, например, что левый конец найденного отрезка и есть искомый максимум.
(если аргумент функции f целочисленный, то отрезок [l;r] тоже дискретный, но на корректность метода это не влияет; просто процесс надо будет останавливать, когда r-l < 3)
Наконец, осталось сказать, что точки m1 и m2 мы брали произвольными. На практике часто берут их так, чтобы [l;r] делилось на 3 равные части (потому что это проще всего написать), хотя никто не мешает брать точки m1 и m2 поближе друг к другу, чтобы ускорить сходимость.
Код:
double f (double x) {
...
}
double l = ..., r = ...;
while (r - l > EPS) { // или: for (int i=0; i<200; ++i) - задав большое количество итераций, нужная точность уж наверняка достигнется
double m1 = l + (r - l) / 3,
m2 = r - (r - l) / 3;
if (f (m1) < f (m2))
l = m1;
else
r = m2;
}
Можно говорить, что тернарный поиск - это обобщение бинарного поиска.
Тернарный поиск на практике можно применять и когда функция не строго убывает, а затем не строго возрастает. Но с 3-им случаем могут быть проблемы... Как повезет
Большое спасибо! Вышеописанный алгоритм можно применить, например, к этой задаче
http://acm.timus.ru/problem.aspx?space=1&num=1436
Страницы 1
Чтобы отправить ответ, вы должны войти или зарегистрироваться
MAXimal :: φορυμ » Algo » Тернарный поиск