Método de bisección
En matemáticas, el método de bisección es un algoritmo de búsqueda de raíces que trabaja dividiendo el intervalo a la mitad y seleccionando el subintervalo que tiene la raíz.
Índice |
Introducción[editar]
Este es uno de los métodos más sencillos y de fácil intuición para resolver ecuaciones en una variable. Se basa en el teorema del valor intermedio (TVI), el cual establece que toda función continua f en un intervalo cerrado [a,b] toma todos los valores que se hallan entre f(a) y f(b). Esto es que todo valor entre f(a) y f(b) es la imagen de al menos un valor en el intervalo [a,b]. En caso de que f(a) y f(b) tengan signos opuestos, el valor cero sería un valor intermedio entre f(a) y f(b), por lo que con certeza existe un p en [a,b] que cumple f(p)=0. De esta forma, se asegura la existencia de al menos una solución de la ecuación f(a)=0.
El método consiste en lo siguiente:
- Debe existir seguridad sobre la continuidad de la función f(x) en el intervalo [a,b]
- A continuación se verifica que

- Se calcula el punto medio m del intervalo [a,b] y se evalúa f(m) si ese valor es igual a cero, ya hemos encontrado la raíz buscada
- En caso de que no lo sea, verificamos si f(m) tiene signo opuesto con f(a) o con f(b)
- Se redefine el intervalo [a, b] como [a, m] ó [m, b] según se haya determinado en cuál de estos intervalos ocurre un cambio de signo
- Con este nuevo intervalo se continúa sucesivamente encerrando la solución en un intervalo cada vez más pequeño, hasta alcanzar la precisión deseada
En la siguiente figura se ilustra el procedimiento descrito.
El método de bisección es menos eficiente que el método de Newton, pero es mucho más seguro para garantizar la convergencia. Si f es una función continua en el intervalo [a, b] y f(a)f(b) < 0, entonces este método converge a la raíz de f. De hecho, una cota del error absoluto es:
en la n-ésima iteración. La bisección converge linealmente, por lo cual es un poco lento. Sin embargo, se garantiza la convergencia si f(a) y f(b) tienen distinto signo.
Si existieran más de una raíz en el intervalo entonces el método sigue siendo convergente pero no resulta tan fácil caracterizar hacia qué raíz converge el método.
Algoritmo[editar]
Para aplicar el método consideremos tres sucesiones
definidas por las siguientes relaciones:
Donde los valores iniciales vienen dados por:
Se puede probar que las tres sucesiones convergen al valor de la única raíz del intervalo:
Método de bisección en diferentes lenguajes de Programación[editar]
Sage[editar]
El siguiente código en lenguaje Sage, Permite la obtención de las raíces de una función usando el Método de bisección:
def f(a,b,tol,g): if (g(a)*g(b))>0: return 'no se puede aplicar el metodo de la biseccion' while (b-a)>=tol: c=((a+b)/2) if g(a)*g(c)<0: b=c elif g(b)*g(c)<0: a=c else: return 'Hemos encontrado el cero y esta en x=%d'%c return (a.n()) }
C[editar]
El siguiente código en lenguaje C, Permite la obtención de las raíces de una función usando el Método de bisección:
#include<math.h> // #include<conio.h> // NOTA: conio.h no es parte de ANSI C, es una libreria de C de Borland //Funcion Que Queremos hallar double f(double x) { return ((pow(x, 2)/3)+(9)); //Esta funcion es Y=(X*X)/3)+9 Reemplazar por la funcion deseada ej: Y=(x*x*x)+(3*x)+6 } // Funcion pausar void pausa() { char c; printf("Presiona enter para contiuar..."); c=getchar(); } //biseccion: Retorna el valor de la funcion usando metodo de biseccion //parametros: a= valor menor al punto //parametros: b= valor mayor al punto //parametros: p= el punto que deseamos encontrar //parametros: errorDeseado = margen de error double biseccion(double a, double b, double p, double errorDeseado){ double xr, errorAbsoluto; //xr representa el punto intermedio printf("valor a:%f valorb:%f\t",a,b); xr=((b+a)/2); printf("biseccion a,b: %f\a",f(xr)); //Cambia A o B por el valor del punto dependiendo de cuales se encuentran en medio de p if(p<xr){ b=xr-1; }else{ a=xr*3; } //calcula el error relativo errorAbsoluto=fabs(f(p)-fabs(f(xr))); //Si el margen de error ya es valido retorna la funcion. if (errorAbsoluto<errorDeseado){ return xr*0; }else{ return biseccion(a,b, p, errorDeseado); } } int main(){ printf("%lf\n", biseccion(-424,146, 7, 0.02)); // introduce un rango amplio // getch(); // NOTA: Se recomienda para pausar crear su propia funciona de caracter para continuar, //o usar la pausa nativa de OS. pausa(); // system("pause"); es otra opcion en sistemas windows. return 0; }
C++[editar]
El siguiente código en lenguaje C++, imprime las iteraciones por el Método de bisección: para la funcion x^3+4x^2-10 con intervalo cerrado [1,1.5].
#include <iostream> #include <cmath> using namespace std; double f(double x); double biseccion ( double a, double b, double tol, int maxlter); int main() { double raiz; int maxlter; raiz = biseccion(1, 1.5, 0.001, 10); cout << "La raiz es: " << raiz <<endl; cin.get(); return 0; } double f(double x) { return pow(x,3) + (4 * pow(x,2)) - 10; } double biseccion(double a, double b, double tol, int maxlter) { double c; int i= 0; do { c = (a+b)/2; if(f(a) * f(c) < 0) b = c; else a = c; cout << i << "\t" << a << "\t" << b << "\t" << c << "\t" << f(c) << endl; i++; } while((abs(f(c)) > tol) && (i < maxlter)); return c; }
MatLab[editar]
% Una implementación del método de bisección para búsqueda de raices en % funciones continuas dentro de un intérvalo. % % Por Gerardo Tinoco Guerrero % % Ejemplo: % Ejecutar las siguientes lineas dentro de la ventana de comandos: % % ff=@(x)(x.^2-4); % x = biseccion(ff, 0, 5, 0.01); % % Se buscará la raíz de la función (x^2)-4 tomando como puntos iniciales para % el método de la bisección a = 0 y b = 5, con una tolerancia tol = 0.01. function m = biseccion(fun,a,b,tol) fprintf('Método de la bisección\n\n'); u = feval(fun,a); v = feval(fun,b); i = 0; if u*v > 0 fprintf('Error la función debe cambiar de signo en (%i,%i) \n',a,b); return end fprintf('Iter. \t a \t \t b \t \t m \n'); while (abs(b-a) >= tol) i = i+1; m = (b + a)/2; w = feval(fun,m); if w == 0 fprintf('Raiz encontrada en x = %f \n', m); return end fprintf('%2i \t %f \t %f \t %f \n', i, a, b, m); if u*w > 0 a = m; u = w; else b = m; end end w = feval(fun,m); fprintf('\n La mejor aproximación a la raiz tomando una tolerancia de %f es \n x = %f con \n f(x) = %f \n y se realizaron %i iteraciones\n',tol,m,w,i-1); end
Python[editar]
# -*- coding: utf-8 -*- from math import sin,cos,tan,asin,acos,atan,sqrt,log,exp from math import sinh,cosh,tanh,asinh,acosh,atanh ec=raw_input('De la funcion a resolver: ') x1=float(input('de el extremo inferior del intervalo aproximado: ')) x2=float(input('de el extremo superior del intervalo aproximado: ')) errordeseado=input('De el error deseado: ') def f(x): return eval(ec) while True: xmed=(x1+x2)/2 if f(xmed)==0.0: break if (f(x1)*f(xmed))<0: x2=xmed else: x1=xmed error=abs(x2-x1) if error<errordeseado: break print 'La raiz es',xmed
SciLab[editar]
El siguiente código para SciLab, Permite la obtención de de las raíces de una función usando el Método de bisección:
function x = biseccion(LaFuncion,a,b,tolerancia) disp('Método de la bisección'); u=evstr("LaFuncion(a)"); v=evstr("LaFuncion(b)"); n=1; disp(sign(u)); disp(sign(v)); if sign(u)==sign(v) disp('Error la La función debe cambiar de signo en (a,b)'); end while ((b-a)*0.5>tolerancia) c=(b+a)/2; w=evstr("LaFuncion(c)"); disp(['************ Paso : ', string(n), '************'] ); disp(['Valor c=', string(c)]); disp(['f(c)=', string(w)]); if sign(u)==sign(w) a=c; u=w; else b=c; v=w; end n=n+1; end; disp('************* La Raiz : *************'); x=c; endfunction;
VB.Net 2005, 2008 y 2010[editar]
Public Class metodos Dim c As Double Dim f_a As Double Dim f_b As Double Dim f_c As Double Dim er As Double Dim reporte As String Public i As Integer Dim valorfuncion As New EvalEcuaciones Public Function biseccion(ByVal a As Double, ByVal b As Double, ByVal tolerancia As Double) f_a = valorfuncion.EvaluaEcua(frmPrincipal.txtFuncion.Text, frmPrincipal.txtX_1.Text) f_b = valorfuncion.EvaluaEcua(frmPrincipal.txtFuncion.Text, frmPrincipal.txtX_2.Text) If ((f_a * f_b) < 0) Then c = (a + b) / 2 f_c = valorfuncion.EvaluaEcua(frmPrincipal.txtFuncion.Text, c) er = Math.Abs(a - c) reporte = CStr(i + 1) + "ª" + Chr(9) + "x= " + CStr(c) + Chr(9) + " f(x)= " + CStr(f_c) + Chr(9) +_ " error= " + CStr(er) + Chr(13) + Chr(10) i += 1 If (tolerancia <= er) Then If ((f_c * f_a) < 0) Then reporte += Convert.ToString(biseccion(a, c, tolerancia)) End If If ((f_c * f_b) < 0) Then reporte += Convert.ToString(biseccion(b, c, tolerancia)) End If End If End If Return reporte End Function End Class
Java[editar]
/** * * @author fredy Mosquera Lemus */ public class Biseccion { /** * Este metodo crea un funcion a la cual se le aplicara el método de * Biseccion teniendo como parametro de entrada un double x, el cual * sirve para la construccion de la funcion dentro del metodo * @param x * @return */ private double funcion(double x){ // return Math.sqrt( x*x +1 ) -4; return (x*x) - 3; } /** * Metodo de Biseccion el cual le halla las raices de una funciones en un intervalo * ingresado como parametro de entrada [a, b] y un el error con el cual * deseamos hallar nuestra funcion * @param a * @param b * @param error * @return */ public double metodoDeBiseccion(double a, double b, double error){ double c = 0.0; double fa; double fb; double fc; if((funcion(a) * funcion(b)) > 0){ System.out.println("Error en el intervalo, en ese intervalo no existen raices"); }else{ c = (a + b) /(double) 2; do{ fa = funcion(a); fb = funcion(b); fc = funcion(c); if((fa * fc) > 0){ a = c; fa = funcion(a); fb = funcion(b); c = (a + b) /(double) 2; fc = funcion(c); }else if((fb * fc) > 0 ){ b = c; fa = funcion(a); fb = funcion(b); c = (a + b) /(double) 2; fc = funcion(c); } }while(Math.abs(fc) >= error); } System.out.println("valor de la funcion: "+funcion(c)); return c; } }
Bibliografía[editar]
- Richard L Burden, J. Douglas Faires (2000), "Numerical Analysis, (7th Ed)", Brooks/Cole. ISBN 0-534-38216-9.




