Изменения

Перейти к: навигация, поиск

Вещественный двоичный поиск

3199 байт добавлено, 14:35, 17 мая 2018
Нет описания правки
'''Вещественный двоичный поиск''' (англ. ''Bisection method''){{---}} алгоритм поиска аргумента для заданного значения монотонной вещественной функции.
== Формулировка задачи ==
Пусть нам задана монотонная функция<tex> f </tex> и какое-то значение <tex> C </tex> этой функции. Необходимо найти значение аргумента <tex>x</tex> этой функции, в которой она принимает определенное значение такое, что <tex>f(x) = C</tex> = ''valOfFunc''.
[[Файл:Function.png]]
Применим идею [[целочисленный двоичный поиск | двоичного поиска]]. Выберем такие границы, где значение функции точно больше и точно меньше заданного значения. Выберем значение в середине этого отрезка. Если оно меньше, чем заданное, то сместим левую границу в середину отрезка. В противном случае сместим правую границу. Далее повторим процесс сужения границ. Встает вопрос, когда остановиться. Есть несколько способов сделать это.
=== Способы закончить поиск ===
{| class="wikitable"
! Способы || Плюсы || Минусы || Оценка на число итераций
|-
| Окончание, когда рассматриваемый отрезок станет меньше заданной погрешности <tex> \varepsilon </tex>. || Заданная точность найденного значения. || Алгоритм может зациклиться. В компьютере мы работаем с конечным числом вещественных чисел, у которых есть точность. При больших значениях функции длина отрезка может никогда не уменьшиться до заданного значения. || В данном случае нам нужно рассмотреть <texdpi=130> \genfrac{}{}{}{}{R - L}{\varepsilon} </tex> чисел <tex> \Rightarrow </tex> примерное число итераций <texdpi=130> \log(\genfrac{}{}{}{}{R - L}{\varepsilon}) </tex>.
|-
| Окончание, когда значение функции на концах отрезках различается менее, чем на заданную погрешность <tex> \varepsilon </tex>. || Значение функции от найденного значения имеет заданную точность. || а) Возможна большая погрешность, если функция будет очень медленно возрастать. <br> б) Может зациклиться по той же причине, что и в первом способе. || Аналогичная с первым случаем логика, примерное число итераций <texdpi=130> \log(\genfrac{}{}{}{}{f(R) - f(L)}{\varepsilon}) </tex>.
|-
| «Абсолютно точный поиск» <br> Окончание, когда границы отрезка — два соседних по представлению значения в типе данных. Утверждается, что два числа — соседние, если середина их отрезка совпадает или с левой, или с правой границей. || Максимально возможная точность найденного значения. || Возможно плохое поведение, если искомый аргумент равен нулю. || При работе с числами с плавающей точкой количество итераций зависит от плотности чисел на данном отрезке. При работе с числами фиксированной точности (= <tex>\varepsilon</tex>) количество итераций аналогично первому и второму случаю равно <texdpi=130> \log(\genfrac{}{}{}{}{R - L}{\varepsilon}) </tex>.
|-
| «Итеративный способ» <br> Выполнение конечного числа итераций. || У способа фиксированная погрешность. || Довольно плохая точность, если границы отрезка находятся на большом расстоянии. || Выполняется заданное количество итераций.
|}
=== Выбор границы отрезка для поиска===Для начала найдем правую левую границу. Выберем , выберем произвольную положительную отрицательную точку (например <tex>-1</tex>). Будем удваивать ее до тех пор, пока значение функции в этой точке меньше ней будет больше заданногозначения. Для того, чтобы найти левую правую границу , выберем произвольную отрицательную положительную точку (например <tex>-1</tex>). Будем удваивать ее до тех пор, пока значение функции в ней будет больше этой точке меньше заданного значения.
== Псевдокод ==
<code> '''double''' findLeftBoard(valueOfFunc C : '''double'''):
x = -1
'''while''' f(x) > valueOfFunc C
x = x * 2
'''return''' x
</code><code>.  '''double''' findRightBoard(valueOfFunc C : '''double'''):
x = 1
'''while''' f(x) < valueOfFuncC
x = x * 2
'''return''' x
.
 
'''double''' binSearch(C : '''double'''):
left = findLeftBoard(C)
right = findRightBoard(C)
'''while''' right - left < eps <font color=green> // Здесь можно использовать другое условие выхода </font>
mid = (left + right) / 2
'''if''' f(mid) < C
left = mid
'''else'''
right = mid
'''return''' (left + right) / 2
 
.
 
== Метод секущих ==
[[Файл:Secant method.png|thumb|350px|right|Метод секущих при <tex> C = 0 </tex>]]
 
Итерационный численный метод приближённого нахождения корня уравнения.
 
=== Алгоритм ===
Пусть нам задана монотонная <tex> f </tex> и значение <tex> C </tex>. Выберем две начальные точки, причем <tex> f(x_{1}) < C </tex>, а <tex> f(x_{2}) > C </tex>. Проведем через них прямую, которая пересечет прямую <tex> y = C </tex> в точке <tex> (x_{3}, C) </tex>. Теперь вместо точек <tex> x_{1} </tex> и <tex> x_{2} </tex> возьмем точки <tex> x_{3} </tex> и <tex> x_{2} </tex>, и проделаем ту же операцию и так далее, получая точки <tex> x_{n+1} </tex> и <tex> x_{n} </tex>, пока <tex> |x_{n-1} - x_{n}| > \varepsilon </tex>.
Вычисляем каждое последующее значение <tex> x_{n+1} </tex> с помощью формулы:
 
<tex dpi=130> x_{n+1} = x_{n-1} + \dfrac{(C - f(x_{n}))\cdot(x_{n} - x_{n-1})}{f(x_{n}) - f(x_{n-1})} </tex>
 
Нахождение нулей функции <tex>(C = 0)</tex>:
 
<tex dpi=130> x_{n+1} = x_{n-1} - \dfrac{f(x_{n})\cdot(x_{n} - x_{n-1})}{f(x_{n}) - f(x_{n-1})} </tex>
 
=== Псевдокод ===
<code>
'''double''' search (a : '''double''', b : '''double''', eps : '''double'''): <font color=green> // Где a {{---}} левая граница, а b {{---}} правая </font>
'''while''' |a - b| > eps
a = b - (b - a) * f(b) / (f(b) - f(a))
b = a - (a - b) * f(a) / (f(a) - f(b))
'''return''' b
</code>
 
== Метод Ньютона ==
[[Файл:Newton method.png|thumb|300px|right|Метод Ньютона]]
 
Итерационный численный метод нахождения нуля заданной функции.
 
=== Алгоритм ===
Задана монотонная, дифференцируемая функция и начальное значение <tex> x_{0} </tex>. Построим касательную к нашей функции в заданной точке и найдем новую точку <tex> x_{1} </tex>, как пересечения касательной и оси абсцисс. Пока не выполнено заданное условие, например <tex> f(x_{n}) < \varepsilon </tex>, вычисляем новое значение <tex> x_{n+1} </tex> по формуле:
 
<tex dpi=130> x_{n+1} = x_{n} - \dfrac{f(x_{n})}{f'(x_{n})} </tex>
 
=== Псевдокод ===
<code>
'''double''' binSearchsearch (valueOfFunc x : '''double'''), eps : left = findLeftBoard(valueOfFunc) right = findRightBoard(valueOfFunc) '''whiledouble''' right - left < eps <font color=green> //Здесь можно использовать другое условие выхода </font> middle = (left + right) / 2: '''ifwhile''' f(middlex) < valueOfFunc> eps left x = middle x - f(x) / f'''else''' right = middle(x) '''return''' (left + right) / 2x
</code>
== Примеры использования = Пример ===* Классической задачей на вещественный двоичный поиск является задача поиска корня Пусть даны числа <tex>nC </tex>-ой степени из числа и <tex>xn </tex>: {{---}} число и корень какой степень нам нужно посчитать соответственно. Пусть <tex>x = \sqrt[n]{xC}</tex>. При Возведем все выражение в <tex>x \ge 1</tex> нижней границей для поиска будет <tex>1n</tex>-ую степень и перенесем всё в левую часть, а верхней {{---}} тогда <tex>x^n - C = 0 </tex>.То есть нужно найти нуль этого выражения, решим это с помощью метода Ньютона. * Если функция нестрого монотонна, то, убрав из приведенного выше алгоритма строки, отмеченные <texcode> '''double''' nthRoot (**)</tex>C : '''double''', мы получим алгоритмn : '''double''', который будет находить <tex>eps : '''double''') '''while''' pow(x</tex> такой, что <texn) - C >feps x = x - (pow(x, n) - C) = </tex> (n * pow(x, n - 1)) '''return'valOfFunc'' и <tex>f(x - \varepsilon) < </texcode> ''valOfFunc''.
== Замечания ==
* Необходимо отметить, то функция должна быть строго монотонна, если мы ищем конкретный корень и он единственный. Нестрого монотонна, если нам необходимо найти самый левый (правый) аргумент. Если же функция не монотонна, то данный алгоритм не найдет искомый аргумент, либо найдет аргумент, но он не будет единственным.
* Классической задачей на вещественный двоичный поиск является задача поиска корня <tex>n</tex>-ой степени из числа <tex>x</tex>: <tex>\sqrt[n]{x}</tex>. При <tex>x \ge geqslant 1</tex> нижней границей для поиска будет <tex>1</tex>, а верхней {{---}} <tex>x</tex>.
== См. также ==* [[Целочисленный двоичный поиск]] == Источники информации == * [http://en.wikipedia.org/wiki/Bisection_method Bisection method {{---}} Wikipedia]* [http://en.wikipedia.org/wiki/Newton%27s_method Newton's method {{---}} Wikipedia]
* [http://www.youtube.com/watch?v=qkLLcdgJj_o Видеолекция "сортировка и поиск"]
* [http://community.topcoder.com/tc?module=Static&d1=tutorials&d2=binarySearch Binary search {{---}} Topcoder] [[Категория: binary searchДискретная математика и алгоритмы]][[Категория: Алгоритмы поиска]]
Анонимный участник

Навигация