<?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=188.170.82.90&amp;*</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=188.170.82.90&amp;*"/>
		<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/188.170.82.90"/>
		<updated>2026-05-19T16:38:18Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%92%D0%B5%D1%89%D0%B5%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%B4%D0%B2%D0%BE%D0%B8%D1%87%D0%BD%D1%8B%D0%B9_%D0%BF%D0%BE%D0%B8%D1%81%D0%BA&amp;diff=65657</id>
		<title>Вещественный двоичный поиск</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%92%D0%B5%D1%89%D0%B5%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%B4%D0%B2%D0%BE%D0%B8%D1%87%D0%BD%D1%8B%D0%B9_%D0%BF%D0%BE%D0%B8%D1%81%D0%BA&amp;diff=65657"/>
				<updated>2018-05-17T11:35:51Z</updated>
		
		<summary type="html">&lt;p&gt;188.170.82.90: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Вещественный двоичный поиск''' (англ. ''Bisection method''){{---}} алгоритм поиска аргумента для заданного значения монотонной вещественной функции.&lt;br /&gt;
&lt;br /&gt;
== Формулировка задачи == &lt;br /&gt;
Пусть нам задана монотонная функция &amp;lt;tex&amp;gt; f &amp;lt;/tex&amp;gt; и какое-то значение &amp;lt;tex&amp;gt; C &amp;lt;/tex&amp;gt; этой функции. Необходимо найти значение аргумента &amp;lt;tex&amp;gt; x &amp;lt;/tex&amp;gt; этой функции, такое, что &amp;lt;tex&amp;gt; f(x) = C &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Function.png]]&lt;br /&gt;
&lt;br /&gt;
== Решение задачи ==&lt;br /&gt;
Применим идею [[целочисленный двоичный поиск | двоичного поиска]]. Выберем такие границы, где значение функции точно больше и точно меньше заданного значения. Выберем значение в середине этого отрезка. Если оно меньше, чем заданное, то сместим левую границу в середину отрезка. В противном случае сместим правую границу. Далее повторим процесс сужения границ. Встает вопрос, когда остановиться. Есть несколько способов сделать это.&lt;br /&gt;
&lt;br /&gt;
=== Способы закончить поиск ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Способы || Плюсы || Минусы || Оценка на число итераций&lt;br /&gt;
|-&lt;br /&gt;
| Окончание, когда рассматриваемый отрезок станет меньше заданной погрешности &amp;lt;tex&amp;gt; \varepsilon &amp;lt;/tex&amp;gt;. || Заданная точность найденного значения. || Алгоритм может зациклиться. В компьютере мы работаем с конечным числом вещественных чисел, у которых есть точность. При больших значениях функции длина отрезка может никогда не уменьшиться до заданного значения. || В данном случае нам нужно рассмотреть &amp;lt;tex dpi=130&amp;gt; \genfrac{}{}{}{}{R - L}{\varepsilon} &amp;lt;/tex&amp;gt; чисел &amp;lt;tex&amp;gt; \Rightarrow &amp;lt;/tex&amp;gt; примерное число итераций &amp;lt;tex dpi=130&amp;gt; \log(\genfrac{}{}{}{}{R - L}{\varepsilon}) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| Окончание, когда значение функции на концах отрезках различается менее, чем на заданную погрешность &amp;lt;tex&amp;gt; \varepsilon &amp;lt;/tex&amp;gt;. || Значение функции от найденного значения имеет заданную точность. || а) Возможна большая погрешность, если функция будет очень медленно возрастать. &amp;lt;br&amp;gt; б) Может зациклиться по той же причине, что и в первом способе. || Аналогичная с первым случаем логика, примерное число итераций &amp;lt;tex dpi=130&amp;gt; \log(\genfrac{}{}{}{}{f(R) - f(L)}{\varepsilon}) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| «Абсолютно точный поиск» &amp;lt;br&amp;gt; Окончание, когда границы отрезка — два соседних по представлению значения в типе данных. Утверждается, что два числа — соседние, если середина их отрезка совпадает или с левой, или с правой границей. || Максимально возможная точность найденного значения. || Возможно плохое поведение, если искомый аргумент равен нулю. || При работе с числами с плавающей точкой количество итераций зависит от плотности чисел на данном отрезке. При работе с числами фиксированной точности &amp;lt;tex&amp;gt;\varepsilon&amp;lt;/tex&amp;gt; количество итераций аналогично первому и второму случаю равно &amp;lt;tex dpi=130&amp;gt; \log(\genfrac{}{}{}{}{R - L}{\varepsilon}) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| «Итеративный способ» &amp;lt;br&amp;gt; Выполнение конечного числа итераций. || У способа фиксированная погрешность. || Довольно плохая точность, если границы отрезка находятся на большом расстоянии. || Выполняется заданное количество итераций.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Выбор границы отрезка для поиска ===&lt;br /&gt;
Для начала найдем левую границу, выберем произвольную отрицательную точку (например &amp;lt;tex&amp;gt;-1&amp;lt;/tex&amp;gt;). Будем удваивать ее до тех пор, пока значение в ней будет больше заданного значения. Для того, чтобы найти правую границу, выберем произвольную положительную точку (например &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;). Будем удваивать ее до тех пор, пока значение функции в этой точке меньше заданного.&lt;br /&gt;
&lt;br /&gt;
== Псевдокод ==&lt;br /&gt;
 '''double''' findLeftBoard(C : '''double'''): &lt;br /&gt;
     x = -1&lt;br /&gt;
     '''while''' f(x) &amp;gt; C &lt;br /&gt;
         x = x * 2&lt;br /&gt;
     '''return''' x &lt;br /&gt;
&lt;br /&gt;
.&lt;br /&gt;
&lt;br /&gt;
 '''double''' findRightBoard(C : '''double'''):&lt;br /&gt;
     x = 1&lt;br /&gt;
     '''while''' f(x) &amp;lt; C&lt;br /&gt;
         x = x * 2&lt;br /&gt;
     '''return''' x&lt;br /&gt;
.&lt;br /&gt;
&lt;br /&gt;
 '''double''' binSearch(C : '''double'''):&lt;br /&gt;
     left = findLeftBoard(C)&lt;br /&gt;
     right = findRightBoard(C)&lt;br /&gt;
     '''while''' right - left &amp;lt; eps        &amp;lt;font color=green&amp;gt; // Здесь можно использовать другое условие выхода &amp;lt;/font&amp;gt;&lt;br /&gt;
         mid = (left + right) / 2&lt;br /&gt;
         '''if''' f(mid) &amp;lt; C&lt;br /&gt;
             left = mid&lt;br /&gt;
         '''else'''&lt;br /&gt;
             right = mid&lt;br /&gt;
     '''return''' (left + right) / 2&lt;br /&gt;
&lt;br /&gt;
.&lt;br /&gt;
&lt;br /&gt;
== Метод секущих ==&lt;br /&gt;
[[Файл:Secant method.png|thumb|350px|right|Метод секущих при &amp;lt;tex&amp;gt; C = 0 &amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
Итерационный численный метод приближённого нахождения корня уравнения.&lt;br /&gt;
&lt;br /&gt;
=== Алгоритм ===&lt;br /&gt;
Пусть нам задана монотонная &amp;lt;tex&amp;gt; f &amp;lt;/tex&amp;gt; и значение &amp;lt;tex&amp;gt; C &amp;lt;/tex&amp;gt;. Выберем две начальные точки, причем &amp;lt;tex&amp;gt; f(x_{1}) &amp;lt; C &amp;lt;/tex&amp;gt;, а &amp;lt;tex&amp;gt; f(x_{2}) &amp;gt; C &amp;lt;/tex&amp;gt;. Проведем через них прямую, которая пересечет прямую &amp;lt;tex&amp;gt; y = C &amp;lt;/tex&amp;gt; в точке &amp;lt;tex&amp;gt; (x_{3}, C) &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; возьмем точки &amp;lt;tex&amp;gt; x_{3} &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; x_{2} &amp;lt;/tex&amp;gt;, и проделаем ту же операцию и так далее, получая точки &amp;lt;tex&amp;gt; x_{n+1} &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; x_{n} &amp;lt;/tex&amp;gt;, пока &amp;lt;tex&amp;gt;  |x_{n-1} - x_{n}| &amp;gt; \varepsilon &amp;lt;/tex&amp;gt;.&lt;br /&gt;
Вычисляем каждое последующее значение &amp;lt;tex&amp;gt; x_{n+1} &amp;lt;/tex&amp;gt; с помощью формулы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex dpi=130&amp;gt; x_{n+1} = x_{n-1} + \dfrac{(C - f(x_{n}))\cdot(x_{n} - x_{n-1})}{f(x_{n}) - f(x_{n-1})} &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нахождение нулей функции &amp;lt;tex&amp;gt;(C = 0)&amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex dpi=130&amp;gt; x_{n+1} = x_{n-1} - \dfrac{f(x_{n})\cdot(x_{n} - x_{n-1})}{f(x_{n}) - f(x_{n-1})} &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод ===&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 '''double''' search (a : '''double''', b : '''double''', eps : '''double'''):        &amp;lt;font color=green&amp;gt; // Где a {{---}} левая граница, а b {{---}} правая &amp;lt;/font&amp;gt;&lt;br /&gt;
     '''while''' |a - b| &amp;gt; eps&lt;br /&gt;
          a = b - (b - a) * f(b) / (f(b) - f(a))&lt;br /&gt;
          b = a - (a - b) * f(a) / (f(a) - f(b))&lt;br /&gt;
     '''return''' b&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Метод Ньютона ==&lt;br /&gt;
[[Файл:Newton method.png|thumb|300px|right|Метод Ньютона]]&lt;br /&gt;
&lt;br /&gt;
Итерационный численный метод нахождения нуля заданной функции.&lt;br /&gt;
&lt;br /&gt;
=== Алгоритм ===&lt;br /&gt;
Задана монотонная, дифференцируемая функция и начальное значение &amp;lt;tex&amp;gt; x_{0} &amp;lt;/tex&amp;gt;. Построим касательную к нашей функции в заданной точке и найдем новую точку &amp;lt;tex&amp;gt; x_{1} &amp;lt;/tex&amp;gt;, как пересечения касательной и оси абсцисс. Пока не выполнено заданное условие, например &amp;lt;tex&amp;gt; f(x_{n}) &amp;lt; \varepsilon &amp;lt;/tex&amp;gt;, вычисляем новое значение &amp;lt;tex&amp;gt; x_{n+1} &amp;lt;/tex&amp;gt; по формуле:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex dpi=130&amp;gt; x_{n+1} = x_{n} - \dfrac{f(x_{n})}{f'(x_{n})} &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод ===&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 '''double''' search (x : '''double''', eps : '''double'''):&lt;br /&gt;
     '''while''' f(x) &amp;gt; eps&lt;br /&gt;
          x = x - f(x) / f'(x)&lt;br /&gt;
     '''return''' x&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
Пусть даны числа &amp;lt;tex&amp;gt; C &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; n &amp;lt;/tex&amp;gt; {{---}} число и корень какой степень нам нужно посчитать соответственно. Пусть &amp;lt;tex&amp;gt; x = \sqrt[n]{C}&amp;lt;/tex&amp;gt;. Возведем все выражение в &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-ую степень и перенесем всё в левую часть, тогда &amp;lt;tex&amp;gt; x^n - C = 0 &amp;lt;/tex&amp;gt;. То есть нужно найти нуль этого выражения, решим это с помощью метода Ньютона.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 '''double''' nthRoot (C : '''double''', n : '''double''', eps : '''double''')&lt;br /&gt;
     '''while''' pow(x, n) - C &amp;gt; eps&lt;br /&gt;
         x = x - (pow(x, n) - C) / (n * pow(x, n - 1))&lt;br /&gt;
     '''return''' x&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Замечания ==&lt;br /&gt;
* Необходимо отметить, то функция должна быть строго монотонна, если мы ищем конкретный корень и он единственный. Нестрого монотонна, если нам необходимо найти самый левый (правый) аргумент. Если же функция не монотонна, то данный алгоритм не найдет искомый аргумент, либо найдет аргумент, но он не будет единственным.&lt;br /&gt;
* Классической задачей на вещественный двоичный поиск является задача поиска корня &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-ой степени из числа &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;\sqrt[n]{x}&amp;lt;/tex&amp;gt;. При &amp;lt;tex&amp;gt;x \geqslant 1&amp;lt;/tex&amp;gt; нижней границей для поиска будет &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;, а верхней {{---}} &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
* [[Целочисленный двоичный поиск]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Bisection_method Bisection method {{---}} Wikipedia]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Newton%27s_method Newton's method {{---}} Wikipedia]&lt;br /&gt;
* [http://www.youtube.com/watch?v=qkLLcdgJj_o Видеолекция &amp;quot;сортировка и поиск&amp;quot;]&lt;br /&gt;
* [http://community.topcoder.com/tc?module=Static&amp;amp;d1=tutorials&amp;amp;d2=binarySearch Binary search {{---}} Topcoder]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Алгоритмы поиска]]&lt;/div&gt;</summary>
		<author><name>188.170.82.90</name></author>	</entry>

	</feed>