牛顿下山法

  • 问题描述


输入:初值,误差限,迭代最大次数,下山最大次数

输出:近似根各步下山因子

  • 基本公式


  • 流程图


  • 算法实现
#include <iostream>
#include <math.h>
#include <queue>
#include <iomanip>

using namespace std;

//定义队列保存近似根
queue <double> root;
//记录每步的下山次数
queue <int> count;
//记录每步的因子
queue <double> factor;
//定义原函数
double function(double x,double y);
//定义导函数
double derivative(double x);
//定义牛顿下山法
void Newton(double x,double e,int N,int M);
//输出函数
void print();

int main()
{
    //定义初值,误差限
    double x,e;
    //定义迭代最大次数,下山最大次数
    int N, M;
    char c = 'y';
    while(c != 'n'){
        cout<<"请依次输入初值、误差限、迭代最大次数、下山最大次数:";
        cin>>x>>e>>N>>M;
        Newton(x,e,N,M);
        print();
        cout<<"是否继续?按n退出:";
        cin>>c;
    }
    return 0;
}
//定义原函数
double function(double x)
{
    return pow(x,3) - x - 1;
}
//定义导函数
double derivative(double x)
{
    return 3*x*x - 1;
}
//定义牛顿下山法
void Newton(double x,double e,int N,int M)
{
    int k = 0,i;
    double lamda,x1;
    while(k<N)
    {
        if(derivative(x)==0){
            cout<<"奇异标志"<<endl;
            return;
        }
        else{
            i = 0;
            lamda = 1;
            factor.push(lamda);
            while(true)
            {
                x1 = x - lamda * function(x)/derivative(x);
                root.push(x1);
                if(fabs(function(x1) < fabs(function(x))))
                {
                    break;
                }
                else{
                    i +=1;
                    lamda *= 0.5;
                }
                if(i>=M)
                {
                    cout<<"迭代失败,请重新输入初值x"<<endl;
                    return;
                }
                factor.push(lamda);
                count.push(i);
                root.push(x1);
            }
            if(fabs(x1 - x) < e)
            {
                cout<<"结果为:"<<x1<<endl;
                return;
            }
            else{
                k+=1;
                x = x1;
            }
        }
    }
    cout<<"迭代失败"<<endl;
    return;
}
//输出函数
void print()
{
    cout<<"------------------------------------------------------------------"<<endl;
    cout<<" k    "<<"近似根  "<<"下山因子 "<<"下山次数  "<<endl;
    int k =1,c;
    double f;
    while(!root.empty()){
        f = factor.front();
        c = count.front();
        cout<<setiosflags(ios::fixed);
        cout<<setprecision(6)<<setw(2)<<k<<" "<<root.front()<<" "<<f<<" "<<setw(2)<<c<<endl;
        if(factor.size() != 1)
        {
            factor.pop();
        }
        if(count.size() != 1){
            count.pop();
        }
        root.pop();
        k++;
    }
} 

  • 运行截图



猜你喜欢

转载自blog.csdn.net/qq_39559641/article/details/81051069