发布时间:2024-01-08 15:00
目录
1.提出问题
1.1具体问题描述
1.2解决方案
2.分析问题
2.1基本思想
2.2基本原理
3.程序运行
3.1运行环境
3.2 程序代码
3.3 运行过程
3.4 运行结果
4.联系实际
【描述问题】
如果在考虑空气阻力的情况下,通过编程去计算投射体撞击地面的时间和飞行路程。
【输入形式】
在程序中输入三个数字,分别是
起始值、前后两次迭代差的绝对值精度、g(t)函数值的精度。
【输出形式】
第一行输出投射体撞击地面经过的时间
第二行输出投射体撞击地面前的飞行路程
注意:输出精确到小数点后10位
- 分析问题
- 采用的计算方法
- 用编程来实现
- 进行结果分析
首先,要明确的是问题中提供的方程都是非线性方程。
其次,针对非线性方程的解决办法是(二分法,迭代法,弦割法和抛物线法)。
而根据这个问题就要采用牛顿迭代法,这是因为牛顿迭代法的两个主要应用方向是
- 目标函数最优化求解。
- 进行方程的求解。
最后,牛顿迭代法的核心思想是对函数进行泰勒展开,本题也将采用这样的思想进行求解
前面已经明确使用牛顿迭代法解决问题,那么结束迭代的条件就是
- 前后两次迭代的差小于某一设定的精度
- 与渐进误差常数有关
- 与所给的函数的函数值精度有关
具体通过编程实现思路,如下:
- 先写主函数main() ,在函数体内部声明变量、精度、还有需要实现的函数功能,最后就是输出打印。
- 用两个函数g()和h()对两个方程g(t)和h(t)进行实现,其中h()就是实现投射体水平飞行路程的函数
- 再用函数g1()表示函数g(t)的求导方程
- 计算投射体水平飞行路程,用函数newton()来实现,这个也是牛顿迭代法的核心
本题程序运行将在VS2022 中进行,采用的编程语言是C++。
#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
#include
double e = 2.718281828;
using namespace std;
double g(double t)
{
return 9600 * (1 - pow(e, (-t / 15.0))) - 480 * t;
//y=g(t)=9600*(1-e^(-t/15.0)) - 480*t
}
double h(double t)
{
return 2400 * (1 - pow(e, (-t / 15.0)));
//x=h(t)=2400*(1-e^(-t/15.0))。
}
double g1(double t)
{
return 640 * pow(e, (-t / 15.0)) - 480;
//求导得 y=g1(t)=640*(e^(-p/15.0))-480
}
double newton(double p0, double delta, double epsilon)
{
double p1 = p0 - g(p0) / g1(p0);//迭代公式
double err = abs(p1 - p0);//绝对误差
double relerr = 2 * err / (abs(p1) + delta);//相对误差
p0 = p1;//赋值循环
double y = g(p0);
if (err < delta || relerr < delta || abs(y) < epsilon)
return p0;//把迭代求的的值返回
else
{
return newton(p0, delta, epsilon);//否则继续迭代
}
}
int main()
{
double p0, t;//p0是起始值,t是投射体撞击地面经过的时间
int ddelta, depsilon;//精度
cin >> p0 >> ddelta >> depsilon;
double delta, epsilon;
delta = pow(10, -ddelta);//精确度
epsilon = pow(10, -depsilon);
t = newton(p0, delta, epsilon);//求时间,牛顿法核心
double x;
x = h(t);//水平飞行距离
cout << \"投射体撞击地面时的时间:\" << fixed << setprecision(10) << t << endl;
cout << \"投射体水平飞行路程:\" << fixed << setprecision(10) << x;
return 0;
}
将程序代码写好后,在VS2022中开始执行,这里提供两个测试用例
测试用例1:【输入】7 4 6
【输出】投射体撞击地面时的时间: 9.0878996662
投射体水平飞行路程: 1090.5479598954
测试用例2:【输入】8 1 1
【输出】投射体撞击地面时的时间: 9.0895510206
投射体水平飞行路程: 1090.6921099181
由于牛顿迭代法具有局部收敛性,所以需要提一个接近于根的初始位置才可以使用,
在这个问题中,使用牛顿迭代法迭代次数更少,可以最优化解决问题。
通过编程输入起始值、前后两次迭代差的绝对值精度、g(t)函数值的精度,就可以求出飞行时间和水平路程,
这个投射体问题,就是牛顿迭代法很好实现实例。牛顿迭代法还可以用于机器学习,在工程中求一个趋势的极值、传递函数参数辨识等应用。