Вещественный двоичный поиск — различия между версиями
| Строка 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;
Пример использования
Классической задачей на вещественный двоичный поиск является задача поиска корня -ой степени из числа : . При нижней границей для поиска будет , а верхней - .
