|
Serwis Edukacyjny w I-LO w Tarnowie
Materiały dla uczniów liceum |
Wyjście Spis treści Wstecz Dalej
Autor artykułu: mgr Jerzy Wałaszek |
©2026 mgr Jerzy Wałaszek
|
| SPIS TREŚCI REMANENT |
|
| Podrozdziały |
Metoda bisekcji (ang. bisection method) , zwana również metodą połowienia lub wyszukiwaniem binarnym pozwala stosunkowo szybko znaleźć pierwiastek dowolnej funkcji w zadanym przedziale poszukiwań <a;b>. Aby można było zastosować metodę bisekcji, funkcja musi spełniać kilka warunków początkowych:

Metoda bisekcji stosowana jest do przybliżonego rozwiązywania równania f(x) = 0 w przedziale <a;b>. Funkcja f(x) musi być określona i ciągła w tym przedziale oraz musi posiadać różne znaki na krańcach przedziału , co gwarantuje istnienie przynajmniej jednego pierwiastka w tym przedziale. Rozwiązanie znajdowane jest za pomocą kolejnych przybliżeń. Z tego powodu należy określić dokładność, z którą chcemy otrzymać pierwiastek funkcji oraz dokładność wyznaczania samej funkcji.
W każdym przybliżeniu algorytm wyznacza środek x0 przedziału jako średnią arytmetyczną krańców. Następnie sprawdzane jest, czy odległość tego środka od krańców przedziału jest mniejsza od założonej dokładności wyliczania pierwiastka. Jeśli tak, to algorytm kończy pracę z wynikiem w x0. Jeśli nie, to wyznaczana jest wartość funkcji w punkcie x0 i sprawdza się, czy odległość tej wartości od 0 jest mniejsza od założonej dokładności wyznaczania funkcji. Jeśli tak, to algorytm kończy pracę z wynikiem w x0.
W przeciwnym razie punkt x0 dzieli przedział na dwie równe połowy: <a;x0> i <x0;b>. Algorytm za nowy przedział przyjmuję tę połówkę, w której funkcja zmienia znak na krańcach i kontynuuje wyznaczanie pierwiastka funkcji.
Z opisu wynika, iż w każdym obiegu szerokość przedziału maleje dwukrotnie. Dzięki temu pierwiastek jest wyznaczany coraz dokładniej. Po dziesięciu obiegach szerokość przedziału maleje 210 = 1024 razy. Po 20 obiegach szerokość maleje 220 = 1048576 razy. Jest to postęp wykładniczy, zatem bardzo szybki.
| εx | – | dokładność obliczania pierwiastka |
| εy | – | dokładność obliczania funkcji |
| a | – | początek przedziału poszukiwań pierwiastka |
| b | – | koniec przedziału poszukiwań pierwiastka |
| f( ) | – | funkcja, której pierwiastek będzie obliczany |
| x0 | – | przybliżony pierwiastek funkcji |
| fa | – | wartość funkcji w punkcie a |
| fb | – | wartość funkcji w punkcie b |
| K01: | fa ← f(a) fb ← f(b) | Obliczamy wartości funkcji na krańcach przedziału . |
| K02: | Jeśli fa
·
fb > 0, to zakończ z błędem |
Funkcja nie ma różnych znaków na krańcach przedziału . |
| K03: | ![]() |
Wyznaczamy środek przedziału . |
| K04: | Jeśli |a - x0| < εx, to zakończ |
Osiągnięto założoną dokładność. Wynik w x0. |
| K05: | fx ← f(x0) | Obliczamy wartość funkcji w środku przedziału |
| K06: | Jeśli | fx
| < εy, to zakończ |
Sprawdzamy, czy funkcja ma wartość 0 w środku przedziału. Wynik w x0. |
| K07: | Jeśli fx
·
fa < 0, to b ← x0 inaczej a ← x0, fa ← fx |
Za nowy przedział
przyjmujemy tę połówkę <a;x0>,
<x0;b>, w której funkcja zmienia znak |
| K08: | Idź do kroku K3 | Kontynuujemy obliczenia |
Poniższy program jest przykładową realizacją algorytmu bisekcji. Program oblicza pierwiastek funkcji:

Wykres tej funkcji w przedziale <-3,1> jest następujący:

Z wykresu wynika, iż pierwiastek znajduje się w przedziale <-1,1;-1>. Taki więc przedział został przyjęty w programie.
// Pierwiastek funkcji - metoda bisekcji
// (C)2019 mgr Jerzy Wałaszek
// Metody numeryczne 0032
//--------------------------------------
#include <iostream>
#include <windows.h>
#include <cmath>
#include <iomanip>
using namespace std;
// Tutaj definiujemy funkcję,
// której pierwiastek jest wyliczany
//----------------------------------
double f(double x)
{
return sin(x*x-x+1/3.0)+0.5*x;
}
// Tutaj definiujemy parametry początkowe
// Dokładność x
double epsx = 1e-14;
// Dokładność y
double epsy = 1e-14;
// Początek przedziału
// poszukiwań pierwiastka
double a = -1.1;
// Koniec przedziału
// poszukiwań pierwiastka
double b = -1.0;
// Program główny
//---------------
int main()
{
// Zmienne
double fa,fb,fx,x0;
// Licznik obiegów pętli
int i = 0;
// Zmienna informująca
// o znalezieniu wyniku
bool result = false;
SetConsoleOutputCP(CP_UTF8);
SetConsoleCP(CP_UTF8);
cout << setprecision(15)
<< fixed;
cout <<
"Obliczanie przybliżonego pierwiastka "
"funkcji metodą bisekcji\n"
"-------------------------------------"
"-----------------------\n\n";
// Obliczamy i zapamiętujemy
// wartości funkcji
// na krańcach przedziału
fa = f(a);
fb = f(b);
// Sprawdzamy, czy na krańcach
// przedziału wartości funkcji
// mają różne znaki
if(fa * fb > 0)
cout <<
"BŁĄD!!! Funkcja nie ma różnych "
"znaków na krańcach przedziału";
else
{
result = true;
// W pętli wyznaczamy kolejne
// przybliżenia pierwiastka
while(true)
{
// Zwiększamy licznik
// obiegów pętli
i++;
// Wyznaczamy środek przedziału
x0 = (a + b) / 2;
// Sprawdzamy, czy szerokość
// przedziału jest mniejsza
// od zadanej dokładności
if(fabs(a - x0) < epsx)
break; // Jeśli tak, to kończymy
// Obliczamy i zapamiętujemy
// wartość funkcji w punkcie x0
fx = f(x0);
// Sprawdzamy, czy wartość
// funkcji jest dostatecznie
// bliska zeru
if(fabs(fx)< epsy)
break; // Jeśli tak, to kończymy
// Za nowy przedział przyjmujemy
// tę z połówek <a;x0>, <x0;b>,
// w której funkcja ma różne
// znaki na krańcach
if(fa * fx < 0)
b = x0;
else
{
a = x0;
fa = fx;
}
}
}
if(result)
cout
<< "Pierwiastek x0 = "
<< setw(20) << x0 << endl
<< "Wartość funkcji f(x0) = "
<< setw(20) << f(x0) << endl
<< "Dokładność dla x epsx = "
<< setw(20) << epsx << endl
<< "Dokładność dla y epsy = "
<< setw(20) << epsy << endl
<< "Liczba obiegów i = "
<< setw(4) << i;
cout << endl << endl;
system("pause");
return 0;
}
|
| Wynik |
Obliczanie przybliżonego pierwiastka funkcji metodą bisekcji ------------------------------------------------------------ Pierwiastek x0 = -1.077713513691339 Wartość funkcji f(x0) = 0.000000000000002 Dokładność dla x epsx = 0.000000000000010 Dokładność dla y epsy = 0.000000000000010 Liczba obiegów i = 44 |
Python
(dodatek) import math
# Pierwiastek funkcji - metoda bisekcji
# (C)2026 mgr Jerzy Wałaszek
# Metody numeryczne 0032
#--------------------------------------
# Tutaj definiujemy funkcję,
# której pierwiastek jest wyliczany
#----------------------------------
def f(x):
return (math.sin(x * x - x + 1 / 3.0)
+ 0.5 * x)
# Tutaj definiujemy parametry początkowe
# Dokładność x
epsx = 1e-14
# Dokładność y
epsy = 1e-14
# Początek przedziału
# poszukiwań pierwiastka
a = -1.1
# Koniec przedziału
# poszukiwań pierwiastka
b = -1.0
# Program główny
#---------------
# Licznik obiegów pętli
i = 0
# Zmienna informująca
# o znalezieniu wyniku
result = False
print(
"Obliczanie przybliżonego pierwiastka "
"funkcji metodą bisekcji\n"
"-------------------------------------"
"-----------------------\n")
# Obliczamy i zapamiętujemy
# wartości funkcji
# na krańcach przedziału
fa = f(a)
fb = f(b)
# Sprawdzamy, czy na krańcach
# przedziału wartości funkcji
# mają różne znaki
if fa * fb > 0:
print(
"BŁĄD!!! Funkcja nie ma różnych "
"znaków na krańcach przedziału")
else:
result = True
x0 = 0.0
# W pętli wyznaczamy kolejne
# przybliżenia pierwiastka
while True:
# Zwiększamy licznik
# obiegów pętli
i += 1
# Wyznaczamy środek przedziału
x0 = (a + b) / 2
# Sprawdzamy, czy szerokość
# przedziału jest mniejsza
# od zadanej dokładności
if math.fabs(a - x0) < epsx:
break
# Obliczamy i zapamiętujemy
# wartość funkcji w punkcie x0
fx = f(x0)
# Sprawdzamy, czy wartość
# funkcji jest dostatecznie
# bliska zeru
if math.fabs(fx) < epsy:
break
# Za nowy przedział przyjmujemy
# tę z połówek <a,x0>, <x0,b>,
# w której funkcja ma różne
# znaki na krańcach
if fa * fx < 0:
b = x0
else:
a = x0
fa = fx
if result:
print(
f"Pierwiastek x0 = {x0:20.15f}")
print(
f"Wartość funkcji f(x0) = {f(x0):20.15f}")
print(
f"Dokładność dla x epsx = {epsx:20.15f}")
print(
f"Dokładność dla y epsy = {epsy:20.15f}")
print(
f"Liczba obiegów i = {i:4}")
print("\n")
input("Naciśnij Enter...")
|
![]() |
Zespół Przedmiotowy Chemii-Fizyki-Informatyki w I Liceum Ogólnokształcącym im. Kazimierza Brodzińskiego w Tarnowie ul. Piłsudskiego 4 ©2026 mgr Jerzy Wałaszek |
Materiały tylko do użytku dydaktycznego. Ich kopiowanie i powielanie jest dozwolone pod warunkiem podania źródła oraz niepobierania za to pieniędzy.
Pytania proszę przesyłać na adres email:
Serwis wykorzystuje pliki cookies. Jeśli nie chcesz ich otrzymywać, zablokuj je w swojej przeglądarce.
Informacje dodatkowe.