简介:这份 PDF 收录第八届 MathorCup 数学建模竞赛优秀论文 C3289,面向准备数学建模竞赛的学生、指导教师及对军事运筹感兴趣的学习者,讨论陆基导弹打击航母这一任务中的轨道建模与算法设计。压缩包仅含 1 个 PDF 文件,大小约 511KB,属于单篇论文型资料,查阅、引用和打印都较方便。论文把飞行过程拆为发射段、中段与末段,建立分段静态轨道模型和引入第三维坐标的动态模型,并用 MATLAB 绘制轨迹、在 Excel 与 SPSS 中生成三维散点图,还分析风速、温度、气压等误差来源及指令延迟对命中率的影响。已有 109 人学习,适合参考赛题拆解、模型假设、公式推导、软件实现与论文组织方式,也能作为微分方程、参数方程和误差分析的综合案例,对备赛论文的章节安排与图表呈现亦有借鉴意义。
1. 一条必须接得上的曲线:分段建模难在哪
第八届 MathorCup 数学建模竞赛的这份优秀论文,把一枚陆基发射的飞行器从点火到命中的整条弹道拆成发射段、中段(两个过程)、末段,逐段写受力、逐段解方程,最后拼成一条完整曲线。乍看是标准的“分而治之”,但真正卡住人的地方根本不在每段怎么解——每段都是匀变速运动,闭着眼都能写——而在接缝上:前一段结束时的位置和速度,必须是后一段的初始条件,任何一个分量对不上,整条曲线就在空中拐出一个折角。工程上要求“不能折线飞行”,数学上这叫 C¹ 连续。分段建模的难点从来不是分段,是缝合。
2. 消参的本质:把时间从方程里挤出去
分段轨迹最自然的表达形式是参数方程——横坐标、纵坐标各自写成关于时间 t 的函数,物理意义清楚,代码也好写。但论文最终交付的是一组 y=f(x) 的分段解析式。这个转换动作看着像格式整理,实际上是整篇建模里最容易翻车的一步,因为它暗含了一个前提:横坐标必须是时间的单调函数。
2.1 为什么最终要交付 y=f(x) 而不是参数方程
弹道剖面分析的提问方式是固定的:给定水平飞出去多远,此时高度是多少。这是一个“以水平距离为自变量”的查询,参数方程回答不了,必须先反解出 t。反解成立的条件是 x(t) 在每段上严格单调。回看三段:发射段水平做匀加速,x 随 t 单调增;中段水平不受力,匀速,单调;末段平抛,水平仍是匀速,单调。三段都单调,全局可逆,所以消参这条路走得通。
一旦某一段的水平速度过零甚至反向,x(t) 就会出现“折返”,同一个 x 对应两个时刻,y=f(x) 直接失去单值性,整份交付物就不成立了。这解释了一个容易被当成随手的处理:论文在描述中段开头时,把“水平速度被反向牵引力快速削减”这一过程写成“视为瞬间完成”。把这段压缩成零时长,等于把它从参数方程里删掉,从而保住了 x(t) 的单调性。常见的实现思路是在“物理真实性”和“解析可交付性”之间做取舍,这里选的是后者。
2.2 三段的解析式其实都是“消 t”消出来的
拿发射段验证一遍就能看清系数是怎么来的。竖直方向以 v₀=500 m/s 起跳,受重力减速到零,水平方向受恒定牵引力加速。写成参数方程后,从 x 反解 t 再代回 y,两个系数就自动浮出来了。
import math g = 9.8 # 重力加速度 v0 = 500.0 # 发射段竖直初速度(m/s) a = 9.96 # 牵引力产生的加速度大小(m/s^2),大小恒定、方向可变 t1 = v0 / g # 发射段结束:竖直速度降为 0 h1 = v0 * v0 / (2 * g) # 发射段上升的总高度 # 发射段参数方程:x = a*t^2/2 ,y = v0*t - g*t^2/2 # 反解 t = sqrt(2x/a) 代回,得 y = k1*sqrt(x) - k2*x k1 = v0 * math.sqrt(2.0 / a) # 根号项的系数,决定起步段的陡峭程度 k2 = g / a # 一次项的系数,等于重力与牵引加速度之比 print(f"t1={t1:.2f}s h1={h1:.1f}m k1={k1:.3f} k2={k2:.4f}") # 输出:t1=51.02s h1=12755.1m k1=224.055 k2=0.9839输出的 224.055 和 0.9839,正是论文分段式第一行的两个系数。系数之间不是独立可调的:k2 恒等于 g/a,它把“重力”和“牵引加速度”的比值固化进了曲线形状里;k1 则同时含 v₀ 和 a。这意味着后面只要改动 a,第一段的形状就会被两个系数同时改写,而不是简单地整体缩放。
末段同理,只不过约束换成了两个上限。末段只受重力做平抛,时间不超过 20 秒,末端总速度不超过 1000 m/s。两个上限都取满,下落高度和水平速度就被勾股关系绑死了。
t3, v_end = 20.0, 1000.0 h3 = 0.5 * g * t3 ** 2 # 平抛下落高度 v_h = math.sqrt(v_end ** 2 - 2 * g * h3) # 由动能定理反解末段水平速度 print(f"h3={h3:.0f}m v_h={v_h:.2f}m/s 水平射程={v_h * t3:.0f}m") # 输出:h3=1960m v_h=980.60m/s 水平射程=19612m注意这里没有任何“设计”成分:末段撤去了牵引力,没有可调参数,两个上限一取满,末段的水平速度、下落高度、水平射程就全部变成确定值。这就是整条弹道的出口条件,也是后一段落反向推算的起点。
2.3 抛物线假设:一旦算空气阻力,整套解法就崩
“发射段轨迹为抛物线”这句话不是描述,是约束。抛物线的充要条件是合力大小方向恒定、且不与初速度共线。空气阻力处处与速度反向、大小随速度变化,是一个方向时刻在转的力,一旦把它算进去,合力方向就随时间漂移,轨迹不再是抛物线,也不再有初等闭式解——只能上数值积分,逐点打表。
论文明确把阻力排除在模型之外,并且在误差分析里单独定性讨论它的影响。这个取舍值得说清楚:不是疏忽,是保交付物。整篇的核心产出是一组分段解析式,读者能代入 x 直接算高度;如果为了算阻力改成数值解,交付物就变成一堆离散点,可读性和可验证性都会掉一个档次。代价也很明确——末段以近 1000 m/s 飞 20 秒,阻力带来的落点偏差绝不可忽略,这部分被推到最后一章用误差项的方法处理,而不是塞回模型里。
3. 参数闭环:三个未知数怎么被一个边界条件锁死
分段建模最常见的写法是“每段各自定参数”,结果拼起来发现接缝处速度跳变、落点偏移几百米。这份论文的做法相反:先用出口条件把末段钉死,再用高度账本把中段钉死,最后用总射程去反解发射段的牵引加速度。整个求解顺序是倒着走的。
3.1 末段的两个硬约束先把水平速度定死
出口条件的作用被严重低估了。末段是纯平抛,不受任何可控力,是最“没有自由度”的一段。正因为没有自由度,它才适合当锚点:20 秒、1000 m/s 两个上限一取,下落高度 1960 米、水平速度 980.60 m/s、水平射程 19612 米三个量同时确定,一个都不剩。
这一步的真正价值在于它给整条弹道划了一条不可逾越的线。飞行器从发射到命中,总水平位移里已经有 19612 米被末段占死了,剩下的才轮到发射段和中段去分配。同样,总的高度落差里已经有 1960 米被末段吃掉,中段必须分担的高度也就固定了。后面所有参数的反解,都建立在“末段不可调”这个前提上。反过来说,如果哪天把末段的时间上限从 20 秒改成 15 秒,整条弹道的每一个参数都要重算,包括发射段的牵引加速度。
3.2 高度账本:10795 米是怎么来的
竖直方向是一本极干净的账。发射段上升 12755 米,末段下降 1960 米,中间的差额 10795 米必须由中段吞掉。而中段的两个过程方向相反:第一过程牵引力向下,合力是 g+a,加速下坠;第二过程牵引力向上,合力是 a−g,向上减速,把竖直速度重新压回零。
设两个过程交接处的竖直速度为 v_mid,则两段高度分别是 v_mid²/(2(a+g)) 和 v_mid²/(2(a−g)),两者之和等于 10795。一个方程、一个未知数,v_mid 被唯一确定;再由 t = v/(加速度) 分别得到两段的时长,中段总时长也就出来了。
关键在于这个方程的结构:两项的分母分别是 a+g 和 a−g,差了一个减号。这个减号会在下一节变成整个模型最脆弱的地方。水平方向则是另一本账——中段水平不受力,速度恒定,所以中段水平位移等于这个恒定速度乘以中段时长。两本账必须联立:竖直账本给出时长,水平账本给出速度,而这个速度又要和发射段末端的水平速度衔接上。如果先解竖直、再回头算水平,很可能发现接缝处速度对不上,曲线在那里断掉。这就是我把它单列成一章的原因——它不是算术问题,是求解顺序问题。
3.3 净加速度只剩零点几:一个让模型变病态的设计
牵引力加速度 a 取 9.96,重力加速度 g 取 9.8,两者相差 0.16 m/s²,只有重力的 1.6%。这意味着中段第二过程的净加速度极其微弱——飞行器在近乎“力平衡”的状态下缓慢减速。好处是这一段飞得又平又长,弹道被拉得很扁;坏处是分母 a−g 变成了一个放大器。
def mid_stage(a, g=9.8, drop=10795.0): """竖直账本:v_mid^2/2 * (1/(a+g) + 1/(a-g)) = drop""" inv = 1.0 / (a + g) + 1.0 / (a - g) # 两个过程的“阻抗”之和 v_mid = math.sqrt(2.0 * drop / inv) # 交接处的竖直速度 t_post = v_mid / (a - g) # 减速过程时长 h_dn = v_mid ** 2 / (2 * (a - g)) # 减速过程吃掉的高度 return v_mid, t_post, h_dn for a in (9.82, 9.90, 9.96, 10.00, 10.50): v_mid, t_post, h_dn = mid_stage(a) print(f"a={a:5.2f} 净加速度={a-9.8:4.2f} v_mid={v_mid:6.2f} " f"t_post={t_post:7.1f}s 该段占高度比={h_dn/10795:6.1%}")| a (m/s²) | 净加速度 a−g | v_mid (m/s) | 减速段时长 (s) | 减速段占高度比 |
|---|---|---|---|---|
| 9.82 | 0.02 | 20.77 | 1038.4 | 99.9% |
| 9.90 | 0.10 | 46.35 | 463.5 | 99.5% |
| 9.96 | 0.16 | 58.54 | 365.9 | 99.2% |
| 10.00 | 0.20 | 65.38 | 326.9 | 99.0% |
| 10.50 | 0.70 | 120.87 | 172.7 | 96.7% |
表格里最刺眼的是第一行到第三行:a 只挪动了 0.14,减速段时长就从 1038 秒掉到 366 秒,接近三倍。这不是数值误差,是结构性的——分母趋近于零时,任何扰动都会被放大到不可控。我用这份表想说明的是:a=9.96 这个看起来别扭的数字不是拍脑袋选的,它是被总射程反解出来的结果,而反解的结果恰好落在病态区边缘。
这个观察后面会反复用到。控制系统延迟 0.2 秒,在净加速度 0.16 的系统里意味着什么?意味着减速段的时间账本被整体改写,落点会沿着射程方向滑出去几百米。误差分析那一章不是补充说明,它是这个病态结构的必然产物。
4. 动目标的三维化:先算落点再发射,为什么行不通
目标会动,这件事把问题从“解一条曲线”变成了“解一条与时间赛跑的曲线”。论文试过两条路,第一条被自己否掉了,而否掉的理由比模型本身更有意思。
4.1 思路一为什么被舍弃:一个解不开的隐式方程
第一条思路很直观:既然知道目标以 32 节(换算成 16.46 m/s)向正南匀速航行,那就先假设飞行器飞 t 秒后命中,算出 t 秒后目标的位置,然后朝着那个点设计弹道。听起来闭环了,实际上是把自己绕进去了——飞行时间 t 决定了目标落点,目标落点又决定了射程,射程又反过来决定飞行时间。这是一个形如 t = F(t) 的隐式方程。
隐式方程不一定无解,用不动点迭代通常能收敛。
import math def fixpoint(L0, v_target, v_missile, iters=6): """L0: 初始水平距离;v_target: 目标速度;v_missile: 平均飞行速度""" t = L0 / v_missile # 初值:先假设目标不动 for i in range(iters): L_new = math.hypot(L0, v_target * t) # 目标跑了一段,射程变长 t_new = L_new / v_missile # 用新射程重算飞行时间 print(f"iter={i} t={t:.3f}s L={L_new:.1f}m t_next={t_new:.3f}s") t = t_new return t fixpoint(L0=378818.0, v_target=16.4622, v_missile=900.0)迭代系数是 v_target / v_missile ≈ 0.018,远小于 1,所以收敛很快,两三步就稳定了。数学上这条路是通的。论文否掉它,理由不在数学:整个弹道在发射瞬间就被完全锁死了,它默认“目标在未来几百秒内严格保持匀速直线”。目标只要中途变速一次,这条弹道就没有任何修正项可以吸收。这是典型的开环设计——它把对未来的预测当成了已知常数塞进边界条件,一旦预测失效,误差无处消化。
顺带说一个单位细节:32 节不能乘 1.852 直接当 m/s 用。1 节 = 1.852 km/h,换算成 m/s 要再除 3.6,得到 0.5144,32 节 = 16.4622 m/s。论文的水平距离表达式里出现的那个 16.4622,就是这么来的。把节当成 km/h 直接乘进去,速度会放大 3.6 倍,整条弹道全废。
4.2 坐标旋转与运动分解:把二维问题撑成三维
第二条思路换了切入点:不再预测落点,而是把目标的运动直接写进坐标里。具体做法是重建坐标系——以发射点为原点,发射点与目标初始位置的连线为 Y 轴,水平面内自 Y 轴顺时针转 90° 为 X 轴,竖直向上为 Z 轴。
这个旋转不是形式主义。目标沿正南航行,而 Y 轴指向目标初始方位,两者之间有一个夹角 θ。目标速度分解到新坐标系的 X、Y 两个分量上,就是 v·sinθ 和 v·cosθ,各自独立地进入对应坐标的参数方程。发射段的初速度同样分解:Z 方向保持原来的竖直初速度,Y 方向叠加目标方向的水平分量。
三个坐标轴的运动之所以能分开写,靠的是一条隐含前提:作用力只有牵引力和重力,且牵引力的方向可以按段取定。Z 方向只有重力和牵引力的竖直分量,Y 方向只有牵引力的水平分量,X 方向完全不受力——三套独立的匀变速运动,各自解各自的,最后用时间 t 串起来就是三维弹道。这就是运动独立性原理在这里的全部价值。
代价也在这里。一旦把空气阻力算进去,阻力方向由速度矢量决定,三个方向立刻耦合,参数方程法直接失效。第 2 章那个“抛物线假设”不是只影响二维模型,它是整个三维分解能成立的地基。
4.3 散点图能验证什么,不能验证什么
三维弹道的参数方程没法像二维那样画成一条 y=f(x) 曲线,论文的处理是在表格软件里按公式生成一系列时刻的 (x, y, z) 散点,再导入统计软件画三维散点图。这个做法在当时的环境下是合理的:不需要写绘图代码,改公式就能改图。
但散点图作为验证手段
本文还有配套的精品资源,点击获取