Red de conocimiento informático - Material del sitio web - Algoritmos y procedimientos para encontrar raíces de polinomios

Algoritmos y procedimientos para encontrar raíces de polinomios

Esta cuestión se puede resolver mediante el método de la dicotomía. Por supuesto, la dicotomía mencionada aquí no es tan simple y clara como la del libro de Tan Haoqiang, y no puede determinarse mediante f (x1) * f (x2) lt; 0. Porque el ejemplo que dio fue encontrar raíces en un intervalo monótono, pero aquí necesitamos encontrar todas las soluciones, y el intervalo no es necesariamente monótono. La última vez que publiqué un programa similar, alguien comentó que no era bueno porque simplemente no entendía que la dificultad de encontrar todas las raíces en un intervalo no monótono no es comparable a la de encontrar una raíz en un intervalo monótono. Esto demuestra que no entendía en absoluto el propósito del algoritmo.

La idea aquí es establecer primero un intervalo y cuanto más preciso sea el cambio real, mejor. Por supuesto, no se pueden pasar por alto las raíces. Al mismo tiempo, cuanto menor es h, mayor es el tiempo de cálculo, pero mayor es la precisión del resultado, por lo que el valor debe tomarse en consideración en función de la precisión y el tiempo de ejecución requerido por el programa, aquí es 0.1 .

Al mismo tiempo, para mejorar la velocidad de cálculo, se utiliza el famoso método de evaluación de Horner. Es decir, encontrar 3x^3-5x^2 x 1 se transforma en encontrar ((3x-5)x 1)x 1, porque el primer método de búsqueda requiere 7 multiplicaciones, mientras que el método con paréntesis solo requiere 3 multiplicaciones. Por supuesto, si la función polinómica es par o impar, el intervalo [a, b] también se puede simplificar.

Se establece un polinomio en el programa y se puede cambiar al polinomio deseado.

Un programa c completo es el siguiente. El programa ha sido depurado tanto en win-tc como en Dev-c.

#include lt;math.hgt;

#include lt;stdio.hgt

#include lt;stdlib.hgt; p>doble ecuación(doble x)

{

doble z

z=(((((x-5.0)*x 3.0)*x 1.0)*x-7.0)*x 7.0)*x-20.0; /*Cambiar al polinomio real*/

return(z

}

int BinSearchRoot(double a, double b, double h, double eps, double x[], int m) /*Utiliza el método binario para calcular las raíces reales de ecuaciones no lineales*/

/*Parámetro significado:

a El límite inferior de la raíz requerida

b El límite superior de la raíz requerida, es decir: la raíz requerida cae dentro del intervalo [a, b]

h tamaño de paso progresivo

precisión de eps

x valor de raíz

m número esperado de raíces*/

{

int n, js;

doble z, y, z1, y1, z0, y0; (z);

while ((zlt; =b h/2.0)amp; amp; (n!=m)) /*Buscar el subintervalo con un tamaño de paso determinado*/

{

if (fabs(y)lt; eps) /*El punto de decisión actual es la raíz de la ecuación*/

{

n =n 1;

x[n-1]=z;

z=z h/2.0; p >

}

else /*El punto actual no es una raíz de la ecuación*/

{

z1=z h

y1 =Equation(z1);

if (fabs(y1)lt; eps) /*El siguiente punto es la raíz de la ecuación*/

{

n =n 1;

x[n-1]=z1

z=z1 h/2.0; Equation(z);

p>

}

else if (y*y1gt; 0.0) /*No hay raíz en este intervalo*/

{ y=y1; z=z1;}

else /*Hay una raíz en este intervalo*/

{

js=0; /* Bandera, 0 significa que no se ha encontrado la raíz, 1 significa que se ha determinado la raíz */

while (js==0) ​​​​

{

if (fabs(z1-z)lt;eps) /*La longitud del intervalo es menor que la dada. Con cierta precisión, se puede considerar que se ha encontrado la raíz*/

{

n=n 1;

x[n-1]=(z1 z )/2.0 /*Utilice el valor mediano del intervalo como raíz*/

z=z1 h/2.0; /*Colocar la posición de búsqueda en el siguiente intervalo*/

y=Equation(z); La raíz se ha encontrado en el intervalo actual*/

}

else /*Intervalo Si es mayor que la precisión dada, realice dos divisiones*/

{

z0=(z1 z)/2.0; /*Bisección de intervalo*/

y0=Ecuación(z0);

if (fabs(y0)lt; eps) /*z0 posición es la raíz*/

{

x[n]=z0

n=n 1;

z=z0 h/2.0;

y=Ecuación(z)

}

si no ((y*y0); ) lt; 0.0) /*[z, z0] tiene raíces*/

{ z1=z0; y1=y0;}

else { z=z0; }

}

}

}

}

}

regresar( n); /*Devuelve el número de raíces*/

}

int main()

{

int i, n

estático int m=6;

estático doble x[6]

sistema("cls"); ("\nLa función no lineal es:\n");

printf("\nf(x)=(((((x-5.0)*x 3.0)*x 1.0)*x-7.0 )*x 7.0)*x-20.0\n"); /*Cambiar al polinomio real*/

n=BinSearchRoot(-100.0, 150.0, 0.1, 0.000001, x, m);

printf("\nLa función tiene d raíces, son:\n", n /*Muestra el número de raíces*/

for (i=0; ilt;=n); -1; i)

printf("x(d)=10.7f\n",i,x[i]);

sistema("pausa"); p>

p>

return 0;

}

Posdata: Baidu es un lugar relativamente impetuoso. Me río de los comentarios irresponsables de algunas personas. Si no puede entender las cosas verdaderamente correctas, sólo significa que aún no ha alcanzado ese nivel y tiene que buscar las razones dentro de sí mismo.

Evidentemente el método de la dicotomía no puede resolver el problema de la raíz virtual.