1. 程式人生 > >非線性方程C/C++求解(二分法、牛頓法、牛頓下山法、弦截法)

非線性方程C/C++求解(二分法、牛頓法、牛頓下山法、弦截法)

Description

分別用(1)二分法;(2)牛頓法;(3)牛頓下山法;(4)弦截法;

計算下列方程的實根:<1> x*x-3*x+2-exp(x)=0;<2> x*x*x-x-1=0

要求:(1)精度為10^-8;(2)輸出迭代初值及歌詞迭代值和迭代次數,比較方法的優劣

參考程式碼

#include <cstdio>
#include <cmath>
#define percise 0.000000001

double func1(double v,bool id){//原函式
    if(id) return v*v-3*v+2-exp(v);//方程1 x^2-3*x+2-e^x=0
        else return v*v*v-v-1;//方程2 x^3-x-1=0
}
double func2(double v,bool id){//導數
    if(id) return 2*v-3-exp(v);//方程1的導數
        else return 3*v*v-1;//方程2的導數
}
void dichotomy(double x,double y,bool id){
    double middle=(x+y)/2;
    int i=0;
    printf("-----------------二分法-------------------\n");
    printf("初始值為:左邊界點%f,右邊界點%f\n",x,y);
    while(fabs(func1(middle,id))>percise){
        func1(middle,id)*func1(x,id)>0?x=middle:y=middle;
        middle=(x+y)/2;
        i++;
        printf("迭代次數為:%d,左邊界點%f,右邊界點%f\n",i,x,y);
    }
    printf("最終結果為%f\n",middle);
}
void NewtonMethod(double x,bool id){
    int i=0;
    printf("-----------------牛頓法-------------------\n");
    printf("初始值為%f\n",x);
    while(fabs(func1(x,id)/func2(x,id))>percise){
        x-=func1(x,id)/func2(x,id);
        i++;
        printf("迭代次數為:%d,此時x為%f\n",i,x);
    }
    printf("最終結果為%f\n",x);
}
void NewtonDownMethod(double x,bool id){
    int i=0;
    double x1,u=1;
    printf("---------------牛頓下山法------------------\n");
    printf("初始值為%f\n",x);
    while(fabs(func1(x,id)/func2(x,id))>percise){
        u=1;
        x1=x-u*func1(x,id)/func2(x,id);
        if(fabs(func1(x1,id))>=fabs(func1(x,id)))
             u*=0.5;
        i++;
        printf("迭代次數為:%d,此時x為%f,x1為%f,u為%f\n",i,x,x1,u);
        x=x1;
    }
    printf("最終結果為%f\n",x);
}
void SecantMethod(double x,double y,bool id){
    int i=0;
    printf("-----------------弦割法-------------------\n");
    while(fabs(func1(x,id)*(y-x)/(func1(y,id)-func1(x,id)))>percise){
        x-=func1(x,id)*(y-x)/(func1(y,id)-func1(x,id));
        i++;
        printf("迭代次數為:%d,此時x為%f\n",i,x);
    }
    printf("最終結果為%f\n",x);
}
int main() {
    dichotomy(0,1,1);dichotomy(1,2,0);//用二分法求兩個方程的解
    NewtonMethod(0,1);NewtonMethod(2,0);//用牛頓法求兩個方程的解
    NewtonDownMethod(-32,1);NewtonDownMethod(-11,0);//用牛頓下降法求兩個方程的解
    SecantMethod(-10,1,1);SecantMethod(-10,1,0);//用弦割法求兩個方程的解
    return 0;
}

優化和改進