1.实验内容
分别利用牛顿公式和二分法对某一方程(此实验是以开方公式为准,即x2-c=0,在验证时取c=115)进行求解。且对两者的求解结果进行比较,比较两者的迭代次数和精度。
分别编写函数Binary(min,
max, times)和 Newton(x0,
times)实现以上两种方法。实验初始界面:
选择编号进入相应的功能模块进行计算
2.主要函数
1)二分法:
函数参数:(min,max)表示二分区间,
times表示要进行多少次二分。
变量说明:mid
=(min +
max)/2.0,即每次二分后的点。
二分原理:对于给定的方程f(x)=0,在二分区间(min,
max)上,进行如下处理:
a.选择min与max的中点mid;
b.判断f(mid)是否等于0,若是则返回mid;
c.判断f(min)*f(mid)<0,若true,则max=mid;
d.否则min=mid;
f.判断次数是否达到times次,若是完成,若否返回a。
2)牛顿迭代函数
函数参数:x0表示给定的初值,times表示迭代次数;
牛顿迭代:按照牛顿迭代公式
把已知的初始值x0带入等式的右边,得到x1。然后再把x1带入右端得到x2,由于牛顿迭代公式的局部收敛性,当带入一个合适的初始值时,如此下去便能求得精度很高的近似值。
3.实验结果
1)。二分法结果
首先选择编号1进入二分功能模块,系统提示输入下限,即前面说的min,输入后回车,系统提示输入上限,即max,最后系统提示输入二分次数,即times。输入以后的结果如下:
从第9次与第10次对比可以知道,经过10次二分以后达到的精度为4次。
2)。牛顿迭代结果
选择2进入牛顿迭代功能模块,系统提示输入初始值,即前面的x0,接着系统提示输入迭代次数。回车以后的结果:
从4次开始,迭代结果就开始重复了,对比第2次与第3次可知,在相同给定的条件下,即给定初值为x0=10,经过三次牛顿迭代便达到了10为有效数字,可见牛顿迭代的速度要明显快于二分法。
为了与二分法进行平等的对比,这里在以二分的上限max=11来作为牛顿迭代的初始值,得到结果如下,其也是在第3次迭代后便达到了10位有效数字,可见牛顿迭代速度之快。
4.实验分析
牛顿迭代相对于二分法有明显的速度优势,但是二分法比牛顿法有更加重要的性质。对于二分法只要你给定一个足够大的包含解的上下限,一定能够经过有限次二分找到满足精度的解。但是对于牛顿迭代,由于其局部收敛性,当给定的初值远离真实值的时候,可能会发生发散的情况,其求解速度反而比二分要慢。如下这种情况:
二分法:(0.0001,
100)迭代次数为20次
通过最后两次的比较,其达到5位有效数字;
牛顿迭代,初始值x0=0.0001,同样迭代20次
比较最后两次,其达到4位有效数字。
5.实验源码
#include
#include
//#progmma comment(lib, "ws2_32.lib")
void menu();
double Newton(double x0, int times);
double Binary(double min, double max, int times);
//times表迭代次数,求解区间(min, max)
void First();
void Second();
double f(double x); //f(x)
double p(double x);
//f(x)的迭代格式
int main(){
int flag=0;
menu();
printf("\t\t请输入:");
scanf("%d", &flag);
while(flag){
if(flag == 1) {
First();
printf("\t\t----------------------------------------------\n");
}
else if(flag == 2) {
Second();
printf("\t\t----------------------------------------------\n");
}
else printf("\t\t输入错误!\n");
printf("\t\t请继续输入:");
scanf("%d", &flag);
}
printf("\t\tExit successful!\n");
return 0;
}
void menu(){
printf("\t\t---------方程(y = x*x - 115)求根--------------\n");
printf("\t\t
\n");
printf("\t\t
1. 二分法
\n");
printf("\t\t
2. 牛顿迭代
\n");
printf("\t\t
0. 退出
\n");
printf("\t\t----------------------------------------------\n");
}
void First(){
double max=0, min=0, fruit=0;
int times = 0; //迭代次数
printf("\t\t请输入下限:");//min
scanf("%lf", &min);
//这里min是double型数据,所以输入格式应该是%lf,如果按%f输入那么会造成输入错误
printf("\t\t请输入上限:");//max
scanf("%lf", &max);
printf("\t\t请输入二分次数:");//精度e
scanf("%d", ×);
fruit = Binary(min, max, times);
if(fruit == 0)
printf("此内没有解\n");
else
printf("\t\tBinary: .8f\n", fruit); //二分计算
}
double f(double x){
return x * x - 115;
}
double Binary(double min, double max, int
times){
double mid = 0;
int i=0;
//printf("min:%f max:%f\n", min,max);
printf("\n");
printf("\t\t
次数\t 结果\n");
for(i=1; i<=times; i++){
mid = (min + max)/2.0;
if(f(min)*f(mid) < 0)
max = mid;
else if(f(mid) == 0)
return mid;
else
min = mid;
printf("\t\t\t%d \t.8f\n", i, mid);
}
return mid;
}
double Newton(double x0, int times){
int i=0;
//printf("x0:%f times:%d\n", x0, times);
if(x0 == p(x0)) return x0; //如果x0刚好是解,直接返回
//printf("\t\t1 \t.8f\n", x0);
printf("\n");
printf("\t\t
次数\t 结果\n");
for(i=1; i<=times; i++){
x0 = p(x0);
printf("\t\t\t%d \t.8f\n", i, x0);
}
return x0;
}
//y = x*x - 115 的牛顿迭代格式为p(x);
double p(double x){
double fruit=0;
fruit = 0.5 * (x + 115.0/x);
//printf("p \t%f\n", fruit);
return fruit;
}
void Second(){
double x0=0;//x0表示初值
int times=0;//times表迭代次数
printf("\t\t请输入初值:");//x0
scanf("%lf", &x0);
printf("\t\t请输入迭代次数:");//e
scanf("%d", ×);
printf("\t\tNewton: .8f\n", Newton(x0, times));
}