简介面向无线传感器网络WSN教研与仿真入门者这份资料基于Matlab 2021a完成Leach与HEED协议的对比实现重点考察能耗、存活节点数、网络吞吐量等指标本科、硕博阶段课程设计或课题预研均适用。压缩包共7个文件包括6个可运行的m脚本和1个avi操作录像脚本负责参数配置、协议调度与结果曲线输出录像演示从运行主程序到生成仿真图表的完整流程方便对照复现。包体约6.17MB轻量紧凑已有240人浏览学习。借助源码与录屏读者可逐行理解两种分簇路由协议的算法差异每个脚本均包含关键注释便于逐段调试录像还展示常见报错与参数修改位置能帮助初学者快速定位问题。在此基础上读者也能自行调整节点数量、轮次、通信半径等参数观察不同场景下的性能变化为后续改进或论文实验提供基础从原理到复现形成完整闭环。1. 无线传感器网络里 LEACH 和 HEED 之争本质是能耗效率与网络稳定性的取舍做无线传感器网络WSN路由协议选型时LEACH 和 HEED 是两个绕不开的分簇协议。LEACH 靠随机轮转把簇头角色轮流派给节点追求能耗在节点间的均摊HEED 则用剩余能量和簇内通信成本两个指标筛选簇头追求每轮簇头质量的可控性。两者都能延长网络寿命但延长路径完全不同。实际仿真对比中很多开发者跑完看到 HEED 每轮能耗更高就判定它更差但真正的差异往往来自参数没对齐、能量模型设置不一致甚至随机种子不同。这篇文章把协议机制、NS-2 仿真配置、统计指标口径和仿真录像制作串成一条完整链路适合正在做 WSN 课程设计、毕业设计或协议选型验证的开发者对照复现。2. 先吃透协议再动手LEACH 的随机轮转与 HEED 的双重选簇逻辑2.1 LEACH 的分布式簇头选举公式阈值与轮转如何决定能耗分布LEACH 的设计哲学很朴素簇头要承担数据融合、转发和调度能耗必然高于普通节点那就让所有节点轮流当簇头把能量消耗平均化。每一轮开始时节点各自独立计算是否当选不依赖中心控制。判断依据是下面这个阈值公式# LEACH 簇头选举阈值计算协议理解用仿真内以下方 TCL 脚本为准 def leach_threshold(p, r, in_G): 参数: p: 预期的簇头节点比例通常取 0.05 r: 当前轮数从 0 开始 in_G: 当前节点是否属于最近 1/p 轮内未当选过簇头的集合 返回: 本轮阈值节点生成 [0,1) 随机数小于阈值则当选 if not in_G: return 0.0 return p / (1 - p * (r % int(1 / p)))每个节点生成一个 [0,1) 的随机数小于阈值就当簇头。这里的核心是int(1/p)这个取模周期当 p0.05 时周期是 20 轮表示每 20 轮里每个节点理论上至少有一次当选机会。这保证了能耗的长期均匀但也带来两个问题。第一个问题是簇头数量的随机波动。虽然期望值是 5%但具体某一轮可能一个簇头都没有也可能多个簇头挤在同一个区域让局部节点的传输路径变得很绕。第二个问题是 LEACH 默认节点同构、能量一致一旦网络里有能量偏低的节点随机轮转并不会绕开它反而可能让低能量节点当上簇头提前死亡。仿真里调 p 的影响非常直接。p 调大簇头变多控制开销变大单轮能耗升高p 调小非簇头节点要传更远信道竞争加剧。经验值一般取 0.05 到 0.1超过 0.1 后能耗曲线会明显恶化。对照实验里LEACH 和 HEED 最好保持 p 与簇头期望比例一致否则对比起点就不公平。2.2 HEED 的混合判据剩余能量与簇内通信成本如何共同决定簇头HEED 把 LEACH 的随机抽签改成了质量筛选。它分两个阶段选簇头第一阶段看剩余能量第二阶段看簇内通信成本。第一阶段每个节点按剩余能量占初始能量的比例计算竞争力值# HEED 竞争力值计算主判据 def heed_c_metric(residual_energy, initial_energy): 剩余能量占比越高竞争力越强 return residual_energy / initial_energy只有竞争力值超过设定阈值的节点才进入候选名单典型阈值 0.05。这一步直接把低能量节点排除在外避免 LEACH 那种快饿死的节点被抽中当簇头的尴尬。第二阶段候选节点在若干轮迭代中互相广播竞争力值边缘概率低的节点主动退出。如果两个候选节点的竞争力差距在 5% 以内就引入副判据——簇内通信成本AMRPAverage Minimum Reachability Power来打破平局。AMRP 的计算是每个候选簇头统计邻居节点最小发射功率的平均值值越小说明周围节点越容易以低功率够到它。HEED 的迭代次数控制参数在仿真脚本里通常叫n_iters典型值取 5 到 8 轮。迭代太少候选节点来不及收敛网络中会出现多个相邻簇头迭代太多控制消息开销线性上涨反而吃掉分簇带来的能量收益。这里特别要提醒 AMRP 的统计口径。AMRP 不是简单距离均值而是最小可达发射功率的均值。仿真里功率模型如果是两径传播TwoRayGroundAMRP 与距离的四次方挂钩数值差异很大如果是自由空间模型Friis则与距离平方挂钩。因此换信道模型之后AMRP 的绝对数值不能跨仿真直接比较只能看同一场景下的相对排序。2.3 直接对照两协议消息开销、收敛速度与适用场景维度LEACHHEED簇头选择依据随机阈值轮转剩余能量 AMRP每轮簇头数量期望由 p 控制波动大由竞争力阈值控制更稳定控制消息开销低单轮广播较高多轮迭代对节点异构性的容忍度差好收敛速度快一轮完成慢依赖迭代次数典型适用场景同构静态网络异构、覆盖优先的网络结论很直接如果优化目标是网络里所有节点尽量同时耗尽能量LEACH 的随机轮转更合适如果优化目标是每轮簇头质量有保证、网络覆盖不塌陷HEED 的双判据更稳。很多公开资料的对比结论互相矛盾根源就在没对齐这个适用前提。提示性能对比前先写清楚优化目标——均摊能耗还是延长稳定期。目标不同选型结论可能完全相反。3. 用 NS-2 从零跑通 LEACH 和 HEED 的最小仿真脚本、参数与预期输出3.1 为什么选 NS-2模块可用性与修改成本的平衡WSN 仿真工具有 NS-2、NS-3、OMNeT、Castalia 等。单论 LEACH 和 HEED 对比NS-2 至今仍然是最省事的选择。LEACH 的 NS-2 扩展包已经流传多年模块可以直接编译运行HEED 的参考实现也能在对应源码包里找到改参数就能跑。NS-3 架构更新但 LEACH 没有随主版本发布官方实现需要自己移植OMNeT 又要额外装框架。对课程设计和毕业设计而言NS-2 学习曲线虽陡但前人踩过的坑多反而是性价比最高的路径。我一般会在 Ubuntu 或者 WSL 环境里装 NS-2.35编译时需要留意 make 版本和 lib 依赖很多报错都是缺libx11-dev或libxt-dev。装完先跑一下官方自带的默认示例确认环境能出 NS-2 的 trace 文件再开始改协议参数。3.2 LEACH 最小仿真 TCL 脚本关键参数逐一拆解跑 LEACH 通常需要三个文件场景脚本、协议参数模板和能量模型定义。下面是最小可跑的 TCL 脚本骨架50 个节点、100m x 100m 区域、仿真时长 120 秒# LEACH 最小仿真脚本基于 NS-2.35 # 场景50 节点随机分布在 100m x 100m 区域 set opt(chan) Channel/WirelessChannel set opt(prop) Propagation/TwoRayGround set opt(netif) Phy/WirelessPhy set opt(mac) Mac/802_11 set opt(ifq) Queue/DropTail/PriQueue set opt(x) 100 set opt(y) 100 set opt(nn) 50 set opt(stop) 120 set opt(energymodel) EnergyModel set opt(initialenergy) 2.0 set opt(rxpower) 0.5 set opt(txpower) 1.0 # 固定随机种子保证实验可复现 ns-random 12345 set ns_ [new Simulator] set topo [new Topography] $topo load_flatgrid $opt(x) $opt(y) # 创建节点并分配初始能量 for {set i 0} {$i $opt(nn)} {incr i} { set node_($i) [$ns_ node] $node_($i) set X_ [expr {int(rand()*100)}] $node_($i) set Y_ [expr {int(rand()*100)}] $node_($i) set energy_ $opt(initialenergy) } # 接入 LEACH 协议代理 set leach_agent [new Agent/LEACH] $leach_agent set p_ 0.05 $leach_agent set round_time_ 5 # 周期性统计全网剩余能量 proc record_energy {} { global ns_ node_ opt set time_now [$ns_ now] set total_energy 0.0 for {set i 0} {$i $opt(nn)} {incr i} { set total_energy [expr {$total_energy [$node_($i) set energy_]}] } puts time$time_now total_energy$total_energy $ns_ at [expr {$time_now 5}] record_energy } $ns_ at 10.0 record_energy $ns_ at $opt(stop) halt_all proc halt_all {} { global ns_ $ns_ halt } $ns_ run脚本里值得注意的参数有三个。p_是 LEACH 簇头比例直接决定每轮簇头数量round_time_是单轮时长太短会控制消息堆积太长则簇头更替太慢initialenergy和功率参数决定能耗整体量级不同取值下两协议的相对优劣可能反转。比如初始能量从 2J 改成 5JLEACH 的优势窗口会明显拉长因为随机轮转在长生命周期里的均摊效果被放大了。3.3 HEED 仿真接入从模块替换到参数调整HEED 的接入方式是替换协议代理类参数数量比 LEACH 多一点。需要先在 NS-2 源码目录里把自己的 heed 模块编译进去然后在场景脚本里配置# HEED 仿真脚本中的协议配置段 set heed_agent [new Agent/HEED] $heed_agent set c_threshold_ 0.05 $heed_agent set n_iters_ 6 $heed_agent set alpha_ 0.5 $heed_agent set cluster_radius_ 25c_threshold_太低会把能量不足的节点放进候选名单太高则可能出现某个区域没有候选簇头的死区alpha_控制主判据和副判据在竞争力计算里的权重0.5 表示等权cluster_radius_决定一个簇的覆盖半径调小会导致簇数量过多、消息开销上涨。HEED 和 LEACH 的最大差别在分簇的稳定性。HEED 一旦选出簇头在后续若干轮内簇头更替明显减缓簇结构稳定LEACH 则每轮都可能换一批表现为 trace 文件里簇头地址频繁变化。这个差异在 NAM 动画里一眼就能看出来。3.4 判断仿真已经正确运行的三个信号跑完并不代表可信。我会先检查三个信号再决定要不要继续对比分析。第一日志里每轮簇头数量应稳定在预期区间。LEACH 大约在p * 总节点数左右浮动HEED 应当低于这个数但波动更小。如果 HEED 每轮簇头数比 LEACH 还多多半是c_threshold_设置太低竞争力筛选没起作用。第二能量曲线初始阶段应平滑下降。出现台阶状突降说明有节点被反复选为簇头协议轮转失效。第三仿真结束时的存活节点比例应与同参数典型结果接近。50 节点、2J 初始能量、120 秒仿真通常至少保留 60% 到 70% 节点存活远低于这个数就要回头查发射功率和初始能量是否合理而不是急着换协议再跑一轮。4. 性能对比的四大指标怎么算才不翻车能耗、寿命、吞吐与覆盖4.1 网络寿命的两种定义FND 与 HND 怎么选网络寿命是 WSN 协议对比最常用的指标但定义不同结论可能反转。FNDFirst Node Death指第一个节点能量耗尽的时间HNDHalf Node Death指半数节点死亡的时间。LEACH 因为能耗均匀FND 通常来得晚HEED 的簇头承担更多融合任务节点能耗波动更大FND 可能更早但 HND 附近的网络覆盖明显更完整。只报 FND 会低估 HEED只报 HND 会低估 LEACH。我通常在仿真里同时记录 FND 和 HND并额外算一个存活节点时间曲线下的面积作为综合寿命指标。每 5 秒记录一次存活节点数仿真结束后用矩形法积分import csv # 读取存活节点日志计算存活面积寿命综合指标 survivals [] with open(alive_nodes.log, r) as f: for line in f: time, count line.strip().split(,) survivals.append((float(time), int(count))) area 0.0 for i in range(1, len(survivals)): t_prev, c_prev survivals[i-1] t_curr, c_curr survivals[i] area (t_curr - t_prev) * (c_prev c_curr) / 2.0 print(f存活面积节点·秒: {area:.2f})这个指标能把整个生命周期压成一个数值做柱状图时两协议差异非常直观。面积越大说明网络整体存活时间越长且能吸收个别时刻的偶然波动。FND、HND、存活面积三者同时上报评审或验收方基本不会说统计口径有问题。4.2 能耗均匀度用标准差而不是平均值判断协议优劣平均能耗低不等于协议好。一个把能耗集中在少数节点的网络平均能耗可能很好看但局部节点很快死亡网络出现空洞覆盖塌陷。因此能耗均匀度是第二重要的观察点。统计方法很简单取每个节点仿真结束时的剩余能量算标准差。标准差越小说明能耗越均匀。LEACH 的能量分布标准差通常小于 HEED因为随机轮转天然把能耗摊平HEED 的簇头要持续承担转发剩余能量离散度更高。但 HEED 的簇头分布更合理数据融合效率高所以总能量消耗往往更低。两个指标放一起看才有意义。另外要注意统计时间点必须一致。拿 LEACH 跑 150 秒的数据和 HEED 跑 120 秒的数据比标准差后者节点死得早、剩余能量为零的多标准差必然偏大。统一仿真时长是基本前提。4.3 吞吐量和丢包率的统计口径排除初始阶段噪声吞吐量对比最容易犯的错是拿整个仿真周期的数据直接平均。协议从启动到第一次稳定选簇通常有 5 到 15 秒的预热期这段时间控制消息占主导数据面吞吐量极低。把它算进全程均值PDR 和吞吐量都会被严重拉低。我一般分三段统计预热段0 到 10 秒、稳定段10 到 90 秒、衰减段90 秒后。对比时只报稳定段的吞吐量和 PDR衰减段单独报用于观察网络寿命末期行为。分段统计可以用 AWK 处理 NS-2 的 trace 文件# 计算稳定段吞吐量10~90秒内收到的数据包字节数 BEGIN { start 10.0 end 90.0 bytes 0 } $1 start $1 end $2 r $4 RTR { bytes $6 } END { throughput bytes / (end - start) * 8 / 1000 printf(Throughput: %.2f kbps\n, throughput) }注意$4 RTR这个条件它只统计网络层实际接收的数据避免同一个包在链路层被重复计数。丢包率则用稳定段内应用层发送包数减去RTR 接收包数再除以发送包数不能把控制包混进去否则 HEED 消息开销大的劣势会被严重放大。提示统一统计口径再下结论。LEACH 和 HEED 的控制开销结构不同混入控制包的吞吐量对比结果没有参考意义。5. 仿真录像的做法与避坑指南从 NAM 轨迹到可验收的录像文件5.1 完整制作链路NAM 配置、脚本时序与录制工具NS-2 自带的 NAM 动画工具可以直观展示节点通信行为。要让 NAM 反映协议行为在仿真脚本里需要启用 trace# 打开 NAM trace 文件 set tracefd [open leach.nam w] $ns_ namtrace-all $tracefd proc stop_nam {} { global ns_ tracefd close $tracefd } $ns_ at $opt(stop) stop_namNAM 动画生成后用屏幕录制工具抓成视频。我一般会先用 NAM 手动播放一遍找到簇头出现和数据融合的关键时间点再重新播放并全程录制。窗口分辨率设 1280x720帧率 30fps时长控制在 60 到 90 秒。太长时间的录像在对比展示时没人能看完反而削弱结论。录制工具的选择影响画质和体积。系统自带录屏最省事但对焦和帧率不稳第三方工具支持区域录制和帧率控制适合需要固定窗口位置的场景。建议固定 NAM 窗口位置和大小避免录制过程中窗口抖动。5.2 避坑一随机种子不一致导致对比失真现象同一场景跑 LEACH 和 HEED第二次仿真里节点布局和能耗曲线完全变样。 原因NS-2 默认启动时使用随机种子节点位置、簇头选举顺序全部变掉。 解决在脚本开头固定随机种子两协议用同一套节点位置。# 固定种子 12345两协议共用同一节点布局 ns-random 12345对比实验必须确认两个脚本的随机种子一致。否则 LEACH 碰巧分到 50 个节点均匀分布HEED 分到节点聚成一团结论再漂亮也没有可比性。换种子后如果结论方向不变说明比较结果稳定如果方向变了说明协议差异对拓扑敏感需要在论文或报告里明确写出这个敏感性结论。5.3 避坑二节点能量模型缺失、HEED 判据失效现象HEED 跑出来的结果比 LEACH 差很多簇头频繁更换能耗曲线异常。 原因脚本只在节点创建后单独设了energy_字段但没在 node-config 里启用能量模型。HEED 的竞争力计算读到能量字段为空第一阶段判据形同虚设。 解决在创建节点前先用 node-config 统一设置能量模型参数$ns_ node-config -energyModel $opt(energymodel) \ -initialEnergy $opt(initialenergy) \ -rxPower $opt(rxpower) \ -txPower $opt(txpower)注意单独用set energy_赋初值的方式不会让能量模型在 NS-2 里生效。节点读数正常的关键是 node-config 的-energyModel参数。这个坑在 LEACH 里不明显因为 LEACH 不依赖能量字段做判据但 HEED 的主判据直接读这个值模型缺失等于把协议降级成随机选簇算法对比结论纯属翻车。5.4 避坑三录像不同步导致对比图对不上现象两段录像时间轴对不上簇头出现顺序混乱做双屏对比时观众一头雾水。 原因录制时没有固定 NAM 的播放起点或手动拖动了进度条。 解决录制开始时在 NAM 的 replay 按钮上重置时间轴到 0统一开启和结束录制剪辑时保留完整时长轴。有条件的话在画面右上角叠一个时间标注这样不同片段的对应关系一目了然。两段录像叠加对比时用时间标注对齐关键事件比肉眼找数据包跳变准确得多。5.5 避坑四录像帧率太高导致文件体积暴涨现象一段 90 秒的 60fps 录像占了 400 多 MB压缩后画面模糊。 原因NAM 动画是非等宽事件流每秒事件数差异很大60fps 录制把大量重复帧全部存了下来。 解决录制帧率降到 24fps控制消息密集段用慢放空闲段用快进。剪辑后压制编码时用恒定质量参数x264 的 CRF 值设为 23体积和画质平衡最佳。不要用固定码率压制事件密集段码率不够会糊事件稀疏段码率又浪费。提示录像不是越长越好。一段 60 秒、带时间轴标注、关键事件标记的录像比 10 分钟完整录播更能说明问题。6. 把性能数据叠加进仿真录像的进阶技巧帧标记、指标叠加与结果存档纯录像只能让观看者模糊看到节点死亡和数据流看不出定量差异。更实用的做法是把能耗曲线实时叠加到录像画面上。第一步TCL 脚本里每 5 秒记录一次全网剩余能量总和导出为 CSV第二步用剪辑软件把曲线以画中画形式叠加到 NAM 视频上。叠加位置固定在下三分之一处避免遮挡主画面数据流。曲线颜色用红蓝对比LEACH 用红色、HEED 用蓝色。纵轴量程必须一致否则斜率差异会误导视觉判断——比如 LEACH 曲线满量程是 100 焦耳HEED 是 50 焦耳前者看起来平缓后者看起来陡峭观感完全不同。帧标记是另一个提升录像质量的小技巧。在剪辑软件里为关键事件打标记第一个节点死亡FND、数据融合首次出现、簇头切换瞬间并在标记处用文字说明这个事件对指标的影响。答辩汇报时评审不需要从头看完整录像只需要定位标记点比几十页文字说明有效得多。我遇到过一次评委直接问FND 在哪个时间点靠标记点十秒内就找到了对应画面并解释清楚原因。存档方面也要养成固定习惯。仿真结束后按场景-协议-种子-日期命名目录保留 TCL 脚本、trace 文件、能耗 CSV 和视频文件四件套。这个习惯来自我第一次对比实验翻车。当时改了参数忘记保存原版脚本复现时怎么都调不回原来那组簇头分布折腾了两天才发现是随机种子没记录。现在每次跑仿真前先记种子跑完立即归档脚本和日志再也不会出现数据能拿到但说不清怎么跑出来的情况。希望帮到你。本文还有配套的精品资源点击获取