二分法求解方程的根java_【数值分析】利用二分法和牛顿公式求解方程的根

1.实验内容

​分别利用牛顿公式和二分法对某一方程(此实验是以开方公式为准,即x2-c=0,在验证时取c=115)进行求解。且对两者的求解结果进行比较,比较两者的迭代次数和精度。

分别编写函数Binary(min,

max, times)和 Newton(x0,

times)实现以上两种方法。实验初始界面:

a4c26d1e5885305701be709a3d33442f.png选择编号进入相应的功能模块进行计算

2.主要函数

1)二分法:

a4c26d1e5885305701be709a3d33442f.png

​函数参数:(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表示迭代次数;

a4c26d1e5885305701be709a3d33442f.png

​牛顿迭代:按照牛顿迭代公式

a4c26d1e5885305701be709a3d33442f.png

​把已知的初始值x0带入等式的右边,得到x1。然后再把x1带入右端得到x2,由于牛顿迭代公式的局部收敛性,当带入一个合适的初始值时,如此下去便能求得精度很高的近似值。

3.实验结果

1)。二分法结果​

首先选择编号1进入二分功能模块,系统提示输入下限,即前面说的min,输入后回车,系统提示输入上限,即max,最后系统提示输入二分次数,即times。输入以后的结果如下:​

a4c26d1e5885305701be709a3d33442f.png

从第9次与第10次对比可以知道,经过10次二分以后达到的精度为4次。

2)。牛顿迭代结果

选择2进入牛顿迭代功能模块,系统提示输入初始值,即前面的x0,接着系统提示输入迭代次数。回车以后的结果:

a4c26d1e5885305701be709a3d33442f.png

从4次开始,迭代结果就开始重复了,对比第2次与第3次可知,在相同给定的条件下,即给定初值为x0=10,经过三次牛顿迭代便达到了10为有效数字,可见牛顿迭代的速度要明显快于二分法。

为了与二分法进行平等的对比,这里在以二分的上限max=11来作为牛顿迭代的初始值,得到结果如下,其也是在第3次迭代后便达到了10位有效数字,可见牛顿迭代速度之快。

a4c26d1e5885305701be709a3d33442f.png

​4.实验分析

​牛顿迭代相对于二分法有明显的速度优势,但是二分法比牛顿法有更加重要的性质。对于二分法只要你给定一个足够大的包含解的上下限,一定能够经过有限次二分找到满足精度的解。但是对于牛顿迭代,由于其局部收敛性,当给定的初值远离真实值的时候,可能会发生发散的情况,其求解速度反而比二分要慢。如下这种情况:

二分法:(0.0001,

100)迭代次数为20次

a4c26d1e5885305701be709a3d33442f.png

通过最后两次的比较,其达到5位有效数字;

牛顿迭代,初始值x0=0.0001,同样迭代20次

a4c26d1e5885305701be709a3d33442f.png

比较最后两次,其达到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));

}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值