Метод бисекции

Материал из Википедии — свободной энциклопедии
Перейти к: навигация, поиск

Метод бисекции или метод деления отрезка пополам — простейший численный метод для решения нелинейных уравнений вида f(x)=0. Предполагается только непрерывность функции f(x). Поиск основывается на теореме о промежуточных значениях.

Содержание

[править] Обоснование

Алгоритм основывается на следующем следствии теоремы Больцано — Коши:

Logo arte.jpg Пусть функция f(x)\in\mathrm{C}([a,\;b])\!, тогда если f(a)>0, f(b)\!<0, то \exist c\in[a,\;b]:\;f(c)=0.

Таким образом, если мы ищем ноль, то на концах отрезка функция должна быть разных знаков. Разделим отрезок пополам и возьмём ту из половинок, для которой на концах функция по-прежнему принимает значения разных знаков. Если серединная точка оказалось искомым нулём, то процесс завершается.

Если задана точность вычисления \varepsilon \!, то процедуру следует продолжать до тех пор, пока длина отрезка не станет меньше \varepsilon .

Для поиска произвольного значения достаточно вычесть из значения функции искомое значение и искать ноль получившейся функции.

[править] Описание алгоритма

Задача заключается в нахождении корней нелинейного уравнения

f(x)=0. \qquad ( 1 )

Для начала итераций необходимо знать интервал [xL,xR] значений x, на концах которого функция принимает значения разных знаков:

f(x_L)f(x_R)<0. \qquad ( 2 )

Из непрерывности функции f и условия (2) следует, что на интервале [xL,xR] существует хотя бы один корень уравнения (в случае наличия нескольких корней метод приводит к нахождению одного из них)

Выберем точку внутри интервала

x_M=(x_R+x_L)/2.  \qquad ( 3 )

Если f(x_M)=0, то корень найден. Если f(x_M)\ne 0 разобьём интервал [xL,xR] на два: [xL,xM] и [xM,xR]. Теперь найдём новый интервал, в котором функция меняет знак. Пусть \! f(x_L)f(x_M)<0 и соответственно корень находится внутри интервала [xL,xM]. Тогда обозначим xR=xM и повторим описанную процедуру до достижения требуемой точности. За количество итераций N первоначальный отрезок делится в 2N раз.

[править] Поиск значения монотонной функции

Поиск значения монотонной функции, записанной в массиве, заключается в сравнении срединного элемента массива с искомым значением, и повторением алгоритма для той или другой половины, в зависимости от результата сравнения.

Пускай переменные L_b\,\! и U_b\,\! содержат, соответственно, левую и правую границы отрезка массива, где находится нужный нам элемент. Исследования начинаются со среднего элемента отрезка. Если искомое значение меньше среднего элемента, осуществляется переход к поиску в верхней половине отрезка, где все элементы меньше только что проверенного, то есть значением U_b\,\! становится \left( M - 1 \right)\,\! и на следующей итерации исследуется только половина массива. Т.о., в результате каждой проверки область поиска сужается вдвое.

Например, если длина массива равна 1023, после первого сравнения область сужается до 511 элементов, а после второй — до 255. Т.о. для поиска в массиве из 1023 элементов достаточно 10 сравнений.

l = леваяГраница - 1
r = праваяГраница + 1
while (r - l > 1) {
  середина = (l+r) / 2
  if (массив[середина] < значение)
     l = середина
  else
     r = середина
 } 
 if (массив[r] ≠ значение)
   return -1 // элемент не найден
 else
   return r

[источник не указан 1004 дня]

[править] Программный код

  • xn – начало отрезка по х;
  • xk – конец отрезка по х;
  • xi – середина отрезка по х;
  • eps – требуемая точность вычислений.

Таким образом, весь алгоритм можно записать следующим образом (в псевдокоде):

  1. Начало.
  2. Ввод xn, xk, eps.
  3. Если F(xn) = 0, то Вывод (корень уравнения – xn).
  4. Если F(xk) = 0, то Вывод (корень уравнения – xk).
  5. Пока (F(xi) <> 0) и |xk-xn| > eps повторять:
  6. xi := (xk+xn)/2;
  7. если (F(xn)*F(xi) < 0), то xk := xi;
  8. если (F(xi)*F(xk) < 0), то xn := xi.
  9. Вывод (Найден корень уравнения – xi точности ε).
  10. Конец.


Пример реализации алгоритма на языке Matlab[источник не указан 476 дней]

 clear;
 
 %Интервал
 x_L=1;
 x_R=2;
 length=x_R-x_L;
 %Начальная ошибка
 err=length;
 
 %Итерационный цикл
 while err>1e-3
     %Деление отрезка пополам
     x_M=(x_L+x_R)/2;
     %Нахождение нового интервала
     if tan(x_L)*tan(x_M)<0
         x_R=x_M;
     else
         if tan(x_M)*tan(x_R)<0
             x_L=x_M;
         else
             x_M
             break;
         end
     end
     %Пересчёт ошибки
     err=(x_R-x_L)/length;
 end
 %Вывод результата
 x_M
 err

Результат выполнения вполне ожидаемый

 x_M =
 
     1.5713
 
 
 err =
 
   9.7656e-004

[править] См. также

[править] Ссылки

Личные инструменты
Пространства имён

Варианты
Действия
Навигация
Участие
Печать/экспорт
Инструменты
На других языках