1. 赛题回顾与核心挑战解析
2023年的全国大学生数学建模竞赛B题,题目是“多波束测线问题”。这个题目一出来,很多同学,尤其是第一次参加国赛或者对海洋测绘、优化算法不太熟悉的队伍,第一反应可能是有点懵。它不像一些经典的预测题或者物理题那样有明确的公式可以套用,也不像一些数据分析题那样有现成的数据集可以挖掘。它的核心,是把一个非常专业的海洋工程测量问题,抽象成了一个典型的覆盖优化与非线性规划问题。
简单来说,题目描述了一个场景:我们要用搭载了多波束测深声呐的船去测量一片长方形的海域。这个声呐不是单点测量,它像一把扇子,一次能扫出一条带状区域(测线)。船沿着规划好的路径(测线)航行,声呐向两侧发射波束,就能测出这条测线左右一定宽度内的水深。我们的任务就是,设计最少的测线(让船跑最短的路),确保对整个目标海域实现全覆盖测量,并且还要满足一个关键的精度要求:相邻测线之间的重叠率不能低于一个给定值(比如10%)。
这个“重叠率”是题目的灵魂,也是最大的难点所在。它不是一个简单的几何覆盖问题。重叠率定义为相邻两条测线之间,重叠部分的面积占其中一条测线有效覆盖面积的百分比。这意味着:
- 它不是宽度比:不能简单地认为两条测线中心距小于某个值,重叠率就达标了。因为测线在边缘的覆盖宽度会变化。
- 它不对称:测线A与测线B的重叠率,和测线B与测线A的重叠率,计算结果可能不同(因为分母选取的测线不同)。题目通常指定一个计算方向。
- 它与海底坡度有关:题目会给出一个关键参数——海水深度。波束的覆盖宽度(Swath Width)是随着水深和波束开角(一个固定参数)变化的。水深越深,单次扫描覆盖的宽度越大。这直接影响了每条测线的“有效宽度”,进而影响了重叠率的计算。
所以,这道题的挑战是多维度的:它需要你理解一个物理模型(多波束测深几何),将其转化为数学模型(覆盖宽度计算函数),然后在此基础上构建一个复杂的约束优化模型(在满足全覆盖和重叠率约束下,最小化总测线长度)。这非常考验参赛者的数学建模能力、优化算法功底和编程实现能力。
2. 问题一:对称海域的“理想”优化
问题一通常设定为一个相对简单的场景:测量区域是中心对称的,比如一个矩形,并且测线方向是固定的(例如,平行于矩形长边)。海水深度设为常数。这是一个入门环节,目的是让队伍建立起基础模型。
这里的核心任务是计算在给定测线间距下,是否满足重叠率约束,并寻找满足全覆盖条件下的最小测线数量(即最小总长度)。步骤非常清晰:
- 建立覆盖宽度模型:根据给定的波束开角 θ 和水深 D,计算单侧覆盖宽度 W。公式来源于几何关系:
W = D * tan(θ/2)。那么一条测线的总覆盖宽度就是2W(中心线左右各W)。 - 建立重叠率模型:假设两条相邻测线的中心距离为 d。它们之间的重叠部分宽度为
2W - d。那么,重叠率 η = (重叠部分宽度) / (单条测线覆盖宽度) =(2W - d) / (2W) = 1 - d/(2W)。这是一个非常简洁的线性关系。 - 转化为约束条件:题目要求 η ≥ η0(例如10%)。代入公式,得到
1 - d/(2W) ≥ η0,即d ≤ 2W * (1 - η0)。 - 设计测线布局:对于长度为 L,宽度为 W_rect 的矩形区域,测线平行于长边。要完全覆盖宽度方向,需要的测线条数 N 必须满足:
(N-1) * d + 2W ≥ W_rect。这里2W是边缘效应,第一条和最后一条测线的一半宽度就能覆盖边缘。我们的目标是在满足d ≤ 2W * (1 - η0)的前提下,最小化 N(或总长度 N*L)。 - 求解:这本质上是一个一维布局问题。最优解通常是在满足重叠率约束下,取最大的允许间距 d_max =
2W * (1 - η0),然后计算所需的最少测线条数 N_min =ceil((W_rect - 2W) / d_max) + 1。总航程就是N_min * L。
注意:这里的
ceil是向上取整函数。很多同学在这里会犯错,直接用除法计算出一个非整数条数,这是不符合实际的。必须取整后验证覆盖是否完全。一个实用的技巧是:计算出 N_min 后,反推实际的间距 d_actual =(W_rect - 2W) / (N_min - 1),然后验证此 d_actual 是否仍满足d_actual ≤ d_max。通常因为向上取整,d_actual 会小于 d_max,这意味着实际重叠率比最低要求更高,这是允许的。
问题一的“坑”与心得:
- 单位统一:题目给出的角度可能是度数,计算时务必转换为弧度。
tan()函数在大多数编程语言中默认接收弧度制。 - 边缘处理:上述模型假设第一条和最后一条测线的中心线距离区域边界为 W,即其边缘波束刚好覆盖边界。这是“刚好全覆盖”的临界情况。在论文中需要清晰说明这个假设。更稳妥的做法是,认为测线覆盖范围是
[中心位置 - W, 中心位置 + W],然后确保整个区域[0, W_rect]被这些区间完全覆盖。 - 结果验证:画出示意图!用编程(如MATLAB的
plot、Python的matplotlib)画出矩形区域和所有测线的覆盖范围(用长条矩形表示)。直观检查是否有缝隙,并可以计算任意相邻测线间的实际重叠率进行数值验证。这个图能极大地增强论文的说服力。
3. 问题二:引入深度变化与坡度
问题二开始接近现实情况:海水深度不再恒定,而是沿着测线方向(或垂直测线方向)变化。通常,题目会给出一个深度变化函数,比如D(x) = 某表达式,其中 x 是沿测线方向的位置坐标。
这下复杂度直接上了一个台阶。覆盖宽度 W 不再是常数,而是随着位置 x 变化的函数W(x) = D(x) * tan(θ/2)。这意味着,同一条测线上,不同位置的覆盖宽度是不同的。那么,相邻两条测线之间的重叠率,也不再是一个简单的全局值,而是随着沿航向的位置不同而变化。
核心难点:如何定义和计算“两条测线之间的重叠率”?当宽度变化时,题目中“重叠部分面积 / 单条测线覆盖面积”的定义就需要进行积分运算。
- 离散化建模思路(推荐):这是最实用、最容易编程实现的方法。将一条测线长度 L 离散成 M 个密集的点(如每隔1米一个点)。对于每个点 x_i,计算其水深 D(x_i),进而得到该点处的覆盖半径 W(x_i)。那么,一条测线可以看作是由这 M 个点及其对应的覆盖半径所表征的集合。
- 计算重叠面积:对于相邻的两条测线,它们在这些离散点上的投影是错开的。我们需要计算,对于第一条测线上的每个点,其覆盖范围与第二条测线上对应点(相同 x 坐标)的覆盖范围,在垂直测线方向上的重叠长度。然后,将所有点上的重叠长度求和(近似于积分),再乘以离散点的间距 Δx,就得到了重叠面积的近似值。
- 计算单条测线覆盖面积:类似地,单条测线的覆盖面积可以近似为所有离散点处覆盖宽度之和乘以 Δx,即
Σ (2 * W(x_i)) * Δx。 - 建立约束:对于任意一对相邻测线,计算出的重叠率必须 ≥ η0。这形成了一个复杂的、非线性的约束条件,因为测线间距 d 会影响每个点处的重叠计算。
- 优化模型:此时,目标函数还是最小化总测线长度(或条数),但决策变量(测线间距)与约束条件之间的关系无法用简单公式表达,需要通过数值计算来评估。这通常需要使用优化算法,如非线性规划(NLP)求解器,或者更实用的启发式算法,如模拟退火(SA)、遗传算法(GA)来搜索最优的测线位置。
问题二的实战策略与心得:
- 果断采用离散化:不要试图去推导一个连续的、复杂的积分解析式。国赛时间有限,离散化方法概念清晰,易于编程实现和调试。只要离散点足够密(Δx 足够小),精度完全满足要求。
- 清晰定义数据结构:在编程时,定义好每条测线。例如,用一个数组存储测线中心线的 y 坐标(假设测线平行于x轴),再用一个函数
get_coverage_at_x(y, x)来计算位于 y 的测线在横坐标 x 处的左右边界。 - 重叠率计算函数是关键:编写一个健壮的
calculate_overlap(测线A, 测线B)函数。输入两条测线的参数,通过离散积分的方式返回重叠率。这个函数将是后续优化算法的核心评估器。 - 算法选型建议:对于这种中等规模、约束复杂的优化问题,模拟退火(SA)是非常合适的选择。它的原理是模拟固体退火过程,允许以一定概率接受“坏解”,从而有机会跳出局部最优。你可以将测线的位置序列作为“状态”,随机移动一条测线(产生新状态),计算新的总长度和所有重叠率约束,根据Metropolis准则决定是否接受新状态。
- 状态表示:用一个数组
[y1, y2, ..., yN]表示所有测线的中心位置。 - 新状态产生:随机选择一条测线,在其当前位置附近随机扰动一个值。
- 能量函数:即目标函数,总航程
N*L加上一个巨大的惩罚项。例如:E = 总长度 + PENALTY * Σ max(0, η0 - η_i),其中 η_i 是第 i 个重叠率,PENALTY 是一个很大的数(如10^6)。这样,当约束不满足时,“能量”会很高,算法会倾向于逃离这些不可行区域。
- 状态表示:用一个数组
- 可视化至关重要:画出深度变化曲线
D(x),再画出优化后的测线布局图,并用颜色深浅表示不同位置的覆盖宽度。这能直观展示你的模型如何应对深度变化。
4. 问题三:非平行测线与复杂区域
问题三通常是整个赛题的升华,可能有两种方向:一是测线方向不再固定,可以与区域边界成一定角度(即旋转测线);二是测量区域不再是简单的矩形,可能是“凹”字形或带有障碍物的区域。
方向一:旋转测线当测线可以旋转时,优化变量增加了——每条测线的角度(或者所有测线采用同一个旋转角)。这带来了两个影响:
- 区域覆盖:旋转后,为了覆盖整个矩形区域,所需的测线长度和条数会发生变化。通常,沿着区域长轴方向布置测线总长度最短,但旋转一个角度后,单条测线变长,可能需要更多条数,这是一个权衡。
- 重叠率计算:计算两条斜线之间的重叠面积变得更加复杂。因为它们的覆盖范围不再是简单的平行带状区域相交。此时,离散化方法依然有效,但计算两个倾斜矩形区域的重叠面积需要更细致的几何计算。
策略:可以将旋转角也作为优化变量。在模拟退火算法中,状态变量变为[θ, y1, y2, ...]或每条测线有自己的角度[θ1, y1, θ2, y2, ...]。新状态产生时,除了扰动测线位置,还可以以一定概率扰动旋转角。能量函数计算时,需要先根据旋转角将测线的覆盖范围投影到区域坐标系,再进行重叠判断和面积计算。计算量会增大,但思路是连贯的。
方向二:复杂区域对于凹形区域,核心难点在于判断测线的有效覆盖部分。一条测线可能只有一部分穿过目标区域,另一部分在区域外(无效)。在计算覆盖面积和重叠面积时,只考虑落在区域内的部分。
策略:
- 区域表示:用多边形顶点序列来定义复杂区域。
- 覆盖段计算:对于一条测线,计算它与区域多边形的交点。这些交点将测线分割成若干段,只有落在多边形内部的段才是有效覆盖段。
- 离散化适配:在离散积分计算覆盖和重叠面积时,只对那些位于区域内部的离散点进行计算。这需要在重叠率计算函数中增加一个“点是否在区域内”的判断。
- 优化调整:对于凹形区域,最优的测线布局可能不再是等间距的。可能需要在某些狭窄部分布置更密的测线。这更加凸显了启发式算法(如SA、GA)的优势,它们可以自动探索这种非均匀的布局。
问题三的综合心得:
- 化繁为简:无论问题多复杂,其基础仍然是问题二建立的离散化计算框架。复杂区域和旋转测线,只是在这个框架上增加了“预处理”步骤(计算有效段、坐标变换)。
- 模块化编程:一定要将代码模块化。例如:
calculate_effective_segment(测线, 区域),rotate_coordinate(点, 角度),is_point_in_polygon(点, 多边形),calculate_overlap(测线A, 测线B, 区域)。这样在应对问题三时,只需要调用这些已有的模块,并添加新的驱动逻辑即可,调试起来会清晰很多。 - 性能与精度的平衡:离散点越多,计算越精确,但程序越慢。在优化算法(如SA)中,需要成千上万次评估能量函数。一个技巧是采用自适应离散精度:在优化搜索初期,使用较粗的离散(如Δx=10米)进行快速筛选;在找到潜在最优解区域后,再用更细的离散(如Δx=1米)进行精确计算和最终验证。
- 结果分析要深入:不要只给出一个最优布局图和几个数字。分析一下为什么算法找到了这个布局?旋转角度的变化如何影响总航程?复杂区域的“瓶颈”处是如何处理的?这些分析能极大提升论文的深度。
5. 论文写作与通用技巧
数学建模竞赛,“模”是过程,“文”是呈现。一个清晰、严谨、美观的论文至关重要。
1. 摘要:重中之重摘要必须独立成篇,概括全部工作。采用“总-分-总”结构:
- 总:用一两句话说明针对什么问题,建立了什么模型,采用了什么方法,达到了什么目的。
- 分:针对问题一、二、三,分别简述你的模型核心、求解方法和主要结果(关键数值)。例如:“针对问题一,建立了基于几何关系的恒定重叠率优化模型,推导出最优测线间距公式,得到最少测线数为N,总航程为L。”
- 总:总结模型的优点(如适应性强、效率高)和特色(如创新性地采用了XX算法处理非线性约束)。最后可以提一句“为多波束测深规划提供了有效参考”。
2. 模型建立部分
- 符号说明:制作一个清晰的表格,列出所有变量、符号及其含义、单位。
- 模型假设:合理且必要。例如:“假设海水声速均匀”、“忽略潮汐影响”、“测线为直线”等。假设要服务于简化模型,但不能动摇问题根基。
- 模型推导:从物理原理(多波束几何)一步步推导到数学公式。公式要编号,重要公式可单独列出。问题一的线性推导要清晰,问题二的离散化公式要给出求和表达式。
3. 模型求解与结果分析
- 算法描述:如果你用了模拟退火或遗传算法,不要只写名字。用流程图或文字描述清楚算法的步骤:初始化温度、产生新解、接受准则、降温策略、终止条件。给出关键参数的选择依据(如初始温度、降温系数为什么取0.95)。
- 结果展示:图表结合。问题一的结果可以配公式和简单表格。问题二、三必须有示意图。示意图要精美,有图例、坐标轴标签。例如:一张图上同时显示海底地形起伏(用曲线或颜色)和多条测线的覆盖范围(用半透明色块表示),重叠部分颜色加深。这样评委一目了然。
- 灵敏度分析:这是拿高分的关键。分析某个参数变化对结果的影响。例如:改变最低重叠率要求η0(从10%到20%),观察总航程如何变化;或者改变海水深度的变化幅度。这能体现你对模型的理解深度。
- 模型检验:用另一种方法验证你的结果。例如,对于问题二,你可以用非常密集的测线(远多于最优解)计算一个“理论上界”,然后对比你的优化结果,看节省了多少航程。或者,对离散化精度进行测试,说明当Δx小于某个值后,结果已稳定。
4. 编程实现与团队协作
- 语言选择:MATLAB在矩阵运算和绘图上很方便,Python(NumPy, SciPy, Matplotlib)更通用,资源更多。选择团队最熟悉的。
- 分工明确:一人主攻模型推导和论文写作,一人主攻算法编程实现,一人负责数据验证、绘图和辅助建模。但核心模型需要三人共同理解。
- 版本管理:即使不用Git,也要定期将代码、论文、数据打包,按时间戳命名(如
2023B_final_v1.zip),避免最后时刻误覆盖。 - 留足时间写论文:最后一天一定要留出至少6-8小时专门进行论文的整合、润色、排版和检查。慌慌张张赶出来的论文往往漏洞百出。
2023年国赛B题是一道非常经典的优化类赛题,它完美地体现了数学建模竞赛的精髓:将复杂的实际问题抽象为清晰的数学模型,并利用计算工具进行求解。它考察的不仅仅是数学知识,更是问题分解、算法设计、编程实现和科学写作的综合能力。对于参赛者来说,无论获奖与否,深入经历这样一次从“茫然”到“清晰”再到“解决”的全过程,本身就是一次极有价值的锻炼。