Вещественный двоичный поиск — различия между версиями
Строка 2: | Строка 2: | ||
== Формулировка задачи == | == Формулировка задачи == | ||
− | Пусть нам задана монотонная функция. Необходимо найти | + | Пусть нам задана монотонная функция. Необходимо найти значение (<tex>c</tex>) этой функции в заданной точке (<tex>x</tex>). |
− | + | ||
− | [[Файл: | + | [[Файл:Function.png]] |
== Решение задачи == | == Решение задачи == | ||
− | Применим идею двоичного поиска. Выберем такие границы, где значение функции точно больше и точно меньше заданного значения. Выберем значение в середине этого отрезка. Если оно меньше, чем заданное, то сместим левую границу. В противном случае сместим правую границу. Далее повторим процесс сужения границ. Встает вопрос, когда остановиться. Есть несколько способов сделать это. | + | Применим идею двоичного поиска. Выберем такие границы, где значение функции точно больше и точно меньше заданного значения. Выберем значение в середине этого отрезка. Если оно меньше, чем заданное, то сместим левую границу в середину отрезка. В противном случае сместим правую границу. Далее повторим процесс сужения границ. Встает вопрос, когда остановиться. Есть несколько способов сделать это. |
− | == | + | == Способы закончить поиск == |
− | + | * Первый способ заключается в том, чтобы остановиться, когда рассматриваемый отрезок станет меньше заданного эпсилон. Но у этого подхода есть свои плюсы и минусы: | |
+ | : <tex>\oplus</tex> Алгоритм с большой точностью найдет значение аргумента | ||
− | + | : <tex>\ominus</tex> Алгоритм может зациклиться. В компьютере мы работаем с конечным числом вещественных чисел. У чисел есть точность. Соответственно при больших значениях функции, длина отрезка может никогда не уменьшиться до заданного значения | |
− | + | * Второй способ менее точен. Предлагается заканчивать алгоритм, когда значение функции на концах отрезках различается менее, чем на заданное эпсилон. | |
− | + | : <tex>\oplus</tex> В отличии от предыдущего, не зацикливается при больших значениях функции. | |
− | + | ||
− | + | : <tex>\ominus</tex> Возможна большая погрешность, если функция будет очень медленно возрастать | |
− | + | * Абсолютно точный поиск. Вспомним о том, что вещественный числа в компьютере дискретным. Будем завершать поиск, когда границы отрезка - два соседних по представлению значения в типе данных. Утверждается, что два числа - соседние, если середина их отрезка совпадает или с левой, или с правой границей. | |
− | + | : <tex>\ominus</tex> Возможно плохое поведение, если искомый аргумент равен 0. | |
− | + | * Итеративный способ. В этом способе выполниться только конечное число число итераций. | |
− | + | : <tex>\oplus</tex> Плюсом этого способа является фиксированная погрешность. | |
− | + | ||
− | + | == Выбор границы отрезка для поиска== | |
+ | Для начала найдем правую границу. Выберем произвольную положительную точку (например </tex>1</tex>). Будем удваивать ее до тех пор, пока значение функции в этой точке меньше заданного. Для того, чтобы найти левую границу выберем произвольную отрицательную точку (например <tex>-1</tex>). Будем удваивать ее до тех пор, пока значение в ней будет больше заданного значения. | ||
== Псевдокод == | == Псевдокод == | ||
Строка 46: | Строка 48: | ||
mid = (left + right) / 2; | mid = (left + right) / 2; | ||
if f(mid) < c | if f(mid) < c | ||
− | + | left = mid; | |
else | else | ||
− | + | right = mid; | |
return l; | return l; | ||
</pre> | </pre> | ||
+ | == Пример использования == | ||
+ | Классической задачей на вещественный двоичный поиск является задача поиска корня <tex>n</tex>-ой степени из числа <tex>x</tex>: <tex>\sqrt[n]{x}</tex>. При <tex>x >= 1</tex> нижней границей для поиска будет <tex>1</tex>, а верхней - <tex>x</tex>. | ||
== Источники == | == Источники == | ||
* [http://www.intuit.ru/department/algorithms/basicalgos/2/ Интернет университет, лекция сортировка и поиск] | * [http://www.intuit.ru/department/algorithms/basicalgos/2/ Интернет университет, лекция сортировка и поиск] |
Версия 20:34, 12 июня 2012
Вещественный двоичный поиск - алгоритм поиска аргумента для заданного значения монотонной вещественной функции.
Содержание
Формулировка задачи
Пусть нам задана монотонная функция. Необходимо найти значение (
) этой функции в заданной точке ( ).Решение задачи
Применим идею двоичного поиска. Выберем такие границы, где значение функции точно больше и точно меньше заданного значения. Выберем значение в середине этого отрезка. Если оно меньше, чем заданное, то сместим левую границу в середину отрезка. В противном случае сместим правую границу. Далее повторим процесс сужения границ. Встает вопрос, когда остановиться. Есть несколько способов сделать это.
Способы закончить поиск
- Первый способ заключается в том, чтобы остановиться, когда рассматриваемый отрезок станет меньше заданного эпсилон. Но у этого подхода есть свои плюсы и минусы:
- Алгоритм с большой точностью найдет значение аргумента
- Алгоритм может зациклиться. В компьютере мы работаем с конечным числом вещественных чисел. У чисел есть точность. Соответственно при больших значениях функции, длина отрезка может никогда не уменьшиться до заданного значения
- Второй способ менее точен. Предлагается заканчивать алгоритм, когда значение функции на концах отрезках различается менее, чем на заданное эпсилон.
- В отличии от предыдущего, не зацикливается при больших значениях функции.
- Возможна большая погрешность, если функция будет очень медленно возрастать
- Абсолютно точный поиск. Вспомним о том, что вещественный числа в компьютере дискретным. Будем завершать поиск, когда границы отрезка - два соседних по представлению значения в типе данных. Утверждается, что два числа - соседние, если середина их отрезка совпадает или с левой, или с правой границей.
- Возможно плохое поведение, если искомый аргумент равен 0.
- Итеративный способ. В этом способе выполниться только конечное число число итераций.
- Плюсом этого способа является фиксированная погрешность.
Выбор границы отрезка для поиска
Для начала найдем правую границу. Выберем произвольную положительную точку (например </tex>1</tex>). Будем удваивать ее до тех пор, пока значение функции в этой точке меньше заданного. Для того, чтобы найти левую границу выберем произвольную отрицательную точку (например
). Будем удваивать ее до тех пор, пока значение в ней будет больше заданного значения.Псевдокод
findLeft(c) x = -1; while f(x) > c x = x * 2; return x;
findRight(c) x = 1; while f(x) < c x = x * 2; return x;
binSearch(c) left = findLeft(с); right = findRight(с); while left < right - eps //Здесь можно использовать другое условие выхода mid = (left + right) / 2; if f(mid) < c left = mid; else right = mid; return l;
Пример использования
Классической задачей на вещественный двоичный поиск является задача поиска корня
-ой степени из числа : . При нижней границей для поиска будет , а верхней - .