Chinaunix首页 | 论坛 | 博客
  • 博客访问: 107738
  • 博文数量: 106
  • 博客积分: 2025
  • 博客等级: 大尉
  • 技术积分: 1165
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-06 12:51
文章分类

全部博文(106)

文章存档

2012年(106)

我的朋友

分类: C/C++

2012-05-08 01:35:50

求解方程:f(x)=0的解 f(x)=3x^4-5x^3+4x-11 迭代多少次

练习:求解方程:f(x)=0的解f(x)=3x^4-5x^3+4x-11 迭代多少次

程序如下:

1.迭代法(不动点法):(利用公式:Sn-1=Sn-f(Sn)/f’(Sn) (n=0,1,^)

/*算法描述:
用迭代法求下面方程
y=x(x*x(3*x-5)+3)-11
的实根的过程是:
1.
想在谁附近求解,这个范围或者这个数值大多是题目已经给定了的(本程序是根据输入的数值来计算的)
2.
f(x)=x(x*x(3*x-5)+3)-11
3.x1=X
4.
f(x1)
5.
f(x)求导,得到f1(x),f1(x1)
6.
调整x,使x=x1-f(x1)/f1(x1)
7.
符合条件x-x1>1e-6,转到第3
8.
不符合条件x-x1>1e-6,则x1就是要求的实根
*/
#include

#include

//y=x(x*x(3*x-5)+3)-11

float f(float x)

{

return (3*pow(x,4)-5*pow(x,3)+4*x-11);

}

float f1(float x)

{

return (12*pow(x,3)-15*pow(x,2)+3);

}

void main()

{

float x,x1,y1,y2;

int n=0;

printf("请输入一个任意实数:X=");

scanf("%f",&x);

printf("这个方程的近似解\n");

do

{

x1=x;

y1=f(x);

y2=f1(x1);

x=x1-y1/y2;

n++;

}

while (fabs(x-x1)>=1e-6);

printf("A root is %f\n",x1);

printf("迭代次数:%d\n",n);

}

未解决问题:

无法求出全部的解,只能根据猜想的范围来进行取值,如此题我就是取了四个值,分别是正数、负数、0和特殊值,然后得到了2个解。但如果是更加复杂的方程,x的次数很高,我不知道如何才能找到准确的全部解。另外,在我取值1时,出现了1.#INF00的结果。我发现这是由于当X1时,f1(x)=0,这样就使得除数为0,所以产生了这样的结果,但改写程序后依然错误。还需要再思考下!

改写:

#include

#include

//y=x(x*x(3*x-5)+3)-11

float f(float x)

{

return (3*pow(x,4)-5*pow(x,3)+4*x-11);

}

float f1(float x)

{

float t,s;

t=12*pow(x,3)-15*pow(x,2)+3;

if(t==0)

{printf("ERROR,INPUT AGAIN: ");

scanf("%f",&s);

float f1(s);}

else return t;

}

void main()

{

float x,x1,y1,y2;

int n=0;

printf("请输入一个任意实数:X=");

scanf("%f",&x);

printf("这个方程的近似解\n");

do

{

x1=x;

y2=f1(x1);

y1=f(x);

x=x1-y1/y2;

n++;

}

while (fabs(x-x1)>=1e-6);

printf("A root is %f\n",x1);

printf("迭代次数:%d\n",n);

}

2.二分法:

#include

#include

double f(double x)

{

return 3*x*x*x*x-5*x*x*x+4*x-11;

}

main()

{

int n=0;

double left=-10,right=10,mid;

double ans;

do

{

mid=(left+right)/2;

ans=f(mid);

if(ans>0)

right=mid;

else if(ans<0)

left=mid;

else

break;

n++;

}while(right-left>1e-6);

printf("近似结果:%lf\t%lf\n",mid,ans);

printf("迭代次数:%d\n",n);

}

3.弦截法:

//弦截法求3*x*x*x*x-5*x*x*x+4*x-11=0的根

#include

#include

float f(float x)

{ //计算f(x)的值

return 3*x*x*x*x-5*x*x*x+4*x-11;

}

float point(float x1 ,float x2)

{

//计算与x轴交点的x

return (x1*f(x2)-x2*f(x1))/(f(x2)-f(x1));

}

void main()

{

int n=0;

//输入两个数x1,x2

float x1,x2,x;

do

{

printf("输入两个数x1,x2:");

scanf("%f%f",&x1,&x2);

}

while (f(x1)*f(x2) >= 0); //当输入两个数大于0为真时,继续重新输入

//关键循环步骤:

do

{

x=point(x1,x2);//得到交点的值

if(f(x)*f(x1)>0)

x1=x; //新的x1

else

x2=x;

n++;

}

while (fabs(f(x)) > 0.000001); //0.000001为取值精度

printf("一个解为%f\n",x);

printf("迭代次数:%d\n",n);

}

经过三种方法的结果对比可知二分法不能计算复根和重根,不动点法可以用来求方程的重根、复根,单纯的从算法说,不动点法循环的次数比二分法少,并且误差也比较小。弦截法比二分法收敛得快。效率二分法<弦截法<不动点法

 

阅读(310) | 评论(0) | 转发(0) |
0

上一篇:传统算法小结

下一篇:传统算法

给主人留下些什么吧!~~