简介:本资源是全国大学生数学建模竞赛B题一等奖获奖方案,面向数学建模初学者、参赛学生及海洋探测相关领域研究者,聚焦多波束测线布局优化这一典型工程建模问题——在保障海底地形全覆盖前提下,最小化测线重叠率以提升探测效率与数据质量。压缩包共13个文件(1.16MB),含5个核心Python脚本(实现模拟退火求解、覆盖计算与可视化)、2个MATLAB程序(用于地形建模与图形输出)、2张关键结果图(抽象模型与优化效果对比)、1份Word说明文档、1份Markdown结构说明、1份PDF问题分析及1份TXT补充说明,代码模块清晰、注释完整,覆盖建模推导、算法实现、结果验证全流程。已有79人学习下载,提供从赛题理解、变量定义、约束构建到SA参数调优的完整技术路径,特别适合复现优化逻辑、拓展至其他区域覆盖类问题(如无人机航测、卫星遥感路径规划)的学习与二次开发。
1. 项目概述:从一道赛题到一套完整的解决方案
去年带队参加全国大学生数学建模竞赛,我们组抽到了那道关于多波束测线技术的B题。题目背景很明确:给你一艘科考船,船底装了个多波束声呐,这玩意儿能像一把扇子一样向海底发射声波,一次能扫出一条带状区域。我们的任务,就是规划这艘船的航行路线,让它在有限的区域内,用最少的“扫帚”(测线)把海底地形扫得又全又好,还不能扫太多重复的地方。说白了,就是要在保证全覆盖的前提下,最大化单次扫描的覆盖宽度,同时最小化不同测线之间的重叠区域。这听起来像个工程优化问题,但内核是纯粹的数学建模与算法博弈。
我们最终拿了一等奖,靠的不是灵光一现,而是一套从问题抽象、模型建立到算法求解的完整“组合拳”。这个“基于多波束测线技术的海洋地形探测与优化建模系统”,就是我们交出的答卷。它的核心价值在于,将复杂的海洋测绘工程问题,转化为了一个可计算、可优化的数学模型,并利用智能优化算法(我们用的是模拟退火算法)找到了高质量的近似最优解。这对于资源有限的海洋调查(船时、燃油都极其昂贵)具有直接的现实意义。无论你是正在备战数模竞赛的学生,还是对路径规划、优化算法感兴趣的研究者,或是相关领域的工程师,这套从实际问题到代码落地的完整思路,都值得你花时间深入了解。
2. 核心问题拆解:把海洋测绘翻译成数学语言
面对赛题,第一步也是最关键的一步,就是如何把一段充满工程术语的描述,精准地翻译成数学公式和约束条件。这决定了你模型的天花板。
2.1 多波束测线的几何模型构建
多波束声呐的工作原理,决定了它的覆盖范围不是一个简单的矩形。它是一个与海底地形、海水声速剖面、波束开角等多个因素相关的复杂曲面。但在初版模型中,为了抓住主要矛盾,我们进行了合理的简化:假设海底是平坦的,且海水声速均匀。此时,单次测线在海床上的投影,近似一个以船底换能器为顶点的等腰梯形(严格说是对称的扇形条带)。
这里有几个关键参数需要从题目中提取或定义:
- 测线间距 (D):两条相邻测线中心线之间的垂直距离。这是我们的核心决策变量,我们优化的目标就是找到最优的D值。
- 覆盖宽度 (W):单条测线在海床上能扫到的实际宽度。它与水深(H)、波束开角(θ)有关,简化公式为
W = 2 * H * tan(θ/2)。水深越深,覆盖越宽。 - 重叠率 (η):相邻测线扫掠区域的重叠部分宽度与单条测线覆盖宽度的比值。这是我们需要最小化的目标之一。重叠率太高,意味着效率低下,做了无用功;重叠率为零或负值(即出现漏测缝隙),则是任务失败。
注意:在实际高端模型中,W并非常数。由于波束在传播中的扩展和海底地形起伏,边缘波束的入射角变大,导致其覆盖的海底点位置精度下降。因此,有效的“全覆盖”通常要求相邻测线有必要的重叠(例如10%-20%),以确保所有区域都被至少一个中心波束(精度最高)覆盖到。赛题中“最小化重叠率”是在保证全覆盖约束下的最小化,这个约束条件必须明确。
2.2 优化目标的数学定义
题目要求“覆盖范围最大化”和“重叠率最小化”,这是一个典型的多目标优化问题。直接处理两个目标比较麻烦,常见的处理方法是将其转化为单目标问题。
我们的思路是:在保证全覆盖(无缝隙)这一硬性约束下,最小化总的重叠面积。因为对于固定测区,测线数量越少,总航程越短,效率自然越高。而测线数量直接由测线间距D决定。D越大,需要的测线越少,但重叠率可能降低到出现漏测;D越小,测线越多,重叠率越高。
因此,我们构建了如下数学模型:
- 决策变量:测线间距
D。 - 约束条件:
D ≤ W(确保相邻测线间无缝隙,即重叠率 η >= 0)。更严格的约束可能是D ≤ W * (1 - 最低要求重叠率)。 - 目标函数:最小化总重叠面积,或等价地,最小化所有相邻测线重叠率的总和。由于测区规则(如矩形),总重叠面积可以表示为关于D的函数:
Total_Overlap = N * [W - D] * L,其中N是测线数量(也是D的函数),L是单条测线长度。我们的目标就是寻找一个D,在满足约束的前提下,使Total_Overlap最小。
通过这种方式,我们将“多目标”巧妙地转化为了在约束条件下对单一目标函数的优化。模型建立后,接下来的挑战就是如何求解这个最优的D。
3. 算法选型:为什么是模拟退火?
问题转化为寻找一个最优的数值解,我们面临多种算法选择:穷举法、梯度下降、遗传算法、粒子群算法,以及我们最终采用的模拟退火算法。每种算法都有其适用场景。
- 穷举法:如果D的可能取值很少,这最直接。但D是连续变量,离散化后如果精度要求高,搜索空间巨大,计算不可行。
- 梯度下降法:需要目标函数连续可导。我们的目标函数中,测线数量N是D的阶跃函数(例如,
N = ceil(区域宽度 / D)),导致函数不光滑,存在断点,梯度信息不好用。 - 遗传算法/粒子群算法:这类群体智能算法适合多峰、非线性问题,但参数(种群大小、交叉变异概率)调优需要经验,且收敛速度有时不稳定。
我们选择模拟退火算法,是基于以下几个关键考量:
- 应对非凸性:我们的目标函数很可能不是光滑的凸函数,而是存在多个局部最优解。模拟退火源于固体退火过程的物理原理,其核心在于以一定的概率接受“劣质解”,从而使算法有能力跳出局部最优的“陷阱”,向着全局最优区域搜索。
- 简单易实现:SA的算法框架相对清晰,核心步骤就是“产生新解 -> 计算目标差 -> Metropolis准则判断接受与否 -> 降温”。我们可以在短时间内编码实现并调试。
- 灵活可控:通过调整初始温度、降温速率、马尔可夫链长度等参数,可以平衡算法的“勘探”(全局搜索)和“开采”(局部精细搜索)能力。这对于在有限的竞赛时间内取得一个“满意解”至关重要。
- 与问题适配:我们的决策变量D是单变量连续优化,SA处理起来非常高效。新解的产生可以通过在当前解附近施加一个随机扰动来实现,例如
D_new = D_current + random.uniform(-step, step),并控制D_new在合理区间内。
实操心得:在数模竞赛中,算法选型不必追求最新最复杂,关键是“合适”和“可控”。模拟退火算法原理易于在论文中阐述,过程便于可视化(如绘制能量随迭代下降的曲线),这能让评委清楚地看到你的求解思路和收敛过程,是加分项。相比之下,一些黑箱化严重的深度学习模型反而可能因为解释性不足而丢分。
4. 系统实现与核心代码解析
我们的系统主要使用Python实现,因其科学计算库丰富(NumPy, SciPy),绘图方便(Matplotlib),且代码简洁。整个系统流程可分为:参数初始化、目标函数定义、模拟退火主循环、结果可视化。
4.1 环境准备与参数定义
import numpy as np import matplotlib.pyplot as plt import random import math # ========== 问题参数(根据赛题具体数据设定)========== area_width = 1000 # 测区宽度 (米) area_length = 2000 # 测区长度 (米) H = 100 # 平均水深 (米) theta = np.deg2rad(120) # 波束开角,120度转换为弧度 # 计算覆盖宽度 W = 2 * H * math.tan(theta / 2) # 单条测线覆盖宽度 # ========== 模拟退火算法参数 ========== T_init = 1000 # 初始温度 T_min = 1e-3 # 终止温度 alpha = 0.95 # 降温系数 (0.9 ~ 0.99之间) Lk = 100 # 每个温度下的迭代次数(马尔可夫链长度)4.2 目标函数与约束处理
这是模型的核心,需要准确计算给定测线间距D下的总重叠面积。
def calculate_total_overlap(D, W, area_width, area_length): """ 计算给定测线间距D下的总重叠面积。 参数: D: 测线间距 W: 单条测线覆盖宽度 area_width: 测区宽度(垂直于测线方向) area_length: 测区长度(沿测线方向) 返回: total_overlap: 总重叠面积 num_lines: 需要的测线数量 is_valid: 解是否有效(是否全覆盖) """ if D <= 0 or D > W: # 基本约束:间距必须为正且不能大于覆盖宽度(否则必有缝隙) return float('inf'), 0, False # 计算需要的测线数量(向上取整,确保覆盖整个宽度) num_lines = math.ceil(area_width / D) # 计算实际使用的总宽度(可能略大于测区宽度) total_width_used = (num_lines - 1) * D + W # 计算单条测线的重叠宽度(相邻测线间的重叠部分) overlap_width_per_pair = W - D if overlap_width_per_pair < 0: # 如果出现缝隙,返回无穷大代价 return float('inf'), num_lines, False # 总共有 (num_lines - 1) 个重叠区域 # 每个重叠区域的面积 = 重叠宽度 * 测线长度(即area_length) total_overlap = (num_lines - 1) * overlap_width_per_pair * area_length # 有效性检查:实际使用宽度必须能覆盖测区宽度,且不能有缝隙 if total_width_used < area_width or overlap_width_per_pair < 0: is_valid = False # 对于无效解,可以给予一个惩罚项,这里直接返回无穷大 total_overlap = float('inf') else: is_valid = True return total_overlap, num_lines, is_valid def objective_function(D, W, area_width, area_length, penalty=1e6): """ 模拟退火使用的目标函数。我们希望最小化总重叠面积。 对无效解施加一个巨大的惩罚值。 """ total_overlap, _, is_valid = calculate_total_overlap(D, W, area_width, area_length) if not is_valid: return total_overlap + penalty # 无效解惩罚 return total_overlap4.3 模拟退火算法主循环实现
这是算法的引擎,控制着解的迭代和更新。
def simulated_annealing(T_init, T_min, alpha, Lk, W, area_width, area_length): """ 模拟退火算法主函数。 """ # 1. 初始化 current_D = W * 0.7 # 初始解:设为覆盖宽度的70%,一个合理的起点 current_energy = objective_function(current_D, W, area_width, area_length) best_D = current_D best_energy = current_energy T = T_init history_energy = [current_energy] history_D = [current_D] history_T = [T] # 2. 外循环:温度下降 while T > T_min: for i in range(Lk): # 3. 内循环:每个温度下迭代 # 产生新解:在当前解附近随机扰动 # 扰动步长可以随温度降低而减小,增强后期局部搜索 step_size = 0.1 * W * (T / T_init) new_D = current_D + random.uniform(-step_size, step_size) # 边界处理:确保D在(0, W]之间 new_D = max(1e-3, min(W, new_D)) new_energy = objective_function(new_D, W, area_width, area_length) # 计算能量差 delta_E = new_energy - current_energy # Metropolis准则:决定是否接受新解 if delta_E < 0: # 新解更优,接受 accept = True else: # 新解更差,以一定概率接受 p = math.exp(-delta_E / T) if random.random() < p: accept = True else: accept = False if accept: current_D = new_D current_energy = new_energy # 更新历史最优解 if current_energy < best_energy: best_D = current_D best_energy = current_energy # 保存当前温度下的信息用于绘图 history_energy.append(current_energy) history_D.append(current_D) history_T.append(T) # 降温 T = T * alpha # 计算最优解对应的其他信息 final_overlap, final_num_lines, is_valid = calculate_total_overlap(best_D, W, area_width, area_length) avg_overlap_ratio = (W - best_D) / W if is_valid else None return best_D, best_energy, final_num_lines, avg_overlap_ratio, history_energy, history_D, history_T4.4 结果可视化与方案输出
算法跑完后,用图表说话,能让你的论文和报告增色不少。
# 运行算法 best_D, best_energy, num_lines, avg_overlap, energy_hist, D_hist, T_hist = simulated_annealing( T_init, T_min, alpha, Lk, W, area_width, area_length ) print("="*50) print("模拟退火优化结果") print("="*50) print(f"最优测线间距 D* = {best_D:.2f} 米") print(f"单条测线覆盖宽度 W = {W:.2f} 米") print(f"所需测线数量 = {num_lines} 条") print(f"平均重叠率 = {avg_overlap:.2%}") print(f"总重叠面积(目标函数值)= {best_energy:.2f} 平方米") print("="*50) # 绘制优化过程曲线 fig, axes = plt.subplots(2, 2, figsize=(14, 10)) # 1. 能量(总重叠面积)随迭代下降曲线 ax1 = axes[0, 0] ax1.plot(energy_hist, 'b-', linewidth=0.8) ax1.set_xlabel('迭代次数') ax1.set_ylabel('总重叠面积 (m²)') ax1.set_title('目标函数值(总重叠面积)优化过程') ax1.grid(True, linestyle='--', alpha=0.5) ax1.axhline(y=best_energy, color='r', linestyle='--', alpha=0.7, label=f'最优值: {best_energy:.1f}') ax1.legend() # 2. 决策变量(测线间距D)搜索轨迹 ax2 = axes[0, 1] ax2.plot(D_hist, 'g-', linewidth=0.8) ax2.set_xlabel('迭代次数') ax2.set_ylabel('测线间距 D (米)') ax2.set_title('决策变量(测线间距)搜索轨迹') ax2.grid(True, linestyle='--', alpha=0.5) ax2.axhline(y=best_D, color='r', linestyle='--', alpha=0.7, label=f'最优D: {best_D:.2f}') ax2.legend() # 3. 温度下降曲线 ax3 = axes[1, 0] ax3.plot(T_hist, 'm-', linewidth=1.5) ax3.set_xlabel('外循环迭代次数') ax3.set_ylabel('温度 T') ax3.set_title('模拟退火温度下降曲线') ax3.set_yscale('log') # 温度通常指数下降,用对数坐标更直观 ax3.grid(True, linestyle='--', alpha=0.5) # 4. 最优测线布置示意图 ax4 = axes[1, 1] # 绘制测区边界 rect = plt.Rectangle((0, 0), area_length, area_width, linewidth=2, edgecolor='k', facecolor='none') ax4.add_patch(rect) ax4.set_xlim(-100, area_length+100) ax4.set_ylim(-100, area_width+100) ax4.set_xlabel('沿航向距离 (米)') ax4.set_ylabel('垂直航向距离 (米)') ax4.set_title(f'最优测线布置示意图 (D={best_D:.1f}m, N={num_lines})') ax4.set_aspect('equal') # 绘制每条测线的覆盖范围(简化为矩形条带) for i in range(num_lines): y_center = i * best_D # 条带下边界和上边界 y_bottom = y_center - W/2 y_top = y_center + W/2 # 绘制覆盖条带,用半透明表示重叠 rect_line = plt.Rectangle((0, y_bottom), area_length, W, linewidth=0.5, edgecolor='blue', alpha=0.3, facecolor='lightblue') ax4.add_patch(rect_line) # 绘制测线中心线 ax4.axhline(y=y_center, color='red', linestyle='-', linewidth=1, alpha=0.7) ax4.grid(True, linestyle=':', alpha=0.3) plt.tight_layout() plt.show() # 输出详细的航次计划表(示例) print("\n详细航次计划(从测区一侧开始):") for i in range(num_lines): y_center = i * best_D print(f"测线 {i+1:2d}: 中心线位置 y = {y_center:7.2f} m, 覆盖范围 y ∈ [{y_center - W/2:7.2f}, {y_center + W/2:7.2f}] m")5. 参数调优与算法改进实战
模拟退火算法性能高度依赖于参数设置。在竞赛中,我们花了大量时间进行参数调优和算法改进。
5.1 关键参数的影响与调优策略
初始温度
T_init:- 作用:决定算法初期接受劣质解的概率。温度越高,接受差解的概率越大,全局搜索能力越强。
- 调优:设置过低会陷入局部最优;过高则前期搜索过于随机,收敛慢。我们采用了一种自适应方法:先进行若干次随机搜索,计算目标函数值的标准差σ,然后令
T_init = k * σ,其中k是一个系数(通常取10-100)。这样初始温度能与问题的规模相关联。
降温系数
alpha:- 作用:控制温度下降的速度。alpha越接近1,降温越慢,在每个温度下搜索越充分,但耗时增加。
- 调优:通常在0.9到0.99之间。我们采用了可变降温系数:在高温阶段用较小的alpha(如0.85)快速降温,锁定有希望的区域;在低温阶段用较大的alpha(如0.98)缓慢降温,进行精细搜索。
马尔可夫链长度
Lk:- 作用:每个温度下产生新解的次数。应保证在该温度下系统能达到“热平衡”。
- 调优:固定值可能低效。我们将其与解空间的大小挂钩,例如
Lk = int(100 * (当前温度 / 初始温度)),温度高时多搜索,温度低时少搜索。
新解产生机制:
- 基础:
D_new = D_current + random.uniform(-step, step)。 - 改进:
step不应是固定的。我们让step = step_max * (T / T_init),即步长随温度降低而线性减小,符合“先粗后细”的搜索逻辑。step_max可以设为W * 0.2。
- 基础:
5.2 算法增强技巧:记忆性与重启机制
基础的SA算法在迭代中只保留当前解和最优解,可能会“遗忘”曾经路过的好区域。我们引入了两个改进:
- 记忆最优解:这已经是标准操作,任何时候发现更好的解都保存下来。
- 重启机制:当连续若干个温度下最优解都没有更新时,算法可能停滞在某个平台。此时,我们不是直接结束,而是以当前最优解为起点,将温度重置到一个中等水平(如
T = T_init * 0.3),重新开始退火过程。这相当于给算法一次“二次冲刺”的机会,往往能帮助其跳出僵局。
# 在模拟退火主循环中加入重启机制的伪代码片段 no_improve_streak = 0 no_improve_threshold = 5 # 连续5个温度无改进则触发重启 restart_T_factor = 0.3 # 重启温度设为初始温度的30% while T > T_min: # ... 内循环迭代 ... if current_energy < best_energy: best_energy = current_energy best_D = current_D no_improve_streak = 0 # 有改进,重置计数器 else: no_improve_streak += 1 # 检查是否触发重启 if no_improve_streak >= no_improve_threshold: print(f"在温度{T:.2f}触发重启机制") # 以当前最优解为起点,重置温度 current_D = best_D current_energy = best_energy T = T_init * restart_T_factor no_improve_streak = 0 continue # 跳过本次降温,用新温度开始下一轮 # ... 降温 ...6. 从模型到论文:数模竞赛的呈现要点
解决了问题,还要把解决方案清晰、有说服力地呈现出来。这是数模竞赛拿高分的关键。
6.1 模型假设的明确与合理性论证
论文中必须清晰列出所有模型假设,并说明其合理性。例如:
- 假设1:海底地形平坦,海水声速均匀。合理性:在初步规划阶段,忽略小尺度起伏和声速剖面变化,可简化模型,抓住主要矛盾。对于大范围地形趋势探测,该假设可接受。
- 假设2:测线为直线,且平行布置。合理性:这是最常规、最易实施的航测模式,符合工程实际。
- 假设3:波束边缘覆盖即视为有效覆盖。合理性:本模型聚焦于“几何全覆盖”,后续可讨论在精度要求下需增加必要重叠率作为模型改进。
6.2 灵敏度分析与模型稳健性检验
评委喜欢看到你对模型“边界”的思考。我们需要进行灵敏度分析,回答“如果某个参数变了,结果会怎样?”。
- 水深变化:如果水深H在区域内变化(如从80米到120米),我们的最优间距D是否依然有效?我们可以绘制
最优D随H变化的曲线,或者给出一个适应性的D调整公式(如D_opt = k * H,k为系数)。 - 测区形状:如果不是规则的矩形,而是多边形,模型如何调整?可以提出将测区进行网格化或三角剖分,然后对每个子区域应用本模型,再考虑边界衔接的思路。
- 算法参数:展示不同初始温度、降温系数对最终优化结果的影响,证明我们的参数选择是鲁棒的,结果不是偶然得到的。
6.3 可视化与结果表达
一图胜千言。除了代码中给出的优化过程图和测线布置图,还可以增加:
- 重叠率分布图:用热力图显示测区内不同位置的重叠次数,直观展示覆盖的均匀性。
- 收敛性对比图:将模拟退火与简单贪心算法、随机搜索的收敛曲线放在一起对比,突出SA的优越性。
- 三维效果图:如果时间允许,可以绘制海底地形(假设有)与测线覆盖范围的三维关系图,增强表现力。
7. 常见问题与避坑指南
在实际编程和建模过程中,我们踩过不少坑,这里总结出来,希望能帮你节省时间。
7.1 算法收敛性问题
- 问题:算法很快收敛到一个明显很差的解,或者能量曲线一直上下跳动不下降。
- 排查:
- 初始温度太低:导致一开始就无法跳出局部最优。尝试大幅提高
T_init,观察初期是否接受了一些劣质解。 - 降温太快:
alpha太小,系统还没达到平衡就迅速冷却。尝试将alpha提高到0.99以上。 - 马尔可夫链太短:每个温度下还没搜索充分就降温了。增加
Lk。 - 新解产生步长不合理:
step太大导致解乱跳,太小则搜索范围有限。尝试动态调整步长,并与问题尺度(如W)关联。
- 初始温度太低:导致一开始就无法跳出局部最优。尝试大幅提高
- 技巧:始终绘制能量变化曲线和温度曲线。健康的曲线应该是:初期能量剧烈波动且值较高,中期波动减小并呈下降趋势,后期在最优值附近轻微波动。
7.2 模型与代码的脱节
- 问题:论文里描述的模型很完美,但代码实现是另一回事,结果对不上。
- 避坑:
- 单元测试:对关键函数如
calculate_total_overlap,用几个简单的手算案例进行验证。例如,当D = W时,重叠面积应为0;当D = W/2时,计算是否正确。 - 打印中间变量:在算法迭代中,定期打印
current_D,current_energy,new_D,new_energy,delta_E,accept_prob等,观察算法决策过程是否符合预期。 - 可视化中间状态:对于复杂的二维布置问题,可以在每次找到更优解时,简单绘制一下当前的测线布置图,直观检查是否合理。
- 单元测试:对关键函数如
7.3 结果的可解释性与现实意义
- 问题:算出一个最优间距D=75.3米,然后就结束了。这不够。
- 提升:
- 取整与操作化:实际航行中,船长不可能精确控制75.3米。你需要将结果操作化。例如,建议采用75米或76米的整数间距,并重新计算该间距下的重叠率和所需测线数,评估这个“近似最优解”的效能损失。
- 给出完整方案:输出不应该只是一个数字,而应该是一个完整的航次计划表,包括每条测线的起始点坐标、航向、长度,以及预计的作业时间(结合船速)。
- 讨论局限性:主动指出模型的不足(如忽略海流、风向、转弯耗时),并提出未来改进方向(如结合旅行商问题优化测线顺序),这体现了思维的严谨和深度。
7.4 性能优化
- 问题:当测区很大,需要模拟的测线数量很多时,目标函数计算可能成为瓶颈。
- 优化:
- 向量化计算:如果使用Python,尽量用NumPy的数组运算代替循环。
- 缓存结果:如果目标函数计算非常耗时,可以考虑对计算过的
(D, 参数)进行缓存(如使用字典),避免重复计算。 - 简化模型:在SA迭代的早期,温度高,接受差解概率大,可以用一个快速但粗略的模型计算目标函数(如用更粗的网格估算面积);在低温精细搜索阶段,再切换回精确模型。但这需要仔细设计,确保一致性。
最后想说的是,这道B题是一个经典的“建模-算法-实现-分析”闭环训练。模拟退火算法在这里是一个出色的工具,但更重要的是你如何定义问题、构建模型、解释结果。真正让你在竞赛中脱颖而出的,不是代码跑得多快,而是你对问题本质的理解深度和将复杂现实世界抽象为简洁数学模型的能力。我们这套方案,从假设到验证,从算法到调优,从代码到论文,提供了一个完整的范式,你可以把它看作一个模板,应用到其他具有类似结构的优化问题中去,比如无线传感器网络部署、无人机植保路径规划、仓库货架扫描路线设计等等。关键在于抓住“覆盖”与“效率”这对核心矛盾,并用数学的语言将其清晰地表达出来。
本文还有配套的精品资源,点击获取