非线性方程组的二分法与三分法求根

已知某非线性方程(常为n方多项式),手动计算难以求解。因此,我们利用计算机擅长繁冗大量计算的特点,将其转换为程序,计算机执行即可。

首先,二分法的求解是我们常用的方法之一。

二分法的定义:

对于区间[a,b]上连续不断且f(a)·f(b)<0的函数y=f(x),通过不断地把函数f(x)的零点所在的区间一分为二,使区间的两个端点逐步逼近零点,进而得到零点近似值的方法叫二分法。(来自百度)

 

代码实现:

#include<iostream>
#include<cmath>

using namespace std;

double f(float x)
// f(x) 函数体 以2倍的x的三次方减去4倍的x的二次方加3倍的x减6 为例
//返回函数值
{
    double y = 2*x*x*x - 4*x*x + 3*x - 6;
    return y;
}
//主函数
int main()
{
    float x1 = -10.0;
    float x2 = 10.0;
    float mid , f1 , fmid;
    //定义 x1 与 x2 的中间值mid 与其对应的函数值 fmid
    //定义 x1 对应的函数值 f1
    if(f(x1)*f(x2)>0)
    {
        printf("不一定有根");
        return 0;
    }
    //如果选取的两个点不相等的话 即为有大于等于0.000001的空隙
    while(fabs(x1-x2)>=0.000001)
    {
        mid=(x1+x2)/2;
        f1=f(x1);
        fmid=f(mid);
        if(fmid==0) break;
        //中间值恰好为根
        else if(f1*fmid<0) x2=mid;
        //f1与fmid异号 则用mid代替x2
        else x1=mid;
        //否则即为x2的函数值与fmid异号 则用mid代替x1
    }
    printf("%6.6f",(x1+x2)/2);

    return 0;
}

可以看到,二分法主要借助一中间变量以及其函数值来判断是否是根。

其次推广到三分法。

三分法是基于二分法的概念,将间隔平均分为三份。

代码实现:

#include<iostream>
#include<cmath>

using namespace std;

double f(float x)
{
    double y = 2*x*x*x - 4*x*x + 3*x - 6;
    return y;
}
int main()
{
    float a,b,h,fa,f1,f2,fb,t1,t2;
    a = -10,b = 10;
    if(f(a)*f(b)>0)
    {
        printf("不一定有根");
        return 0;
    }
    while(fabs(a-b)>=0.000001)
    {
        h = fabs(b-a)/3;
        t1 = a+h;
        t2 = a+2*h;
        fa = f(a);
        fb = f(b);
        f1 = f(t1);
        f2 = f(t2);
        if(f1==0)
        {
            printf("%.6f",t1);
            break;
        }
        else if(f2==0)
        {
            printf("%.6f",t2);
            break;
        }
        else if(fa == 0)
        {
            printf("%.6f",a);
            break;
        }
        //if(f1 == 0) printf("%.6f",t1);
        //if(f2 == 0) printf("%.6f",t2);
        else if(fb == 0)
        {
            printf("%.6f",b);
            break;
        }
        if(fa*f1<0)
            b=t1;
        else if(fa*f2<0)
            b=t2;
        else if(fb*f2<0)
            a=t2;
        else if(fb*f1<0)
            a=f1;
        else
        {
            a=t1;
            b=t2;
        }
    }
    return 0;

}

三分法代码的bug是在找h的时候,应该用后面的减去前面的,取绝对值除以三才是三等分,和二分不一样,因为你得考虑符号问题:就是那个 ( -10 + 10) 的话就是 0,你的 h 就变成 0 了不管a与b怎么加减都是不变的,然后导致循环一直进行没有停止,也就没有输出。

再有就是,后面的情况考虑全面,加上 a b 现在一共有四个点,考虑t1 t2 (判断顺序换了应该也没问题,情况全面就可以乐)。

最后就是输出,要是三分法就不能直接输出(a+b)/3了,因为你不知道实在哪个三分点,所以直接在循环里面判断完接着输出就好乐。

希望能帮到大家。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值