/**
  对分法求非线性方程的根  

   算法思想:在区间[a,b]间找到所有根,从a开始搜寻,步长h.
      对每一个子区间[xi ,xi+1],    xi+1 = xi +h:
1.若f(xi) = 0, xi为实根,从xi +h/2 继续搜索2.若f(xi+1) = 0, xi+1为实根,  从  xi+1+h/2 继续搜索
3..若f(xi) f(xi+1) >0, 当前子区间无实根, 从xi+1继续搜索
4...若f(xi) f(xi+1) <0, 当前子区间有实根 ,二分搜索寻找根(当然,只能找到一个根)
注意步长h的选择, 过大导致漏根, 过小导致计算量增大.
                                                               
《数值计算方法与算法》-2 Editon -科学出版社 P86
《C#数值计算算法编程》 p207

 代码维护:2007.04.20   pengkuny
**/ 

#include<iostream>
#include
<cmath>

using namespace std;

#define epsilon 0.00001  //精度

double func(double x)//方程表达式
{
    
double y;
    y 
= (((((x-5)*x+3)*x+1)*x-7)*x+7)*x-20;  //范例方程,6次方程,至多六个实根
    return y;
}


/**
nNumRoots:实根个数的预估值
x[]:记录搜索到的所有实根,
xStart: 区间的左端点
xEnd :  区间的右端点
Step :  搜索求根时采用的步长
返回:求得的实根的数目
*/

int getRootBisect(int nNumRoots, double x[], double xStart, double xEnd, double Step)
{
    
int n,js;
    
double z,y,z1,y1,z0,y0;

    
// 根的个数清0
    n = 0

    
// 从左端点开始搜索
    z = xStart; 
    y 
= func(z);

    
// 循环求解
    while ((z<=xEnd+Step/2.0&& (n!=nNumRoots))
    

        
if (fabs(y)<epsilon)
        

            n
++
            x[n
-1= z;
            z 
= z+Step/2.0
            y 
= func(z);
        }

        
else
        

            z1 
= z+Step; 
            y1 
= func(z1);

            
if (fabs(y1)<epsilon)
            

                n
++
                x[n
-1]=z1;
                z
=z1+Step/2.0
                y
=func(z);
            }

            
else if (y*y1>0.0)
            

                y
=y1; 
                z
=z1;
            }

            
else
            

                js
=0;//是否找到根的标志
                while (js==0)
                

                    
if (fabs(z1-z)<epsilon)
                    

                        n
++
                        x[n
-1]=(z1+z)/2.0;
                        z
=z1+Step/2.0; y=func(z);
                        js
=1;
                    }

                    
else//对分搜索
                    
                        z0
=(z1+z)/2.0
                        y0
=func(z0);
                        
if (fabs(y0)<epsilon)
                        

                            x[n]
=z0; 
                            n
++
                            js
=1;
                            z
=z0+Step/2.0
                            y
=func(z);
                        }

                        
else if ((y*y0)<0.0)
                        

                            z1
=z0; 
                            y1
=y0;
                        }

                        
else 
                        

                            z
=z0; 
                            y
=y0;
                        }

                    }

                }

            }

        }

    }


    
// 返回实根的数目
    return(n);
}


int main()
{
    cout
<<"对分法求解非线性方程:"<<endl;

    
double a = -2.5, b = 5;
    
double *x= new double[6];

    
int n = getRootBisect(6, x, a, b, 0.2);
    cout
<<"共有"<<n<<"个根:"<<endl;
    
for (int i =0; i<n; i++)
    
{
        cout
<<"  "<<x[i];
    }

    cout
<<endl;

    system(
"pause");
    
return 0;
}

 

posted on 2007-04-20 19:35 哈哈 阅读(1647) 评论(1)  编辑 收藏 引用

评论:
# re: 对分法求非线性方程的根 2008-05-18 11:52 | ijhokh
chaoxi  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理