Тернарний пошукПостановка задачіНехай дана функція , унімодальна на деякому відрізку . Під унімодальна розуміється один з двох варіантів. Перший: функція спочатку строго зростає, потім досягає максимуму (в одній точці або цілому відрізку), потім строго спадає. Другий варіант, симетричний: функція спочатку спадає, досягає мінімуму, зростає. Надалі ми будемо розглядати перший варіант, другий буде абсолютно симетричний йому. Потрібно знайти максимум функції на відрізку . АлгоритмВізьмемо будь-які дві точки і в цьому відрізку: . Порахуємо значення функції і .Далі у нас виходить три варіанти:
Таким чином, за результатом порівняння значень функції в двох внутрішніх точках ми замість поточного відрізка пошуку знаходимо новий відрізок . Повторимо тепер всі дії для цього нового відрізка, знову отримаємо новий, суворо менший, відрізок, і так далі. Втім, при іншому виборі, коли і ближче один до одного, швидкість збіжності збільшиться. Випадок цілочисельного аргументуЯкщо аргумент функції цілочисельний, то відрізок теж стає дискретним, але, оскільки ми не накладали ніяких обмежень на вибір точок і , то на коректність алгоритму це ніяк не впливає. Можна як і раніше вибирати і так, щоб вони ділили відрізок на 3 частини, але вже тільки приблизно рівні. Другий відмінний момент — критерій зупинки алгоритму. В даному випадку тернарний пошук треба буде зупиняти, коли стане , адже в такому випадку вже неможливо буде вибрати точки і так, щоб були різними і відрізнялися від і , і це може привести до зациклення. Після того, як алгоритм тернарного пошуку зупиниться і стане , з решти декількох точок треба вибрати точку з максимальним значенням функції. РеалізаціяРеалізація для безперервного випадку (тобто коли функція має вигляд: double l = ..., r = ..., EPS = ...;//вхідні дані
while (r - l > EPS) {
double m1 = l + (r - l) / 3,
m2 = r - (r - l) / 3;
if (f(m1) < f(m2))
l = m1;
else
r = m2;
}
Тут EPS — фактично, абсолютна похибка відповіді (не враховуючи похибок, пов'язаних з неточним обчисленням функції). Замість критерію « for (int it = 0; it < iterations; ++it)
З одного боку, доведеться підібрати константу , щоб забезпечити необхідну точність (зазвичай досить декількох сотень, щоб досягти максимальної точності). Зате, з іншого боку, число ітерацій перестає залежати від абсолютних величин і , тобто ми фактично за допомогою задаємо необхідну відносну похибку. |
Portal di Ensiklopedia Dunia