<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Iliagri</id>
		<title>Викиконспекты - Вклад участника [ru]</title>
		<link rel="self" type="application/atom+xml" href="http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Iliagri"/>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/Iliagri"/>
		<updated>2026-04-04T16:36:02Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D1%81_%D0%BF%D0%BE%D0%BC%D0%BE%D1%89%D1%8C%D1%8E_%D0%B7%D0%BE%D0%BB%D0%BE%D1%82%D0%BE%D0%B3%D0%BE_%D1%81%D0%B5%D1%87%D0%B5%D0%BD%D0%B8%D1%8F&amp;diff=80800</id>
		<title>Поиск с помощью золотого сечения</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D1%81_%D0%BF%D0%BE%D0%BC%D0%BE%D1%89%D1%8C%D1%8E_%D0%B7%D0%BE%D0%BB%D0%BE%D1%82%D0%BE%D0%B3%D0%BE_%D1%81%D0%B5%D1%87%D0%B5%D0%BD%D0%B8%D1%8F&amp;diff=80800"/>
				<updated>2021-04-21T11:39:02Z</updated>
		
		<summary type="html">&lt;p&gt;Iliagri: /* Алгоритм */ Ошибки псевдокода&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Поиск с помощью золотого сечения''' (англ. ''Golden section search'') {{---}} это улучшение наивной реализации [[Троичный поиск|троичного поиска]], служащего для нахождения минимума/максимума функции. При простом троичном поиске на каждой итерации функция вычисляется в двух точках. Метод же золотого сечения требует вычисления лишь в одной точке (за исключением первой итерации). &lt;br /&gt;
&lt;br /&gt;
==Алгоритм==&lt;br /&gt;
===Мотивация===&lt;br /&gt;
Рассмотрим одну итерацию алгоритма [[Троичный поиск|троичного поиска]]. Попробуем подобрать такое разбиение отрезка на три части, чтобы на следующей итерации одна из точек нового разбиения совпала с одной из точек текущего разбиения. Тогда в следующий раз не придется считать функцию в двух точках, так как в одной она уже была посчитана. &lt;br /&gt;
&lt;br /&gt;
[[Файл:new_seg.gif|right|450px|Старая точка x1 уже делит отрезок в нужном отношении, поэтому нет необходимости вычислять ее заново (красным отмечены новые значения точек).]]&lt;br /&gt;
&lt;br /&gt;
Для этого нам потребуется, чтобы одновременно выполнялись равенства:  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; \dfrac{a + b}{c} = \dfrac{b + c}{a} = \varphi &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Расстояние от &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; до &amp;lt;tex&amp;gt;x1 = a + b - c = a' &amp;lt;/tex&amp;gt;, от &amp;lt;tex&amp;gt;x2 &amp;lt;/tex&amp;gt; до &amp;lt;tex&amp;gt; r = b = c'&amp;lt;/tex&amp;gt;, от &amp;lt;tex&amp;gt;х1 &amp;lt;/tex&amp;gt; до &amp;lt;tex&amp;gt; х2 = c - b = b'&amp;lt;/tex&amp;gt;. Т.е. если мы подставим &amp;lt;tex&amp;gt;a', b', c'&amp;lt;/tex&amp;gt; в старое соотношение &amp;lt;tex&amp;gt; \dfrac{a + b}{c} &amp;lt;/tex&amp;gt;, то получится &amp;lt;tex&amp;gt; \dfrac {a + b - c + c - b}{b} = \dfrac{a}{b}&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; \dfrac{a}{b} = \varphi &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; \dfrac{c}{b} = \varphi &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Где &amp;lt;tex&amp;gt; \varphi &amp;lt;/tex&amp;gt; {{---}} это некоторое отношение, в котором мы делим отрезок (точки &amp;lt;tex&amp;gt;x_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;x_2&amp;lt;/tex&amp;gt; разбивают отрезок симметрично).&lt;br /&gt;
&lt;br /&gt;
Тогда:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; a + b = \varphi c, a = \varphi b, c = \varphi b&amp;lt;/tex&amp;gt;, откуда получаем &amp;lt;tex&amp;gt; \varphi + 1 = \varphi^2 \Rightarrow \varphi = \dfrac{1 + \sqrt{5}}{2}&amp;lt;/tex&amp;gt;  &amp;amp;nbsp; (тот корень уравнения, который меньше нуля, по понятным причинам отбросили).&lt;br /&gt;
&lt;br /&gt;
Это число совпадает с золотым сечением. Отсюда название метода.&lt;br /&gt;
&lt;br /&gt;
===Свойства золотого сечения===&lt;br /&gt;
Для реализации алгоритма нам потребуется найти &amp;lt;tex&amp;gt; a &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; a + b &amp;lt;/tex&amp;gt;. Если &amp;lt;tex&amp;gt; L &amp;lt;/tex&amp;gt; {{---}} длина исследуемого отрезка, тогда: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; \left(\dfrac{b + c}{a} = \varphi;\; b + c = L - a \right) \Rightarrow&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; a = \dfrac{L}{\varphi + 1} &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; a + b = L - c = L - a = L - \dfrac{L}{\varphi + 1}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что в силу того, что &amp;lt;tex&amp;gt;\varphi&amp;lt;/tex&amp;gt; {{---}} золотое сечение, то &amp;lt;tex&amp;gt;\dfrac{1}{\varphi + 1} = 2 - \varphi&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Итоговый алгоритм выбора границ===&lt;br /&gt;
Формально для поиска минимума (для максимума {{---}} делается аналогично) функции &amp;lt;tex&amp;gt; f &amp;lt;/tex&amp;gt; делаем следующее:&lt;br /&gt;
&lt;br /&gt;
:'''Шаг 1''':&lt;br /&gt;
::Определяем границы поиска &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;, затем устанавливаем текущее разбиение:&lt;br /&gt;
::&amp;lt;tex&amp;gt;x_1 = l + \dfrac{r - l}{\varphi + 1}&amp;lt;/tex&amp;gt; &lt;br /&gt;
::&amp;lt;tex&amp;gt;x_2 = r - \dfrac{r - l}{\varphi + 1}&amp;lt;/tex&amp;gt;&lt;br /&gt;
::и вычислим функцию на них: &amp;lt;tex&amp;gt;f_1 = f(x_1), f_2 = f(x_2)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:'''Шаг 2''': &lt;br /&gt;
:: если &amp;lt;tex&amp;gt;f_1 &amp;lt; f_2&amp;lt;/tex&amp;gt;, тогда&lt;br /&gt;
::: &amp;lt;tex&amp;gt;r = x_2&amp;lt;/tex&amp;gt;&lt;br /&gt;
::: &amp;lt;tex&amp;gt;x_2 = x_1, f_2 = f_1&amp;lt;/tex&amp;gt;&lt;br /&gt;
::: &amp;lt;tex&amp;gt;x_1 = l + \dfrac{r - l}{\varphi + 1},\; f_1 = f(x_1)&amp;lt;/tex&amp;gt; &lt;br /&gt;
:: иначе:&lt;br /&gt;
::: &amp;lt;tex&amp;gt;l = x_1&amp;lt;/tex&amp;gt;&lt;br /&gt;
::: &amp;lt;tex&amp;gt;x_1 = x_2, f_1 = f_2&amp;lt;/tex&amp;gt;&lt;br /&gt;
::: &amp;lt;tex&amp;gt;x_2 = r - \dfrac{r - l}{\varphi + 1},\; f_2 = f(x_2)&amp;lt;/tex&amp;gt;&lt;br /&gt;
:'''Шаг 3''':&lt;br /&gt;
:: если точность &amp;lt;tex&amp;gt;|r - l| &amp;lt; \varepsilon&amp;lt;/tex&amp;gt; нас устраивает, тогда останавливаемся, и искомая точка &amp;lt;tex&amp;gt;x = \dfrac{l + r}{2}&amp;lt;/tex&amp;gt;, иначе назад к шагу 2&lt;br /&gt;
&lt;br /&gt;
===Псевдокод===&lt;br /&gt;
&lt;br /&gt;
 '''double''' goldenSectionSearch(f: '''double -&amp;gt; double''', l: '''double''', r: '''double''', eps: '''double'''):&lt;br /&gt;
     phi = (1 + sqrt(5)) / 2&lt;br /&gt;
     resphi = 2 - phi&lt;br /&gt;
     x1 = l + resphi * (r - l)&lt;br /&gt;
     x2 = r - resphi * (r - l)&lt;br /&gt;
     f1 = f(x1)&lt;br /&gt;
     f2 = f(x2)&lt;br /&gt;
     '''do'''&lt;br /&gt;
       '''if''' f1 &amp;lt; f2&lt;br /&gt;
         r = x2&lt;br /&gt;
         x2 = x1&lt;br /&gt;
         f2 = f1&lt;br /&gt;
         x1 = l + resphi * (r - l)&lt;br /&gt;
         f1 = f(x1)&lt;br /&gt;
       '''else'''&lt;br /&gt;
         l = x1&lt;br /&gt;
         x1 = x2&lt;br /&gt;
         f1 = f2&lt;br /&gt;
         x2 = r - resphi * (r - l)&lt;br /&gt;
         f2 = f(x2)&lt;br /&gt;
     '''while''' abs(r - l) &amp;lt; eps&lt;br /&gt;
     '''return''' (x1 + x2) / 2&lt;br /&gt;
&lt;br /&gt;
===Ошибки псевдокода===&lt;br /&gt;
1. Используются вычислительно-неустойчивые формулы.&lt;br /&gt;
2. Учитывается только абсолютная длина отрезка.&lt;br /&gt;
Подробнее:&lt;br /&gt;
http://mech.math.msu.su/~iliagri/zip/sem2book.pdf&lt;br /&gt;
&lt;br /&gt;
==Время работы==&lt;br /&gt;
Так как на каждой итерации мы считаем одно значение функции и уменьшаем область поиска в &amp;lt;tex&amp;gt; \varphi &amp;lt;/tex&amp;gt; раз, пока &amp;lt;tex&amp;gt; r - l &amp;gt; \varepsilon&amp;lt;/tex&amp;gt;,&lt;br /&gt;
то время работы алгоритма составит &lt;br /&gt;
&amp;lt;tex&amp;gt; \log_{\varphi}\left(\dfrac{r - l}{\varepsilon}\right)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если удельный вес вычисления функции &amp;lt;tex&amp;gt; f &amp;lt;/tex&amp;gt; достаточно большой, тогда получим ускорение работы по сравнению с неулучшенным [[Троичный поиск|троичным поиском]] (&amp;lt;tex&amp;gt; \log_{\varphi}\left(\dfrac{r - l}{\varepsilon}\right)&amp;lt;/tex&amp;gt; против &amp;lt;tex&amp;gt;2 \log_{\frac32} \left(\dfrac{r - l}{\varepsilon}\right)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
За счет этого достигается выигрыш в производительности, т.к. каждый новый отрезок в &amp;lt;tex&amp;gt;\approx 1.618 &amp;lt;/tex&amp;gt; раз короче предыдущего (против &amp;lt;tex&amp;gt;1.5&amp;lt;/tex&amp;gt; у троичного поиска) и сходится он в &amp;lt;tex&amp;gt;\log_{\frac32} \left(\dfrac{1 + \sqrt{5}}{2}\right) \approx 1.1868 &amp;lt;/tex&amp;gt; быстрее, чем в троичном поиске, соответственно, в &amp;lt;tex&amp;gt; \approx 2.3736 &amp;lt;/tex&amp;gt; раза меньше вычислений.  &lt;br /&gt;
&lt;br /&gt;
==См также==&lt;br /&gt;
*[[Троичный поиск]]&lt;br /&gt;
*[[Целочисленный двоичный поиск]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
*[http://ru.wikipedia.org/wiki/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B7%D0%BE%D0%BB%D0%BE%D1%82%D0%BE%D0%B3%D0%BE_%D1%81%D0%B5%D1%87%D0%B5%D0%BD%D0%B8%D1%8F Википедия {{---}} Метод золотого сечения]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Golden_section_search Wikipedia {{---}} Golden section search] &lt;br /&gt;
&lt;br /&gt;
[[Категория:Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория:Алгоритмы поиска]]&lt;/div&gt;</summary>
		<author><name>Iliagri</name></author>	</entry>

	</feed>