1、
设计性实验报告
课程名称: 最优化 实验名称: 牛顿法
实验地点: 指导老师:
实验时间:
提交时间: 班级:
姓 名: 座号:
一、实验目的和要求
[1] 掌握非线性方程的极小点基本求解算法;
[2] 通过实例掌握用MATLAB或C语言求非线性方程的极小点方法;
[3] 编程实现2种或以上算法并进行比较掌握牛顿法原理,并能够用
程序实现
二、实验环境、内容和方法
1.写出非线性方程的极小点基本求解算法的程序框架
2、2.用C语言或matlab编写实现所设计算法
3. 构造一个非线性方程,用所设计的程序实现,比较各个算法的迭代速度,求解的精度,运行的时间。另改变初值,分析初值对解的影响。
4. 可采用二分法,Newton迭代,黄金分割法。
编制程序,用牛顿迭代法、二分法、黄金分割法三种不同的方法求解函数 的最优解。 求解区间为 [-8,8]
解法一:二分法
在C++ 软件中输入如下程序:
#include
using namespace std;
double f(double x
3、)
{
return x*x*x*x-4*x*x*x-6*x*x-16*x+4;
};
int main()
{
double left=-8;
double right=8;
double mid;
while((right-left)>0.005)
{
mid=(left+right)/2;
if(f(mid)==0)
break;
if((f(mid)*f(left))>0)
left=mid;
else
right=mid;
};
cout<4、e");
return 0;
}
运行程序的结果为:
我们知道,在极小点处,并且当时,函数时递减的,即;而当时,函数递增,即。如果找到一个区间,具有性质,,则在之间必有的极小点,并且。
为了找到,我们取,若,则在区间中有极小点。这时以作为新的区间;若,则在中有极小点,因此以作为新的区间。继续这个过程,逐步将区间换小,当区间充分小时,即可取到极小点的近似。
解法二:牛顿迭代法
在C++ 软件中输入如下程序:
#include
#include
#define eps 0.01
doub
5、le fun(double x)
{
return x*x*x*x-4*x*x*x-6*x*x-16*x+4;
}
double diff_fun(double x)
{
return 4*x*x*x-12*x*x-12*x-16;
}
double diff_2_fun(double x)
{
return 12*x*x-24*x-12;
}
double diff_3_fun(double x)
{
return 24*x-24;
}
double newton(double a,dou
6、ble b)
{
double result = (a+b)/2;
double t = 0.0;
while(true)
{
t = result - (diff_fun(result)/diff_2_fun(result));
if(fabs((t-result)) < eps)
{
return result;
}
else
{
r
7、esult =t;
}
}
}
int main()
{
double a =0.0;
double b =6.0;
double x= newton(a,b);
cout<<"求解的结果是 x = "<8、入不同的初值,在不同的迭代次数得到方程的解是不一样的。由于牛顿法是一种函数逼近法,它的基本思想是,在迭代点附近用二阶泰勒多项式近似目标函数,进而求出极小点的估计值。在一定条件下,这个点列收敛于最优解且具有二阶收敛速度。
运用牛顿法时,初值点的选择显得十分重要。如果初始点靠近极小点,则收敛可能很快;如果收敛点原理极小点,则迭代产生的点列还有可能不收敛于极小点。
解法三:黄金分割法
在C++软件中输入如下程序:
#include
#include
double f(double x);//函数声明
//主函数
void main
9、)
{
double a=-8,b=8,e=0.01;
double x1=0,x2=0,x3=0,f1=0,f2=0,f3=0;
x1=a+0.382*(b-a);
x2=a+0.618*(b-a);
f1=f(x1); //调用f函数
f2=f(x2); //调用f函数
//在没有达到误差限情况下就循环
while(fabs(a-b)>=e)
{
if(fabs(f1-0)10、x1*x1-4*x1*x1*x1-6*x1*x1-16*x1+4;
}
else
{
a=x1;
x1=x2;
f1=f2;
x2=a+0.618*(b-a);
f2=x2*x2*x2*x2-4*x2*x2*x2-6*x2*x2-16*x2+4;
}
x3=(a+b)/2;
f3=f(x3);
}
cout<<"方程为:"<<"f(x)=x*x*x*x-4*x*x*x-6*x*x-16*x+4"<11、限为:e=0.01"<