Поиск с помощью золотого сечения — различия между версиями
(знак неравенства в условии выхода их цикла стоял неверный) |
Antonkov (обсуждение | вклад) |
||
Строка 8: | Строка 8: | ||
Точки <tex>x_1</tex> и <tex>x_2</tex> разбивают отрезок на три части. Потребуем, чтобы одновременно выполнялось: | Точки <tex>x_1</tex> и <tex>x_2</tex> разбивают отрезок на три части. Потребуем, чтобы одновременно выполнялось: | ||
− | <tex> \frac{a + b}{c} = \frac{b + c}{a} = \ | + | <tex> \frac{a + b}{c} = \frac{b + c}{a} = \varphi </tex> |
− | <tex> \frac{a}{b} = \ | + | <tex> \frac{a}{b} = \varphi </tex> |
− | <tex> \frac{c}{b} = \ | + | <tex> \frac{c}{b} = \varphi </tex> |
− | Где <tex> \ | + | Где <tex> \varphi </tex> - это некоторое отношение, в котором мы делим отрезок (точки <tex>x_1</tex> и <tex>x_2</tex> разбивают отрезок симметрично). |
Тогда: | Тогда: | ||
− | <tex> a + b = \ | + | <tex> a + b = \varphi c, a = \varphi b, c = \varphi b</tex>, откуда получаем <tex> \varphi + 1 = \varphi^2 \Rightarrow \varphi = \frac{1 + \sqrt{5}}{2}</tex> (тот корень уравнения, который меньше нуля, по понятным причинам отбросили). |
Это число совпадает с золотым сечением. Отсюда название метода. | Это число совпадает с золотым сечением. Отсюда название метода. | ||
Строка 24: | Строка 24: | ||
Для реализации алгоритма нам потребуется найти <tex> a </tex> и <tex> a + b </tex>. Если <tex> L </tex> - длина исследуемого отрезка, тогда: | Для реализации алгоритма нам потребуется найти <tex> a </tex> и <tex> a + b </tex>. Если <tex> L </tex> - длина исследуемого отрезка, тогда: | ||
− | <tex> (\frac{b + c}{a} = \ | + | <tex> (\frac{b + c}{a} = \varphi;\; b + c = L - a) \Rightarrow</tex> |
− | <tex> a = \frac{L}{\ | + | <tex> a = \frac{L}{\varphi + 1} </tex> |
− | <tex> a + b = L - c = L - a = L - \frac{L}{\ | + | <tex> a + b = L - c = L - a = L - \frac{L}{\varphi + 1}</tex> |
− | Причем, заметим что в силу того что <tex>\ | + | Причем, заметим что в силу того что <tex>\varphi</tex> - золотое сечение, то <tex>\frac{1}{\varphi + 1} = 2 - \varphi</tex>. |
Формально для поиска минимума (для максимума - делается аналогично) функции <tex> f </tex> делаем следующее: | Формально для поиска минимума (для максимума - делается аналогично) функции <tex> f </tex> делаем следующее: | ||
Строка 36: | Строка 36: | ||
:'''Шаг 1''': | :'''Шаг 1''': | ||
::Определяем границы поиска <tex>lbound</tex> и <tex>rbound</tex>, затем устанавливаем текущее разбиение: | ::Определяем границы поиска <tex>lbound</tex> и <tex>rbound</tex>, затем устанавливаем текущее разбиение: | ||
− | ::<tex>x_1 = lbound + \frac{rbound - lbound}{\ | + | ::<tex>x_1 = lbound + \frac{rbound - lbound}{\varphi + 1}</tex> |
− | ::<tex>x_2 = rbound - \frac{rbound - lbound}{\ | + | ::<tex>x_2 = rbound - \frac{rbound - lbound}{\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> | ||
[[Файл:Nextsection.gif|thumb|380px|Старая точка x1 уже делит отрезок в нужном отношении, поэтому нет необходимости вычислять ее заново (красным отмечены новые значения точек).]] | [[Файл:Nextsection.gif|thumb|380px|Старая точка x1 уже делит отрезок в нужном отношении, поэтому нет необходимости вычислять ее заново (красным отмечены новые значения точек).]] | ||
Строка 44: | Строка 44: | ||
::: <tex>rbound = x_2</tex> | ::: <tex>rbound = 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 = lbound + \frac{rbound - lbound}{\ | + | ::: <tex>x_1 = lbound + \frac{rbound - lbound}{\varphi + 1},\; f_1 = f(x_1)</tex> |
:: иначе: | :: иначе: | ||
::: <tex>lbound = x_1</tex> | ::: <tex>lbound = 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 = rbound - \frac{rbound - lbound}{\ | + | ::: <tex>x_2 = rbound - \frac{rbound - lbound}{\varphi + 1},\; f_2 = f(x_2)</tex> |
:'''Шаг 3''': | :'''Шаг 3''': | ||
:: если точность <tex>|rbound - lbound| < \varepsilon</tex> нас устраивает, тогда останавливаемся, и искомая точка <tex>x = \frac{lbound + rbound}{2}</tex>, иначе назад к шагу 2 | :: если точность <tex>|rbound - lbound| < \varepsilon</tex> нас устраивает, тогда останавливаемся, и искомая точка <tex>x = \frac{lbound + rbound}{2}</tex>, иначе назад к шагу 2 | ||
Строка 79: | Строка 79: | ||
return (x1 + x2) / 2 | return (x1 + x2) / 2 | ||
==Время работы== | ==Время работы== | ||
− | На каждой итерации исследуемый отрезок сокращается в <tex>\ | + | На каждой итерации исследуемый отрезок сокращается в <tex>\varphi</tex> раз и делается один расчет функции. Делается это до тех пор, пока не станет <tex>|L| < \varepsilon</tex>. Если считать, что одна итерация выполняется за 1 времени, то потребуется <tex> n </tex> операций, чтобы: <tex>L \cdot (\frac{1}{\varphi})^n < \varepsilon \Rightarrow n = [log_{\varphi}(\frac{L}{\varepsilon})]</tex>. |
− | Значит, время работы можно оценивать как <tex> log_{\ | + | Значит, время работы можно оценивать как <tex> log_{\varphi}(\frac{L}{\varepsilon})</tex>. |
Если удельный вес вычисления функции <tex> f </tex> достаточно большой, тогда получим ускорение работы примерно в 2,3 раз по сравнению с неулучшенным [[Троичный поиск|троичным поиском]]. | Если удельный вес вычисления функции <tex> f </tex> достаточно большой, тогда получим ускорение работы примерно в 2,3 раз по сравнению с неулучшенным [[Троичный поиск|троичным поиском]]. | ||
Версия 00:03, 12 мая 2012
Поиск с помощью золотого сечения (Golden section search) - это улучшение наивной реализации троичного поиска, служащий для поиска минимума/максимума функции. При простом троичном поиске на каждой итерации функция вычисляется в двух точках. Метод же золотого сечения требует вычисления лишь в одной точке (за исключением первой итерации). За счет этого достигается выигрыш в производительности.
Содержание
Алгоритм
Рассмотрим одну итерацию алгоритма троичного поиска. Попробуем подобрать такое разбиение отрезка на три части, чтобы на следующей итерации одна из точек нового разбиения совпала с одной из точек текущего разбиения. Тогда в следующий раз не придется считать функцию в двух точках, так как в одной она уже была посчитана.
Точки
и разбивают отрезок на три части. Потребуем, чтобы одновременно выполнялось:
Где
- это некоторое отношение, в котором мы делим отрезок (точки и разбивают отрезок симметрично).Тогда:
, откуда получаем (тот корень уравнения, который меньше нуля, по понятным причинам отбросили).
Это число совпадает с золотым сечением. Отсюда название метода.
Для реализации алгоритма нам потребуется найти
и . Если - длина исследуемого отрезка, тогда:
Причем, заметим что в силу того что
- золотое сечение, то .Формально для поиска минимума (для максимума - делается аналогично) функции
делаем следующее:- Шаг 1:
- Определяем границы поиска и , затем устанавливаем текущее разбиение:
- и вычислим функцию на них:
- Шаг 2:
- если
- иначе:
- если
- Шаг 3:
- если точность нас устраивает, тогда останавливаемся, и искомая точка , иначе назад к шагу 2
Псевдокод
phi = (1 + sqrt(5)) / 2 resphi = 2 - phi goldenSectionSearch(f, lbound, rbound, eps) x1 = lbound + resphi * (rbound - lbound) x2 = rbound - resphi * (rbound - lbound) f1 = f(x1) f2 = f(x2) do if f1 < f2: rbound = x2 x2 = x1 f2 = f1 x1 = lbound + resphi * (rbound - lbound) f1 = f(x1) else: lbound = x1 x1 = x2 f1 = f2 x2 = rbound - resphi * (rbound - lbound) f2 = f(x2) while (abs(rbound - lbound) > eps) return (x1 + x2) / 2
Время работы
На каждой итерации исследуемый отрезок сокращается в
раз и делается один расчет функции. Делается это до тех пор, пока не станет . Если считать, что одна итерация выполняется за 1 времени, то потребуется операций, чтобы: .Значит, время работы можно оценивать как троичным поиском.
. Если удельный вес вычисления функции достаточно большой, тогда получим ускорение работы примерно в 2,3 раз по сравнению с неулучшеннымСм также
Ссылки
- Wikipedia - Golden section search (english)