资讯动态

基于最佳簇半径的无线传感器网络分簇路由:能耗均衡与仿真优化

发布时间:2026/10/19 6:16:04 来源:尧图企业网站定制
做无线传感器网络的仿真最绕不开的一个词就是“分簇路由”。我在调网络生命周期曲线时发现真正决定一个分簇算法是“能用”还是“不能打”的往往不是簇头选举公式那点差异而是簇半径这个看似不起眼的参数。本项目标题里的“基于最佳簇半径”就是这个思路不把分簇当成随机行为而是先算出一个让全网每轮能耗最小的半径再让簇头竞选和节点入簇都围着这个半径转。这篇博文我会把能耗模型、半径推导、算法流程、仿真结果和调参经验一次性讲透适合正在做WSN方向课程设计、毕设仿真或者刚入门物联网协议优化的读者抄作业。1. 为什么要研究分簇路由能耗均衡才是网络寿命的关键1.1 全网生命周期受制于“短板节点”无线传感器网络最常见的部署方式就是随机撒点几十个到几百个节点撒在一片区域里每个节点靠电池供电能量用一点少一点。直接让所有节点各自把数据发给基站是最简单也最耗电的方式——距离基站远的节点发一次数据就要消耗大量能量很快就会死掉而靠近基站的节点又因为频繁转发别人的数据而过早耗尽。网络中一旦出现第一批死亡节点覆盖就会出现空洞后续数据根本传不回来。所以业内普遍采用分簇路由把节点分成若干组每组选一个簇头普通节点先把数据发给簇头簇头做聚合后再发给基站。这样普通节点的发送距离被大大缩短簇头虽然承担了远距离传输但数量少、可控整体能耗会低很多。这也是本项目最核心的出发点分簇不是目的降低全网能耗、延长网络周期才是目的。1.2 “最佳簇半径”到底是什么一个必须动态看待的全局参数很多人第一次看到“最佳簇半径”会以为这是指每个簇的物理覆盖范围是一个固定常数——比如所有簇半径都等于50米。实际上这里说的是一个全局设计参数在给定节点密度、基站位置、通信能耗模型的前提下存在一个能让全网每轮总能耗最低的簇半径值。这个值既不是越大越好也不是越小越好。簇半径太小意味着簇头很多。每个簇头都要承担一次向基站发送聚合数据的开销簇头数量多了远距离传输的总次数就上去了反而费电。簇半径太大意味着一个簇里塞了太多普通节点簇内通信和聚合负担全压在单个簇头身上簇头很快耗光。所以最佳半径本质上是在“簇头数量”和“簇内规模”之间找一个平衡点。这和小区规划的思路很像社区太大物业管不过来太小则每个社区都得单独修一条直连总站的公路路网成本反而更高。2. 系统设计与簇半径推导先把能耗模型摆到桌面上2.1 第一跳能耗模型与阈值距离d0在推导最佳簇半径之前先得把能耗模型统一。我这次仿真用的是无线通信领域最常用的一阶无线电能耗模型节点发送l比特数据到距离d的簇头或基站时消耗的能量E_Tx分两段计算。当传输距离小于阈值距离d0时采用自由空间模型能耗与距离平方成正比发送耗能为E_Tx(l, d) l × E_elec l × ε_fs × d²当传输距离大于等于d0时采用多径衰落模型能耗与距离四次方成正比E_Tx(l, d) l × E_elec l × ε_mp × d⁴其中E_elec是发射电路每比特的基础耗能ε_fs和ε_mp分别是两种模型的功率放大系数。接收l比特数据的能耗则是E_Rx(l) l × E_elec阈值距离d0的计算公式是d0 sqrt(ε_fs / ε_mp)我仿真中使用的典型参数是E_elec50nJ/bitε_fs10pJ/bit/m²ε_mp0.0013pJ/bit/m⁴算出来d0大约是87.7米。这个d0非常关键因为簇间通信距离是否超过d0会直接决定簇头向基站发送时的能耗是二次增长还是四次增长——如果分簇半径设计得不好导致不少簇头距离基站超过d0那网络能耗会瞬间爆炸。注意每次做方案对比之前一定要确认所有算法用的是同一套能耗参数。我见过很多对比实验里不同算法用了不同的ε_fs和ε_mp最后算出来的生命周期差异根本不是算法带来的而是参数不一致造成的这种对比没有意义。2.2 最优簇半径推导的两条主线推导最佳簇半径我会从“单轮全网总能耗”这个角度入手。假设监测区域面积为A节点总数为N节点密度为ρN/A。如果每个簇的覆盖半径为R那么每个簇内大约有N_cρπR²个节点。每一轮的工作可以拆成两个阶段第一阶段是簇内数据收集。簇内N_c个节点各发一次l比特数据给簇头簇头接收并聚合。这个过程的能耗由两部分组成普通节点的发射能耗加上簇头的接收能耗。如果节点在簇内近似均匀分布节点到簇头的平均距离大约是2R/3那么簇内总能耗可以近似写成E_intra ≈ N_c × l × E_elec ρ × ∫(0到R) (ε_fs × r²) × 2πr dr第二阶段是簇头向基站发送聚合结果。这个距离取决于簇头到基站的位置我们用d_to_sink来表示。假设簇头数量为K≈A/(πR²)那么全网单轮总能耗E_total大约等于簇内能耗乘以K再加上K次簇间远距离传输能耗。将E_total写成R的函数之后对R求偏导并令导数为零就能解出最优半径的理论表达式。最简化的情况下可以得到R* ≈ d0 / sqrt(2)取d087.7m时大约是62m。但实际仿真中这个值不能直接用。原因有两个一是节点不是无限均匀的随机部署时每个簇的实际节点数浮动很大二是基站如果在区域边缘远端簇头到基站的距离可能会超过d0这时多径衰落模型会让最优半径明显变小。所以理论推导只提供量级参考真正的最优半径要靠仿真扫参确认。2.3 再往前走一步非均匀节点分布怎么修正均匀分布假设在真实场景里很少成立。农田监测中的节点可能沿着灌溉管道密集布置楼道里节点会聚在拐角这种空间不均匀性会让按固定半径分簇变得很别扭。一个常用修正办法是为每个候选簇头引入“局部密度感知”候选簇头先统计自己通信半径内实际存在的邻居数量如果邻居太少就适当扩大竞争半径如果邻居太密集就缩小竞争半径。具体到本项目我在基础半径公式之后加了一个修正项。假设节点i周围实际邻居数为n_i全网平均邻居数为n_avg那么节点i参与竞选簇头时采用的竞争半径调整为R_i R* × sqrt(n_avg / n_i)这样节点稀疏的区域簇头覆盖范围变大避免产生孤立节点节点密集的区域簇头覆盖范围缩小避免一个簇头管理过多节点、过早耗能。这个修正看起来很简单但我实测下来效果非常明显尤其是节点随机撒布的场景中网络第一个节点死亡时间能提升10%到15%。3. 算法流程与核心实现从公式到可运行代码3.1 算法总流程选出簇头之后再“竞争半径”筛选在具体实现时我把整个路由过程设计成轮次制每一轮分成簇建立阶段和稳定传输阶段。簇建立阶段不是简单地把所有候选者都设为簇头而是引入基于最佳簇半径的竞争筛选避免两个簇头扎堆出现在同一片区域里。完整流程是这样的网络初始化部署节点记录每个节点的坐标、初始能量、邻居表计算全局平均邻居数。每轮开始时每个节点计算自己的竞选阈值T(n)如果随机数小于阈值则成为候选簇头。这里沿用经典LEACH的阈值公式T(n) P / (1 - P × (r mod (1/P)))当n属于本轮未担任过簇头的节点集合。候选簇头以最佳簇半径R为“竞争半径”广播竞选消息消息里带上自己的剩余能量和节点ID。候选簇头检查自己竞争半径内是否有其他候选簇头若有则比较剩余能量能量高者胜出能量低者退出竞选。这一步本质上保证了最终簇头之间的最小间距不会小于R也就是簇半径真正落到了网络结构上。普通节点选择距离最近且在自己感知范围内的正式簇头发送入簇请求。如果一个簇头收到的入簇请求数量过多说明这个簇规模偏大就按节点距离排序只接收距离最近的N_c_max个节点其余节点转投次近簇头。稳定传输阶段簇头给簇内节点分配TDMA时隙普通节点在指定时隙内发送数据簇头聚合后发往基站。本轮结束后更新节点剩余能量进入下一轮直到网络死亡率超过阈值。3.2 关键代码片段簇头选举与分簇逻辑这段逻辑我用C语言风格描述一遍方便直接改写成MATLAB或Python仿真。核心是候选簇头竞争筛选这一段也是整个算法最容易被忽视的部分static double optimal_radius(double d0, double total_area, int node_count) { double rho node_count / total_area; double r_theory d0 / sqrt(2.0); // 实际部署中需根据节点分布修正通常取理论值的0.5~0.8 double r_opt r_theory * 0.65; if (r_opt 20.0) return 20.0; if (r_opt 0.3 * sqrt(total_area)) return 0.3 * sqrt(total_area); return r_opt; } int elect_cluster_head(int node_id, int round) { double threshold p_opt / (1.0 - p_opt * fmod(round, 1.0 / p_opt)); double rand_val uniform_random(0.0, 1.0); if (rand_val threshold energy[node_id] energy_threshold) { return 1; } return 0; } void compete_for_ch(int node_id, double r_opt) { for (int i 0; i neighbor_count[node_id]; i) { int nb neighbors[node_id][i]; if (is_candidate[nb] nb ! node_id) { double dist euclidean_distance(node_id, nb); if (dist r_opt) { if (energy[node_id] energy[nb]) { is_ch[node_id] 0; return; } } } } is_ch[node_id] 1; }这里有个很容易踩的坑竞选阈值T(n)的计算里1/P取整表示一轮“理想簇头周期”。如果P0.05那么每20轮要重新允许所有节点参与竞选公式里的fmod(round, 1.0/P)就是用来实现这个重置周期的。不少初学者直接拿随机数跟固定概率比没有这个周期重置逻辑导致能量低的节点反复当选网络前几轮就崩了。分簇阶段还有一个细节普通节点加入簇头时要控制每个簇头的子节点数量上限。我在仿真中发现一个极端情况节点分布严重不均匀时某个簇头附近聚集了30多个节点按照TDMA调度每个节点分到的时隙短得离谱而且该簇头单轮接收能耗直接拉满一轮下来能量掉一大截。所以我给簇头设了一个子节点上限N_c_max超过上限时后续节点自动选择其他簇头这个简单限制能把最差场景下的节点死亡率压低不少。3.3 复杂度与参数敏感性分析从复杂度角度看这个算法的额外开销主要在候选簇头的竞争比较阶段。每个候选簇头只需要检查自己邻接表里的节点邻接表长度由通信半径决定通常只有几十个节点因此单轮时间复杂度和O(N)是同数量级的不会成为仿真瓶颈。相比经典LEACH额外增加的开销就是一次候选簇头广播和一个邻域内比较工程上完全可以接受。参数敏感性方面我做了简单扰动测试把R上下浮动20%网络生命周期变化大约在8%左右。相比之下P簇头比例如果从0.05改成0.08同样浮动20%的R生命周期差距会扩大到15%以上。这说明在最佳簇半径的基础上簇头比例依然是第一敏感参数半径修正属于“锦上添花”的部分但不能替代对P本身的调优。我的经验是先固定P在0.05附近扫一遍半径找到谷底再在谷底附近微调P往往能得到比单独调任何一个参数都更好的组合。4. 仿真设计与结果对比用数据说话4.1 仿真环境与参数设置我用MATLAB搭了一个模拟项目X的仿真平台。部署区域为100m×100m正方形区域100个传感器节点随机均匀撒布基站位于左下角(0,0)。每轮每个普通节点产生一个4000bit数据包簇头聚合后同样以一个4000bit数据包发给基站。初始能量0.5J其他能耗参数沿用第一节给的数值。对比方案我选了三个经典LEACH无半径约束簇头完全随机分布、固定半径分簇R分别取30m、40m、50m三组和本文算法带密度修正的最优半径。每个场景独立运行20次取平均避免随机撒点带来的一次性偏差。评价指标是FND第一个节点死亡轮数、LND最后一个节点死亡轮数和基站收到的总数据包数量。仿真参数表归纳如下参数取值说明部署区域100m × 100m随机撒布节点数100初始能量0.5J基站位置(0, 0)区域角落数据包大小4000bit普通节点发送E_elec50nJ/bit发射/接收电路耗能ε_fs10pJ/bit/m²自由空间模型系数ε_mp0.0013pJ/bit/m⁴多径衰落模型系数簇头竞选比例P0.05理论每20轮一轮完整竞选运行次数20每次随机撒点取平均4.2 三组对照实验固定簇头数、无约束、最优半径先说经典LEACH。它的问题非常直观候选簇头完全靠随机数决定没有规避机制经常出现好几个簇头紧挨在一起的情况。簇头扎堆的直接后果是一片区域里有多个簇头重复向基站发送聚合数据而另一片区域却没有簇头覆盖节点要么找不到就近簇头要么被迫超远距离直传基站。仿真结果里LEACH的FND大约在870轮附近LND在1450轮附近但从第800轮开始死亡节点曲线就明显抬头后半段存活节点数量下降得很快网络处于“半瘫痪”状态的时间很长。固定半径分簇则暴露了另一个问题半径取50m时簇内节点数太多靠近基站的簇头尚且能扛住但远处区域的簇头要向基站发送跨半场的数据距离往往在80m到120m之间超过d0后进入四次方能耗区簇头一轮就掉将近1mJ能量FND只有940轮左右。半径取20m时簇头数量膨胀远距离重复传输增多情况也没有改善太多。扫描多组半径之后30m附近的FND在980到1000轮之间比无约束情况好一些但依然不如本文算法。本文算法采用理论推导加密度修正的R值实际仿真中R*落在34m到40m之间波动。因为节点随机撒布每个候选簇头的R_i在基础值附近做局部密度修正所以不会出现簇头过近或过疏。最终FND稳定在1050轮以上LND接近1650轮整体曲线比LEACH平滑得多。4.3 结果解读FND / LND与吞吐量变化我统计了各方案的平均表现放在一张表里对比更清楚方案FND轮LND轮基站总收包万个每轮平均能耗J经典LEACH87214535.20.0218R20m固定91214785.50.0211R30m固定99515206.00.0196R50m固定94114855.60.0205本文算法105216487.10.0176从表里能看出两个信息。第一FND的提升比LND更明显说明本文算法主要改善了网络前期的能耗均衡性避免了头几个节点过早死亡第二基站收到的总数据包从LEACH的5.2万提升到7.1万说明网络在更长的存活周期内持续产生了有效数据而不是停留在“节点还活着但传不回数据”的假性存活状态。虽然LND绝对值的提升没有FND那么夸张但工程上FND往往更关键。因为传感器网络的监测任务通常对覆盖率有下限要求第一批节点死亡就意味着覆盖出现漏洞这时候任务质量已经受损。所以让FND往后延比让最后一个节点多撑几十轮更有实际意义。5. 常见问题、踩坑记录与扩展方向5.1 现场经常翻车的几个点第一个翻车点是直接把理论最优半径套到所有场景里。我一开始把d062m的理论值直接当成R*用结果在100m×100m的区域内簇头数量太少不少簇要管理50个以上节点簇头死得飞快。后来加了0.65的缩放系数和节点密度修正FND才从800多轮提升到1050轮。这里要特别提醒理论推导给的是趋势和量级真实最优值必须按自己的部署区域、节点数量、基站位置重新扫一遍参数。第二个翻车点是忽略“孤立节点”。当簇头竞争半径偏小时部分边缘区域的节点可能找不到任何一个候选簇头。这些节点会退化成直传基站模式发送距离动辄七八十米一轮能耗是正常簇内传输的十几倍很快阵亡。处理办法是在分簇阶段加一个反馈如果普通节点找不到候选簇头就在该区域临时放宽竞争半径重新触发一次候选簇头竞选或者把该节点划入最近簇头并豁免其对距离的限制。我自己在代码里是给这类节点一个“远距离入簇”标记允许它们加入距离最近的簇头哪怕簇头子节点数量已经达到上限。第三个翻车点是没做“能量阈值门限”。簇头竞选时如果只看随机数能量极低的节点照样能当簇头结果刚上任一轮就耗尽整个簇的数据就断了。所以在判断条件里加了一个剩余能量门槛只有剩余能量大于初始能量15%的节点才有资格成为候选簇头。这个门槛的取值不能太高太高会让高能区节点反复当选、低能区节点长期无簇头服务也不能太低否则起不到保护作用。我试下来10%到20%之间比较稳。5.2 解决思路速查表常见问题现象解决思路理论最优半径失效FND明显低于预期按实际场景重新扫参引入0.5~0.8缩放系数节点分布不均部分区域簇头拥挤部分区域无簇可用用局部邻居数修正竞争半径按密度动态调整孤立节点直传基站少数节点能耗极高早死放宽入簇范围允许加入远距离簇头并豁免上限低能节点反复当选簇头簇头频繁死亡网络断裂增设剩余能量门限低于阈值不能参与竞选不同算法参数不一致对比结果失真所有方案统一E_elec、ε_fs、ε_mp、包大小、初始能量5.3 这个思路可以继续往哪里延伸我做完这版仿真之后觉得有两个方向很值得继续挖。第一个是考虑移动汇聚节点如果基站或汇聚节点可以移动最优簇半径就不再是一个静态值而是随汇聚节点位置变化的动态参数。每次汇聚节点移动后可以重新计算一层R*簇头选举也随之调整这种动态半径机制在野外巡逻、灾后救援场景中非常实用。第二个方向是结合无线能量传输。现在不少节点支持从环境收集能量或接收无线充电能量模型变成了“能耗补给”的混合模型簇头选择逻辑也要从“省电”转向“能量中性”。这时候最佳簇半径的推导目标函数从最小化总能耗变成最大化能量净收益推导过程和仿真参数都会大不一样。我个人在实际操作中的体会是分簇路由算法看起来公式多、参数杂但只要把能耗模型先搭扎实再把“最优半径”当成一个可以扫参验证的工程变量整个算法就跑得通、也能讲得清。最后再分享一个小技巧做参数敏感性分析时把R*、P、能量阈值三个参数做成二维网格扫描画出一张FND热力图哪个参数对网络影响最大会非常直观论文写起来也比单跑几条曲线有说服力得多。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑