对分法求非线性方程的根
来源:互联网 发布:手机推广软件 编辑:程序博客网 时间:2024/06/10 17:34
对于非线性方程的求解,有时候很难找到解的解析函数,所以只能才用数值求解。常见的一些非线性方程为
算法的基本原理:如果非线性方程f(x)=0,的左端函数f(x)在区间[a,b]上连续,并满足f(a)f(b)<0,则方程至少有一个实根。
基本思想:逐步缩小这个有根的区间,当这个区间减少到一定程序时,就取这个中点作为根的近似值。
如果在区间[a,b]内有多个实根,则单独利用对分法只能得到其一个实根。所以,将对分法与逐步扫描法结合使用,以便尽量搜索给定区间的实根,这种方法概括如下:
(1)从区间左端点x=a开始,以h为步长,逐步往后进行搜索。
(2)对于在搜索过程中遇到的每一个子区间[xk,xk+1], 其中,xk+1=xk+h。进行如下处理:
1.若f(xk)=0,则xk为一个实根,从xk+0.5h开始往后搜索
2.容易f(xk+1)=0,则xk+1为一个实根,从xk+1+0.5h开始搜索
3.若f(xk)f(xk+1)>0,则子区间无实根或h选的过大,放弃本子区间,从xk+1开始搜索
4.容易f(xk)f(xk+1)<0,则当前区间有实根,继续利用对分法,直到求到一个实根为止。,然后从
xk+1开始往后搜索。
代码如下:
/*二分法搜索方程的实根*函数int dhrt(double a,double b,double h,double eps,double *x,int m,double (*f)(double))*double a:求根区间的左端点*double b:求根区间的右端点*double h:搜索求根时所采用的步长*double eps:控制的精度要求*double* x:返回在区间[a,b]搜索到的实根。实根个数由函数值返回*int m:在区间[a,b]内实根个数的预估值*double (*f)(double):f(x)的迭代函数*/#include <iostream>#include<cmath>#include<iomanip>using namespace std;int dhrt(double a, double b, double h, double eps, double *x, int m, double(*f)(double)){ int n = 0; int js = 0; double z = a; //搜素区间的中间点 double z1; //定义的搜素区间的末端 double z0; //定义的搜素区间的起始端 double y1; //用于存放z1点的函数结果 double y0; //用于存放z0点的函数结果 double y = (*f)(z); //用于存放函数z点处的函数结果 //计算过程 while ((z <= b + h / 2) && (n != m)) { if (fabs(y)<eps) //如果值满足“精度要求eps“下的0状态 { n = n + 1; //进行下一次查找 x[n - 1] = z; //保存节点值 z = z + h / 2.0; //变换起始区间加0.5h继续搜素 y = (*f)(z); //计算中点处的值 } else //当中点处的值不满足精度要求的根时 { z1 = z + h; //z1是搜素的子尾区间点 y1 = (*f)(z1); //计算子尾点区间的值 if (fabs(y1)<eps) //如果子尾区间点的值正好满足精度要求 { n = n + 1; //则同上,保存根 x[n - 1] = z; z = z1 + h / 2.0; //子区间起始点加0.5h y = (*f)(z); } else if (y*y1>0.0) //首尾根节点的函数值为正,则表示无根,所以往后开始搜素 { y = y1; z = z1; } else //如果有根,则二分查找 { js = 0; while (js == 0) //立一个flag { if (fabs(z1 - z)<eps) //如果(z1-z)满足精度要求 { n = n + 1; x[n - 1] = (z1 + z) / 2.0; z = z1 + h / 2.0; //搜素起始区间加h y = (*f)(z); js = 1; //flag为1 } else //如果不满足判断要求,继续二分 { z0 = (z1 + z) / 2.0; //计算中点处的值 y0 = (*f)(z0); if (fabs(y0)<eps) //满足精度要求就保存,同上 { x[n] = z0; n = n + 1; js = 1; z = z0 + h / 2; y = (*f)(z); } else if (y*y0<0.0) //相异有根 { z1 = z0; y1 = y0; } else //否则相同无根 { z = z0; y = y0; } } } } } } return n;}double func(double x){ return x*x - 3 * x + 2 - exp(x);}int main(){ cout << "Hello world!" << endl; double a[5]; int n; n = dhrt(0, 1, 0.05, 0.0000001, a, 2, func); cout << n << endl; cout << setprecision(8) << a[0] << " " << endl; return 0;}
注意一点:函数指针那个子程序是对应着不同的函数,需要自己定制!!
1 0
- 对分法求非线性方程的根
- 试位法求解非线性方程的根
- 非线性方程的解法
- MATLAB实例之对线性,非线性,超越方程的求解
- 对分法求解非线性方程
- 用牛顿方法解一元非线性方程的根
- 【数值计算】数值解析--非线性方程的根
- 用牛顿的迭代法求解非线性方程
- 非线性方程(组)的求解
- 二分法 简单迭代法 Newton法 弦截法 求解非线性方程的根
- 用牛顿方法解一元非线性方程的根(Matlab实现)
- Matlab非线性方程求根
- 二分法解非线性方程
- 非线性方程求解
- 非线性方程求根
- 试位法求解非线性方程
- Python求解非线性方程
- Python解非线性方程
- 文件I/O流读写
- Android Studio如何快速生成get,set,tostring,构造函数
- 《基于Apache Kylin构建大数据分析平台》
- Web开发---过滤器(Filter)
- 2016年12月15日开通的博客,技术生涯就从此刻开始!
- 对分法求非线性方程的根
- 根据easyUI的datagrid里字段值关联出其他值(显示其他值)
- OSI网络体系结构及其各层主要协议
- Android 测试开发 - 工具ADB
- source insight style 配色方案
- <xliff:g>标签介绍
- 各大快递电子面单---Api接口(顺丰、快递鸟、菜鸟)
- Atitit xml命名空间机制
- dokuwiki登录设置