Поиск с помощью золотого сечения — различия между версиями
Antonkov (обсуждение | вклад) |
Antonkov (обсуждение | вклад) (→Алгоритм) |
||
| Строка 4: | Строка 4: | ||
Рассмотрим одну итерацию алгоритма [[Троичный поиск|троичного поиска]]. Попробуем подобрать такое разбиение отрезка на три части, чтобы на следующей итерации одна из точек нового разбиения совпала с одной из точек текущего разбиения. Тогда в следующий раз не придется считать функцию в двух точках, так как в одной она уже была посчитана. | Рассмотрим одну итерацию алгоритма [[Троичный поиск|троичного поиска]]. Попробуем подобрать такое разбиение отрезка на три части, чтобы на следующей итерации одна из точек нового разбиения совпала с одной из точек текущего разбиения. Тогда в следующий раз не придется считать функцию в двух точках, так как в одной она уже была посчитана. | ||
| − | + | Пусть <tex>l</tex> и <tex>r</tex> левая и правая граница исследуемого отрезка. | |
| − | Точки <tex>x_1</tex> и <tex>x_2</tex> разбивают отрезок на три части. Потребуем, чтобы одновременно выполнялось: | + | Точки <tex>x_1</tex> и <tex>x_2</tex> разбивают отрезок на три части, длины <tex>a, b, c</tex> соответственно. Потребуем, чтобы одновременно выполнялось: |
<tex> \frac{a + b}{c} = \frac{b + c}{a} = \varphi </tex> | <tex> \frac{a + b}{c} = \frac{b + c}{a} = \varphi </tex> | ||
| Строка 36: | Строка 36: | ||
:'''Шаг 1''': | :'''Шаг 1''': | ||
::Определяем границы поиска <tex>lbound</tex> и <tex>rbound</tex>, затем устанавливаем текущее разбиение: | ::Определяем границы поиска <tex>lbound</tex> и <tex>rbound</tex>, затем устанавливаем текущее разбиение: | ||
| − | ::<tex>x_1 = | + | ::<tex>x_1 = l + \frac{r - l}{\varphi + 1}</tex> |
| − | ::<tex>x_2 = | + | ::<tex>x_2 = r - \frac{r - l}{\varphi + 1}</tex> |
::и вычислим функцию на них: <tex>f_1 = f(x_1), f_2 = f(x_2)</tex> | ::и вычислим функцию на них: <tex>f_1 = f(x_1), f_2 = f(x_2)</tex> | ||
| − | |||
:'''Шаг 2''': | :'''Шаг 2''': | ||
:: если <tex>f_1 < f_2</tex>, тогда | :: если <tex>f_1 < f_2</tex>, тогда | ||
| − | ::: <tex> | + | ::: <tex>r = x_2</tex> |
::: <tex>x_2 = x_1, f_2 = f_1</tex> | ::: <tex>x_2 = x_1, f_2 = f_1</tex> | ||
| − | ::: <tex>x_1 = | + | ::: <tex>x_1 = l + \frac{r - l}{\varphi + 1},\; f_1 = f(x_1)</tex> |
:: иначе: | :: иначе: | ||
| − | ::: <tex> | + | ::: <tex>l = x_1</tex> |
::: <tex>x_1 = x_2, f_1 = f_2</tex> | ::: <tex>x_1 = x_2, f_1 = f_2</tex> | ||
| − | ::: <tex>x_2 = | + | ::: <tex>x_2 = r - \frac{r - l}{\varphi + 1},\; f_2 = f(x_2)</tex> |
:'''Шаг 3''': | :'''Шаг 3''': | ||
| − | :: если точность <tex>| | + | :: если точность <tex>|r - l| < \varepsilon</tex> нас устраивает, тогда останавливаемся, и искомая точка <tex>x = \frac{l + r}{2}</tex>, иначе назад к шагу 2 |
===Псевдокод=== | ===Псевдокод=== | ||
| Строка 56: | Строка 55: | ||
resphi = 2 - phi | resphi = 2 - phi | ||
| − | goldenSectionSearch(f, | + | goldenSectionSearch(f, l, r, eps) |
| − | x1 = | + | x1 = l + resphi * (r - l) |
| − | x2 = | + | x2 = r - resphi * (r - l) |
f1 = f(x1) | f1 = f(x1) | ||
f2 = f(x2) | f2 = f(x2) | ||
| Строка 64: | Строка 63: | ||
do | do | ||
if f1 < f2: | if f1 < f2: | ||
| − | + | r = x2 | |
x2 = x1 | x2 = x1 | ||
f2 = f1 | f2 = f1 | ||
| − | x1 = | + | x1 = l + resphi * (r - l) |
f1 = f(x1) | f1 = f(x1) | ||
else: | else: | ||
| − | + | l = x1 | |
x1 = x2 | x1 = x2 | ||
f1 = f2 | f1 = f2 | ||
| − | x2 = | + | x2 = r - resphi * (r - l) |
f2 = f(x2) | f2 = f(x2) | ||
| − | while (abs( | + | while (abs(r - l) > eps) |
return (x1 + x2) / 2 | return (x1 + x2) / 2 | ||
| + | |||
==Время работы== | ==Время работы== | ||
Так как на каждой итерации мы считаем два значения функции и уменьшаем область поиска в полтора раза, пока <tex> r - l > \varepsilon</tex>, | Так как на каждой итерации мы считаем два значения функции и уменьшаем область поиска в полтора раза, пока <tex> r - l > \varepsilon</tex>, | ||
Версия 00:43, 12 мая 2012
Поиск с помощью золотого сечения (Golden section search) - это улучшение наивной реализации троичного поиска, служащего для нахождения минимума/максимума функции. При простом троичном поиске на каждой итерации функция вычисляется в двух точках. Метод же золотого сечения требует вычисления лишь в одной точке (за исключением первой итерации). За счет этого достигается выигрыш в производительности.
Содержание
Алгоритм
Рассмотрим одну итерацию алгоритма троичного поиска. Попробуем подобрать такое разбиение отрезка на три части, чтобы на следующей итерации одна из точек нового разбиения совпала с одной из точек текущего разбиения. Тогда в следующий раз не придется считать функцию в двух точках, так как в одной она уже была посчитана.
Пусть и левая и правая граница исследуемого отрезка.
Точки и разбивают отрезок на три части, длины соответственно. Потребуем, чтобы одновременно выполнялось:
Где - это некоторое отношение, в котором мы делим отрезок (точки и разбивают отрезок симметрично).
Тогда:
, откуда получаем (тот корень уравнения, который меньше нуля, по понятным причинам отбросили).
Это число совпадает с золотым сечением. Отсюда название метода.
Для реализации алгоритма нам потребуется найти и . Если - длина исследуемого отрезка, тогда:
Причем, заметим что в силу того что - золотое сечение, то .
Формально для поиска минимума (для максимума - делается аналогично) функции делаем следующее:
- Шаг 1:
- Определяем границы поиска и , затем устанавливаем текущее разбиение:
- и вычислим функцию на них:
- Шаг 2:
- если , тогда
- иначе:
- если , тогда
- Шаг 3:
- если точность нас устраивает, тогда останавливаемся, и искомая точка , иначе назад к шагу 2
Псевдокод
phi = (1 + sqrt(5)) / 2
resphi = 2 - phi
goldenSectionSearch(f, l, r, eps)
x1 = l + resphi * (r - l)
x2 = r - resphi * (r - l)
f1 = f(x1)
f2 = f(x2)
do
if f1 < f2:
r = x2
x2 = x1
f2 = f1
x1 = l + resphi * (r - l)
f1 = f(x1)
else:
l = x1
x1 = x2
f1 = f2
x2 = r - resphi * (r - l)
f2 = f(x2)
while (abs(r - l) > eps)
return (x1 + x2) / 2
Время работы
Так как на каждой итерации мы считаем два значения функции и уменьшаем область поиска в полтора раза, пока , то время работы алгоритма составит
Так как на каждой итерации мы считаем одно значение функции и уменьшаем область поиска в раз, пока , то время работы алгоритма составит .
Если удельный вес вычисления функции достаточно большой, тогда получим ускорение работы примерно в 2,4 раз по сравнению с неулучшенным троичным поиском.
См также
Ссылки
- Wikipedia - Golden section search (english)