//x^3-24x^2+167x-312=0 求根问题
//方法1:折半查找法
// 先分析左边多项式函数,得到两个极值点:
// 其中8-5/sqrt(3)为极大值点,8+5/sqrt(3)为极小值点
// 它们把区间分成三部分,三个根就在这三部分中找
//方法2:牛顿迭代法
// 给一个x0,找x0附近的根;利用公式x1=x0-f(x0)/f'(x0)进行迭代,直到收敛
#include <stdio.h>
#include <math.h>
#include <conio.h>
//给定的函数
double f(double x)
{ return x*x*x-24*x*x + 167*x - 312;}
//给定函数的一阶导函数:用于牛顿迭代法求根
double df(double x)
{ return 3*x*x - 24*x + 167;}
//在(left,right)区间内求一个根
//使用折半查找的方法
double solve(double left,double right,double (*pf)(double))
{ double mid=(left+right)/2.0;
if(fabs(pf(mid))<1e-6) return mid;
if(fabs(pf(left)-pf(right))<1e-6) return mid;
if(pf(mid)*pf(left)>0.0) return solve(mid,right,pf);
if(pf(mid)*pf(right)>0.0) return solve(left,mid,pf);
}
//牛顿迭代法求根 x1=x0-f(x0)/f1(x0), f1是f的导函数
double solve_Newton(double x0,double (*f)(double),double (*f1)(double))
{
double x1,delta;
do{ x1 = x0-f(x0)/f1(x0);
//if(fabs(f(x1)-f(x0))<1e-6) break;
delta = x1-x0;
x0 = x1;
}while(fabs(delta)>1e-8);
return (x1+x0)/2.0;
}
//测试折半查找法
int test_1()
{ double x1=8.0-5/sqrt(3.0); //左边驻点(极大值点)
double x2=8.0+5/sqrt(3.0); //右边驻点 (极小值点)
double left,right; //最左边区间的左端点,和最右边区间的右端点
double solve0,solve1,solve2;//三个解
left = x1-10; right = x2+10;
while(f(left)>0.0) left = left -10; //确定合适的最左边搜索区间的左端点
while(f(right)<0.0) right+=10; //确定合适的最右边搜索区间的右端点
solve0 = solve(left, x1,f);
solve1 = solve(x1,x2,f);
solve2 = solve(x2,right,f);
printf("驻点:\t\t%lf\t%lf\n",x1,x2);
printf("驻点函数值:\t%lf\t%lf\n",f(x1),f(x2));
printf("解:\t\t%lf %lf %lf\n",solve0, solve1, solve2);
printf("对应函数值:\t%lf %lf %lf\n",f(solve0), f(solve1), f(solve2));
return 0;
}
//测试牛顿迭代法求解
int test_2()
{ double x1=8.0-5/sqrt(3.0); //左边驻点(极大值点)
double x2=8.0+5/sqrt(3.0); //右边驻点 (极小值点)
double solve0,solve1,solve2;//三个解
solve0 = solve_Newton(x1-100,f,df);
solve1 = solve_Newton((x1+x2)/2,f,df);
solve2 = solve_Newton(x2+100,f,df);
printf("驻点:\t\t%lf\t%lf\n",x1,x2);
printf("驻点函数值:\t%lf\t%lf\n",f(x1),f(x2));
printf("解:\t\t%lf %lf %lf\n",solve0, solve1, solve2);
printf("对应函数值:\t%lf %lf %lf\n",f(solve0), f(solve1), f(solve2));
return 0;
}
int main()
{
printf("【求方程x^3-24x^2+167x-312=0的根】\n解:\n");
printf("------------用折半查找法求解------------\n");
test_1();
printf("\n------------用牛顿迭代法求解------------\n");
test_2();
printf("\n按任意键退出...");
getch();
return 0;
}
运行情况截图:
跟手动进行因式分解算出的根3,8,13一致。