// ConsoleAppNewtonSolu1.cpp : 定义控制台应用程序的入口点。
//
/*
*函数功能:牛顿迭代法,求方程exp(-x)-sin(pi/2*x)=0的根
*函数原形:double NewtonSolu1(double acc);
*参数:double acc,精度要求
*返回值:方程的根
*时间复杂度:O(1)
*备注:牛顿迭代法最好选取接近真实解值作为迭代初始值
*日期:2014/11/30
*原创:是
*作者:EbowTang
*Email:tangyibiao520@163.com
*/
#include "stdafx.h"
#include "math.h"
#include <iostream>
using namespace std;
const double pi=3.1415926;
double NewtonSolu1( double acc);
void NewtonSolu1Test();
int _tmain(int argc, _TCHAR* argv[])
{
NewtonSolu1Test();
return 0;
}
double NewtonSolu1(double acc)
{
double oldX=0.5;//迭代的初始值
double newX=0.0;//临时中间值的初始化,用于保存上一次迭代后xk1的值
int count=0;
while (abs(newX-oldX)>acc)//解的精度
{
newX=oldX;//xk用于保存上一次迭代的结果值
oldX=newX+((exp(-newX)-sin(pi*newX/2))/(exp(-newX)+(pi/2)*cos(pi*newX/2)));//计算这一次迭代的值并重新附给xk1
count++;
if (count>255)
{
cout<<"此迭代法可能是发散的,请检查收敛性!"<<endl;
return 0;
}
}
if (count<255)
cout<<"迭代了:"<<count<<"次"<<endl;
return oldX;
}
void NewtonSolu1Test()
{
double r=0.0;//保存求平方根后的结果
double acc=0.0001;
char ans='n';
do
{
cout<<"“求方程exp(-x)-sin(pi/2*x)=0的根”"<<endl;
cout<<"/****************牛顿迭代法的华丽分割线(迭代初始值为0.5)***************/"<<endl;
cout<<"请输入精度要求:";
cin>>acc;
r=NewtonSolu1(acc);
cout<<"方程的根为:"<<r<<endl;
cout<<"是否继续?(y/n)";
cin>>ans;
} while (ans=='y');
}
// ConsoleAppDichotomySolu.cpp : 定义控制台应用程序的入口点。
//
/*
*函数功能:二分法,求方程exp(-x)-sin(pi*x/2)=0的根
*函数原形:double DichotomySolu1(double a,double b,double e);
*参数:double a,double b,double e,a为区间上限,b为区间下限,e为误差
*返回值:方程的根
*时间复杂度:O(1)
*备注:务必确保二分区间有根
*日期:2014/11/30
*原创:是
*作者:EbowTang
*Email:tangyibiao520@163.com
*/
#include "stdafx.h"
#include "math.h"
#include <iostream>
using namespace std;
const double pi=3.1415926;
double DichotomySolu1(double a,double b,double e);
int _tmain(int argc, _TCHAR* argv[])
{
double r=0.0;//保存求平方根后的结果
double a=0.0;
double b=0.0;
double e=0.000001;
cout<<"该方程为:求方程exp(-x)-sin(pi/2*x)=0的根"<<endl;
cout<<"/***************************二分法的华丽分割线*************************/"<<endl;
cout<<"注意误差默认为0.000001,务必确保二分区间有根:"<<endl;
cout<<"请输入二分法区间下限:"<<endl;
cin>>a;
cout<<"请输入二分法区间上限:"<<endl;
cin>>b;
if (a<b)
r=DichotomySolu1(a,b,e);
else
r=DichotomySolu1(b,a,e);
cout<<"方程的根为:"<<r<<endl;
system("pause");
return 0;
}
double Func(double x)
{
return (exp(-x)-sin(pi*x/2));
}
double DichotomySolu1(double m,double n,double err)
{
double x=0.0;
int count=0;
while (fabs(m-n)>err)
{
x=(m+n)/2;
if (Func(m)*Func(x)<0)
n=x;
else
m=x;
count++;
}
cout<<"二分法共迭代"<<count<<"次"<<endl;
return x;
}
// ConsoleAppSimpleIterationSolu.cpp : 定义控制台应用程序的入口点。
//
/*
*函数功能:,简单迭代法求方程exp(-x)-sin(pi*x/2)=0的根
*函数原形:double SimpleIterationSolu( double error);
*参数:double error,误差要求
*返回值:方程的根
*时间复杂度:
*备注:
*日期:2014/12/21
*原创:是
*作者:EbowTang
*Email:tangyibiao520@163.com
*/
#include "stdafx.h"
#include "math.h"
#include <iostream>
using namespace std;
const double pi=3.1415926;
double SimpleIterationSolu( double );
int _tmain(int argc, _TCHAR* argv[])
{
double res=0.0;
double error=0.000001;
cout<<"简单迭代法的华丽分割线"<<endl;
char ans='n';
do
{
cout<<"请输入的误差要求";
cin>>error;
res=SimpleIterationSolu(error);
cout<<"方程的根为"<<res<<endl;
cout<<"是否继续?(y/n)";
cin>>ans;
} while (ans=='y');
return 0;
}
double SimpleIterationSolu(double err)
{
double newX=1.0;
double oldX=0.0;
int count=0;
while (fabs(newX-oldX)>err)
{
oldX=newX;
newX=oldX+(exp(-oldX)-sin(pi*oldX/2));//这只是简单迭代法的一种形式
count++;
if (count>255)
{
cout<<"请方法可能不收敛,请检查!"<<endl;
break;
}
}
cout<<"简单迭代发共迭代"<<count<<"次"<<endl;
return newX;
}
// ConsoleAppAitkenSolu.cpp : 定义控制台应用程序的入口点。
//
/*
*函数功能:,简单迭代法求方程exp(-x)-sin(pi*x/2)=0的根
*函数原形:double AitkenSolu(double error);
*参数:double error,误差要求
*返回值:方程的根
*时间复杂度:
*备注: 艾特肯加速迭代法
*日期:2014/12/21
*原创:是
*作者:EbowTang
*Email:tangyibiao520@163.com
*/
#include "stdafx.h"
#include "iostream"
using namespace std;
double AitkenSolu(double eps);
double Func(double x);
const double pi=3.1415926;
int _tmain(int argc, _TCHAR* argv[])
{
double result=0.0;
double error=0.000001;
char ans='n';
do
{
cout<<"请输入误差要求"<<endl;
cin>>error;
result = AitkenSolu(error);
cout<<"艾特肯加速迭代法的求根结果为"<<result<<endl;
cout<<"是否继续?(y/n)";
cin>>ans;
} while (ans=='y');
return 0;
}
double Func(double x)
{
return (x+exp(-x)-sin(pi*x/2));
}
double AitkenSolu(double err )
{
int count = 0;
double newX=1.0,tempX=2.0, oldX=3.0,newtempX=4.0;
while ( fabs(tempX-newtempX)>err)
{
oldX=newX;
newtempX = Func(oldX);
tempX = Func(newtempX);
newX=tempX-((tempX-newtempX)*(tempX-newtempX))/(tempX-2*newtempX+oldX);
count++;
if (count > 255)
{
cout<<"迭代超过255次,可能不收敛!\n"<<endl;
break;
}
}
cout<<"艾特肯迭代了"<<count<<"次"<<endl;
return newX;
}
恭喜艾特肯加速法获胜!!!!!!!!!!!!
牺牲运算量从而大大减少迭代次数,适合较大的规模的计算