Троичный поиск — различия между версиями
Murtaught (обсуждение | вклад) (Исправил ошибку в нерекурсивном варианте) |
Gfv (обсуждение | вклад) м (→Псевдокод) |
||
| Строка 24: | Строка 24: | ||
=== Псевдокод === | === Псевдокод === | ||
| − | ternarySearchMin(f, | + | ternarySearchMin(f, left, right, eps) |
| − | if ( | + | if (right - left < eps) |
return (left + right) / 2 | return (left + right) / 2 | ||
a = (left * 2 + right) / 3 | a = (left * 2 + right) / 3 | ||
b = (left + right * 2) / 3 | b = (left + right * 2) / 3 | ||
if (f(a) < f(b)) | if (f(a) < f(b)) | ||
| − | return ternarySearch(f, | + | return ternarySearch(f, left, b, eps) |
else | else | ||
| − | return ternarySearch(f, a, | + | return ternarySearch(f, a, right, eps) |
end | end | ||
Возможен и нерекурсивный вариант: | Возможен и нерекурсивный вариант: | ||
| − | ternarySearchMin(f, | + | ternarySearchMin(f, left, right, eps) |
| − | while ( | + | while (right - left > eps) |
{ | { | ||
a = (left * 2 + right) / 3 | a = (left * 2 + right) / 3 | ||
b = (left + right * 2) / 3 | b = (left + right * 2) / 3 | ||
if (f(a) < f(b)) | if (f(a) < f(b)) | ||
| − | + | right = b | |
else | else | ||
| − | + | left = a | |
} | } | ||
return (left + right) / 2 | return (left + right) / 2 | ||
end | end | ||
| − | |||
=== Время работы === | === Время работы === | ||
Версия 22:25, 12 июня 2013
Троичный поиск (или тернарный поиск) — метод поиска минимума или максимума функции на отрезке.
Алгоритм
Рассмотрим этот алгоритм на примере поиска минимума (поиск максимума аналогичен).Пусть функция на отрезке имеет минимум, и мы хотим найти точку , в которой он достигается.
Посчитаем значения функции в точках и .
Так как в точке минимум, то на отрезке функция убывает, а на — возрастает, то есть
.
Значит если , то , аналогично из следует . Тогда нам нужно изменить границы поиска и искать дальше, пока не будет достигнута необходимая точность, то есть .
Псевдокод
ternarySearchMin(f, left, right, eps)
if (right - left < eps)
return (left + right) / 2
a = (left * 2 + right) / 3
b = (left + right * 2) / 3
if (f(a) < f(b))
return ternarySearch(f, left, b, eps)
else
return ternarySearch(f, a, right, eps)
end
Возможен и нерекурсивный вариант:
ternarySearchMin(f, left, right, eps)
while (right - left > eps)
{
a = (left * 2 + right) / 3
b = (left + right * 2) / 3
if (f(a) < f(b))
right = b
else
left = a
}
return (left + right) / 2
end
Время работы
Так как на каждой итерации мы считаем два значения функции и уменьшаем область поиска в полтора раза, пока , то время работы алгоритма составит
Смотрите также
Есть оптимизация этого алгоритма, если делить отрезок не на равные части, а в отношении золотого сечения, — Поиск с помощью золотого сечения
Литература
Дональд Кнут Искусство программирования, том 3. Сортировка и поиск = The Art of Computer Programming, vol.3. Sorting and Searching.