Троичный поиск — различия между версиями
м (rollbackEdits.php mass rollback) |
|||
(не показано 50 промежуточных версий 6 участников) | |||
Строка 1: | Строка 1: | ||
− | + | '''Троичный поиск''' (''ternary search, тернарный поиск'') {{---}} метод поиска минимума или максимума функции на отрезке, которая либо сначала строго возрастает, затем строго убывает, либо наоборот. | |
− | '''Троичный поиск''' {{---}} метод поиска минимума или максимума функции на отрезке. | + | == Алгоритм == |
− | + | [[File:Ternar2.png|thumb|280px|Пример. <tex>f(a) < f(b) \implies x_{min} \in [l, b]</tex>]] | |
− | + | Рассмотрим этот алгоритм на примере поиска минимума (поиск максимума аналогичен). | |
− | + | Пусть функция <tex>f(x)</tex> на отрезке <tex>[l, r]</tex> имеет минимум, и мы хотим найти точку <tex>x_{min}</tex>, в которой он достигается. | |
− | <tex> | ||
− | |||
− | |||
− | Значит <tex>f( | + | Посчитаем значения функции в точках <tex> a = l + \dfrac{(r-l)}{3} </tex> и <tex> b = l + \dfrac{2(r-l)}{3} </tex>. |
+ | |||
+ | Так как в точке <tex>x_{min}</tex> минимум, то на отрезке <tex>[l, x_{min}]</tex> функция убывает, а на <tex>[x_{min}, r]</tex> {{---}} возрастает, то есть | ||
+ | |||
+ | <tex> \forall x', x'' \in [l, r]: \\ | ||
+ | l < x' < x'' < x_{min} \implies f(l) > f(x') > f(x'') > f(x_{min}) \\ | ||
+ | x_{min} < x' < x'' < r \implies f(x_{min}) < f(x') < f(x'') < f(r) </tex>. | ||
+ | |||
+ | Значит если <tex>f(a) < f(b)</tex>, то <tex>x_{min} \in [l, b]</tex>, | ||
+ | аналогично из <tex>f(a) > f(b)</tex> следует <tex> x_{min} \in [a, r]</tex>. | ||
+ | |||
+ | Тогда нам нужно изменить границы поиска и искать дальше, | ||
+ | пока не будет достигнута необходимая точность, то есть <tex> r-l < \varepsilon </tex>. | ||
+ | |||
+ | Из рассуждений и рисунка может возникнуть идея взять, например, отрезок <tex>[l, a]</tex> вместо отрезка <tex>[l, b]</tex>. Но этого делать нельзя, потому что мы не умеем различать случаи, когда <tex>f(a) < f(b)</tex> и <tex>a</tex> слева или справа от минимума. | ||
+ | |||
+ | Можно заметить, что если мы всегда будем брать отрезок <tex>[l, b]</tex> при <tex>f(a) < f(b)</tex> или <tex>[a, r]</tex> при <tex>f(a) > f(b)</tex> , то минимум функции всегда будет в нашем отрезке. Если <tex>f(a) = f(b)</tex>, то можно взять любой отрезок. | ||
+ | |||
+ | === Псевдокод === | ||
+ | |||
+ | Рекурсивный вариант: | ||
+ | |||
+ | '''double''' ternarySearchMin('''double''' f(), '''double''' left, '''double''' right, '''double''' 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''' ternarySearchMin(f, left, b, eps) | ||
+ | '''else''' | ||
+ | '''return''' ternarySearchMin(f, a, right, eps) | ||
+ | |||
+ | Итеративный вариант: | ||
+ | |||
+ | '''double''' ternarySearchMin('''double''' f(), '''double''' left, '''double''' right, '''double''' 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 | ||
+ | |||
+ | === Время работы === | ||
+ | |||
+ | Так как на каждой итерации мы считаем два значения функции и уменьшаем область поиска в полтора раза, пока <tex> r - l > \varepsilon</tex>, | ||
+ | то время работы алгоритма составит | ||
+ | <tex dpi = "135">2 \log_{\frac32} \left(\dfrac{r - l}{\varepsilon}\right)</tex> | ||
+ | |||
+ | == См. также == | ||
+ | |||
+ | * [[Поиск с помощью золотого сечения]] | ||
+ | |||
+ | == Источники информации == | ||
+ | |||
+ | * Дональд Кнут {{---}} Искусство программирования. Том 3. Сортировка и поиск. / Knuth D.E. {{---}} The Art of Computer Programming. Vol. 3. Sorting and Searching. | ||
+ | * [[wikipedia:ru:Троичный поиск|Троичный поиск — Википедия]] | ||
+ | * [[wikipedia:Ternary search|Ternary search {{---}} Wikipedia]] | ||
+ | |||
+ | [[Категория: Дискретная математика и алгоритмы]] | ||
+ | [[Категория: Алгоритмы поиска]] |
Текущая версия на 19:05, 4 сентября 2022
Троичный поиск (ternary search, тернарный поиск) — метод поиска минимума или максимума функции на отрезке, которая либо сначала строго возрастает, затем строго убывает, либо наоборот.
Алгоритм
Рассмотрим этот алгоритм на примере поиска минимума (поиск максимума аналогичен).
Пусть функция
на отрезке имеет минимум, и мы хотим найти точку , в которой он достигается.Посчитаем значения функции в точках
и .Так как в точке
минимум, то на отрезке функция убывает, а на — возрастает, то есть.
Значит если
, то , аналогично из следует .Тогда нам нужно изменить границы поиска и искать дальше, пока не будет достигнута необходимая точность, то есть
.Из рассуждений и рисунка может возникнуть идея взять, например, отрезок
вместо отрезка . Но этого делать нельзя, потому что мы не умеем различать случаи, когда и слева или справа от минимума.Можно заметить, что если мы всегда будем брать отрезок
при или при , то минимум функции всегда будет в нашем отрезке. Если , то можно взять любой отрезок.Псевдокод
Рекурсивный вариант:
double ternarySearchMin(double f(), double left, double right, double 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 ternarySearchMin(f, left, b, eps) else return ternarySearchMin(f, a, right, eps)
Итеративный вариант:
double ternarySearchMin(double f(), double left, double right, double 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
Время работы
Так как на каждой итерации мы считаем два значения функции и уменьшаем область поиска в полтора раза, пока
, то время работы алгоритма составитСм. также
Источники информации
- Дональд Кнут — Искусство программирования. Том 3. Сортировка и поиск. / Knuth D.E. — The Art of Computer Programming. Vol. 3. Sorting and Searching.
- Троичный поиск — Википедия
- Ternary search — Wikipedia