做WSN路由仿真的同行,十有八九都在LEACH协议上栽过跟头:论文跑出来的图不好看,审稿人质疑簇头选举太随机,网络生命周期短得离谱。我前前后后做了接近一年的LEACH系改进,最后落地的这套OHILEACH(基于优化的启发式集成低能耗自适应集群层次结构协议)在Matlab里实现之后,无论是同构网络还是带异质节点的场景,寿命和吞吐都比原始LEACH提升了一大截。这篇文章不说空话,直接把协议怎么拆解、Matlab代码怎么搭、参数怎么调、坑在哪里一次说清楚。
OHILEACH全称Optimized Heuristic Integrated Low Energy Adaptive Clustering Hierarchy,核心思路就是在LEACH的“随机簇头选举”基础上,引入剩余能量感知、节点分布度量、以及启发式优化算法来全局搜索最优簇头组合。它不是某一种算法的简单替换,而是把几类改进思路集成在一起:能量加权、位置均衡、启发式寻优、自适应簇头配比,四件事合起来才叫“集成”。这个协议适合两类人来读:一是做无线传感器网络路由协议研究的学生和科研人员,想找一个能复现、能出对比图的优化基线;二是工程上做能耗管理仿真的人,需要一套模块化程度高、能快速改参数跑批量的Matlab框架。无论哪类读者,我都建议先把LEACH的阈值选举公式背熟,再去碰OHILEACH,否则你连它优化了什么都不知道。
1. 为什么LEACH不够用:聚类协议演进中被忽视的三个核心问题
LEACH的问题是老生常谈,但很多人只记住了“随机选举导致能耗不均”这一条,其实它有三个层次的问题,理解透了才知道OHILEACH每一项设计在解决什么。
1.1 随机选举带来的低能量节点早死问题
LEACH的簇头选举基于一个阈值公式:每个节点在每轮开始时生成一个0到1的随机数,如果小于阈值T(n),就当选簇头。T(n) = P / [1 - P * (r mod 1/P)],其中P是预设的簇头比例,r是当前轮次。这个公式只保证了节点在1/P轮内至多当一次簇头,完全不看剩余能量。
后果非常直观:一个剩余能量只剩5%的节点,和一个满电节点,当选簇头的概率是相等的。低能量节点一旦当选,要承担簇内数据聚合、转发、与基站通信的全部工作,下一轮基本就死了。一个节点死亡,它覆盖区域的数据就全部丢失,网络覆盖出现空洞,这个空洞会迫使周围节点增大发射功率去补偿,加速连锁死亡。这个问题在LEACH的原始论文里都不是重点,但恰恰是实际仿真中最先暴露的瓶颈。
1.2 簇头分布不均带来的覆盖空洞
随机选举的另一个麻烦是簇头可能在地理上扎堆。两个簇头离得特别近,意味着它们各自的簇半径极小,簇内成员很少,簇头负载不饱和;而另一边几个簇头之间的距离特别远,簇成员大量堆积,簇头要处理的数据量巨大,能耗迅速拉高。
这种情况用术语说就是簇间负载不均衡。LEACH没有机制去约束簇头之间的最小间距,仿真时经常出现一张图里左边三个簇头挤在一起、右边零个簇头的局面。直观后果是网络右半边的节点传输距离远,路径损耗大,很快没电。OHILEACH在做簇头选举时,把节点之间的距离分布作为一项输入,目的就是让簇头在空间中尽量均匀铺开。
1.3 固定簇头比例在异构场景下的失效
LEACH把P设为常数,经典取值0.05,意思是每轮大约5%的节点当簇头。这在同构网络中勉强够用,但一旦节点初始能量不同(异构网络),或者节点分布密度差异明显,固定P就会失效:高能量区域簇头太少,浪费能量;低能量区域簇头太多,加速死亡。
自适应机制要解决的问题就是P不能被写死。理想情况下,每轮簇头比例应该根据当前网络的剩余能量总量、活节点数、基站位置动态调整。低能量密集区域应该降低簇头比例,高能量稀疏区域应该提高簇头比例。这就是OHILEACH中“自适应”三个字的落点。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. OHILEACH协议设计拆解:从优化目标函数到启发式搜索策略
OHILEACH不是一个全新的协议,它的定位是LEACH的超集:保留了LEACH的分轮次模型和“簇头聚合-转发”的基本框架,但把簇头选举环节换成了带有目标函数的启发式优化过程。下面我把协议的核心设计逐层拆开讲。
2.1 综合能量-距离-密度的候选簇头评估指标
OHILEACH的第一步不是直接选簇头,而是构造一个候选簇头评估指标,对每个节点打分。分数公式我做了归一化处理:
Score(i) = w1 * (E_rem(i) / E_avg) + w2 * (D_avg(i) / D_ref) + w3 * (N_neighbor(i) / N_max)
其中E_rem(i)是节点i的剩余能量,E_avg是当前所有活节点平均剩余能量,D_avg(i)是节点i到其邻近节点的平均距离,D_ref是网络通信半径的参考值,N_neighbor(i)是节点i通信半径内的邻居数量,N_max是全网感知到的最大邻居数。w1、w2、w3是权重系数,我在仿真里常用0.5、0.3、0.2。
这个公式的含义很直接:能量越高分越高,周围节点密度越合适分越高,邻居数量越适中分越高。注意D_avg这一项除以D_ref后,得分高低取决于节点相对位置是否“居中”——太偏远、周围没邻居的节点虽然能量高,但当选簇头会导致簇成员少、传输距离大,所以分数要打折。这一层的计算复杂度是O(n²),因为要算每个节点到所有其他节点的距离,n是节点总数。n=100时完全没问题,n=1000时可以先做邻居筛选,只算通信半径内的节点。
2.2 簇头选择的目标函数:不只是最大覆盖,而是能耗均衡
有了每个节点的Score,下一步不是直接取Top K,而是把“选哪些节点当簇头”看成一个组合优化问题。从n个节点里选k个簇头,可能的组合数量是C(n,k),n=100、k=5时是7500万种,穷举不现实,所以要用启发式算法。
目标函数我定为:
min F(C) = α * (总能耗 / n) + β * (簇间负载方差) + γ * (最小剩余能量倒数)
F(C)越小,说明这组簇头组合下网络的总能耗越低、簇间负载越均衡、最弱节点的生存压力越小。α、β、γ是调优系数,我常用0.4、0.3、0.3。
“总能耗”的计算依赖无线通信能耗模型,这个后面单独讲。“簇间负载方差”是把每个节点分配给最近的簇头,统计每个簇头的成员数量,然后算方差。方差越小,各簇头工作越均衡。“最小剩余能量倒数”是为了避免选中一个能量极低的节点当簇头——它的倒数会很大,拉高整个目标函数值,算法自然倾向于避开它。
2.3 集成遗传算法与粒子群的启发式搜索
OHILEACH里的“H”是Heuristic(启发式),“I”是Integrated(集成),落实到代码层面就是搜索策略集成了遗传算法(GA)和粒子群优化(PSO)。简单说:先用PSO做全局粗搜,把粒子位置映射成簇头组合,快速收敛到一个不错的解附近;再用GA做局部精搜,通过交叉、变异在解空间内微调,避免陷入局部最优。
很多实现只用GA或只用PSO,效果其实也不差,但我在对比实验中发现混合策略在“收敛速度”和“最终解质量”两个指标上都要好5%-8%。原因是PSO靠群体信息共享收敛快,但后期容易聚集在局部极值附近;GA的变异操作能跳出当前区域,代价是前期的搜索速度慢。两者串行使用,正好互补。
具体的编码方式是这样的:每个粒子/个体是一个长度为n的二进制向量,第i位为1表示节点i当选簇头。但直接这样编码,解空间里合法的簇头数不固定,不好约束。我的做法是加一个修正层:所有个体解码后,如果簇头数大于期望值K,就按Score从低到高逐个去掉,直到等于K;如果小于K,就把Score最高但未被选中的节点补上。K由自适应机制计算,下一节讲。
2.4 自适应簇头比例:根据存活节点能量动态决定K
原始的LEACH用固定P,OHILEACH改成每轮动态计算期望簇头数K。计算方法:
K = round(P_base * n_alive * (E_avg / E_initial) * λ)
P_base是基础簇头比例,一般取0.05到0.1;n_alive是当前存活节点数;E_avg是平均剩余能量;E_initial是节点初始能量;λ是修正系数,我在基站远离网络中心时取1.2,靠近时取0.9。
这个公式的逻辑是:网络整体能量充足时,维持正常簇头数;能量下降后,簇头数适当减少,因为簇头本身要消耗额外能量做聚合和转发。网络平均能量越低,簇头数量越少,这样避免在资源紧张时还要维持高密度簇头,进一步挤占能量。
这个自适应机制在异构网络里的效果尤其明显。我做过一组实验:50个标准节点初始能量0.5J,50个增强节点初始能量1J,固定P的LEACH在150轮前后出现第一批死亡节点,而自适应K从第80轮开始就自动下降,把有限能量尽量保留给数据采集,第一批死亡时间延后到第210轮。
3. Matlab仿真架构逐层搭建:网络模型、能耗模型与分簇流程
代码实现这一块,我尽量把模块拆得干净一些。整个OHILEACH的Matlab仿真框架分四层:网络初始化层、每轮状态更新层、簇头优化层、数据采集与能耗统计层。
3.1 网络初始化与参数配置表
参数配置集中放在一个结构体里,方便批量仿真时改参数。我给出常用的基准配置:
| 参数 | 符号 | 取值 |
|---|---|---|
| 监测区域边长 | L | 100 m |
| 节点总数 | n | 100 |
| 基站坐标 | BS | (50, 150) |
| 初始能量 | E_initial | 0.5 J |
| 数据包大小 | packetLength | 4000 bit |
| 控制包大小 | controlPacketLength | 200 bit |
| 电路能耗 | E_elec | 50 nJ/bit |
| 自由空间功放 | ε_fs | 10 pJ/bit/m² |
| 多径功放 | ε_mp | 0.0013 pJ/bit/m⁴ |
| 数据聚合能耗 | E_DA | 5 nJ/bit/message |
节点坐标初始化我用均匀随机分布,也可以用聚类分布或者高斯分布来做对比实验。注意一个容易忽略的点:随机种子一定要固定,否则不同轮次的节点位置不同,实验结果不可复现,后面对比时你根本分不清性能差异是算法造成的还是随机误差造成的。
我习惯在仿真开头加一句:
matlab复制rng(42); % 固定随机种子,保证可复现
3.2 无线通信能耗模型:自由空间与多径衰落的切换逻辑
能耗模型是WSN仿真里最核心的一环,代码写错,后面全白搭。默认使用一阶无线通信模型:发送方要消耗电路能耗和数据发射能耗,接收方消耗电路能耗。关键是判断发射能耗用自由空间模型还是多径衰落模型,两者切换的临界距离d0 = sqrt(ε_fs / ε_mp)。
具体公式为:
- E_Tx(l, d) = l * E_elec + l * ε_fs * d²,当d < d0
- E_Tx(l, d) = l * E_elec + l * ε_mp * d⁴,当d ≥ d0
- E_Rx(l) = l * E_elec
注意d⁴增长非常快,所以仿真里凡是超过d0的通信,我们都会尽量通过多跳来避免。这也是为什么簇头到基站的距离一旦超过d0,协议会倾向于在簇头之间建立一条中继链,而不是直接长距离发送。很多人在Matlab里实现LEACH时偷懒,只写d²模型,导致基站距离远时能耗被严重低估,仿真结果和真实趋势对不上,这是个隐蔽的坑。
3.3 每轮建簇与稳定传输的实现流程
每一轮的仿真逻辑按顺序执行以下几步:
- 更新活节点列表,删除能量耗尽节点。
- 计算K、候选节点Score、调用启发式搜索得到本轮簇头集合。
- 非簇头节点扫描周围簇头,选择距离最近的簇头作为归属,加入该簇。
- 簇头接收成员数据,做数据聚合,然后发送给基站。
- 统计本轮总能耗、各类型节点数量,更新节点剩余能量。
- 判断是否达到终止条件(所有节点死亡或达到最大轮数),否则进入下一轮。
在Matlab里,我建议用for循环控制轮次,每轮里用向量化操作更新剩余能量。节点数量是100到500这个规模时,即使加上GA/PSO搜索,单轮耗时也就在0.1到0.5秒之间,跑完整生命周期大概五六百轮,总时间可以接受。如果节点超过1000,建议对距离矩阵做稀疏化处理,不然内存和耗时会爆炸。
3.4 数据聚合:簇头不是简单的转发,而是合并去重
数据聚合是LEACH系协议降低能耗的关键机制。簇内所有成员把感知数据发给簇头,簇头不是一条一条转发给基站,而是把内容合并成一个固定长度的数据包(通常等于一个完整数据包长度),再发给基站。这样全网每轮传递给基站的数据总量大概等于簇头数乘以单个聚合包长度,而不是全网节点数乘以单包长度。
聚合能耗E_DA = l * E_DA_per_bit,在代码里就是:
matlab复制% 簇头聚合后再发送,能耗计算
ETxAgg = packetLength * E_elec + packetLength * amp * d2BS;
% 其中d2BS根据距离与d0的关系选择fs或mp
聚合对总能耗的影响非常大,这也是为什么固定P的情况下,如果簇头数太少,簇内成员太多,簇头聚合压力大,能耗高;簇头数太多,簇头自己发送数据的能耗又叠加。存在一个最优簇头区间,启发式搜索找的就是这个区间内的组合。
4. 核心代码模块实现:簇头选举与启发式搜索的落地细节
代码层面的东西我只讲关键段落,不贴完整工程,否则篇幅太长也淹没重点。核心是三个模块:Score计算、PSO+GA搜索、能量更新。
4.1 Score矩阵计算与候选簇头筛选
候选簇头的Score计算,第一步是算出节点两两之间的距离矩阵。Matlab里用pdist2函数最快:
matlab复制% 计算节点间距离矩阵
distMatrix = pdist2(nodePositions, nodePositions);
% 通信半径内的邻居数
commRadius = 25; % 根据节点密度调整
neighborMatrix = distMatrix < commRadius;
neighborCount = sum(neighborMatrix, 2);
% 平均邻居距离
D_avg = sum(distMatrix .* neighborMatrix, 2) ./ max(neighborCount, 1);
这里neighborCount一定要用max(neighborCount, 1)防止除零,否则孤立节点的D_avg会变成NaN,Score计算全乱。
Score的计算代码:
matlab复制Score = w1 * (E_rem ./ E_avg) + w2 * (D_avg ./ D_ref) + w3 * (neighborCount ./ max(neighborCount));
注意Score中D_avg这一项,D_avg本身是越小越好(节点在邻居中位置适中),所以实际实现里要取倒数或者用1减去归一化值,具体看你定义的方向。我在公式里写的D_avg是高分为好,但代码里需要对应取反转。
matlab复制% D_avg越小越好,做反向归一化
D_score = 1 - min(D_avg ./ D_ref, 1);
Score = w1 * (E_rem ./ E_avg) + w2 * D_score + w3 * (neighborCount ./ max(neighborCount));
4.2 PSO粒子编码与适应度计算
PSO部分的粒子编码采用二进制向量,但Matlab里直接操作二进制向量加约束比较繁琐,我用的是连续值加阈值映射的方式:粒子位置是0到1之间的实数向量,大于0.5表示选中该节点当簇头,之后再用K修正层把簇头数量拉回期望值。
粒子数量一般设30到50,迭代次数设50到100。初次实验时我迭代了200次,发现从第60次开始适应度函数F的值基本不再下降,所以100次足够,再多只是增加计算时间。
PSO的速度和位置更新是标准公式:
matlab复制velocity = w * velocity + c1 * rand * (pbest - position) + c2 * rand * (gbest - position);
position = position + velocity;
关键细节:适应度函数F的计算要完整走一遍“把节点分配给簇头”的过程,这个过程耗时最长。我做的优化是预计算距离矩阵,后续每轮计算不同簇头组合时,直接查表,不再重复算节点间距离。这个优化让整个仿真速度提升了将近3倍。
适应度函数核心代码段:
matlab复制function fval = fitnessF(chosenClusterHeads, distMatrix, E_rem, packetLength)
% 节点分配给最近的簇头
[oldDist, assignment] = min(distMatrix(:, chosenClusterHeads), [], 2);
fval = 0;
for k = 1:length(chosenClusterHeads)
memberIdx = find(assignment == k);
% 计算簇内成员发送能耗与簇头聚合能耗
fval = fval + sum(calcTxEnergy(packetLength, distMatrix(memberIdx, chosenClusterHeads(k))));
end
% 簇头到基站的发送能耗
% 加上负载均衡惩罚项
end
4.3 GA精搜的交叉变异与合法性修正
GA部分的个体也是二进制向量,交叉采用单点交叉,变异采用随机反转一两位。变异概率我设0.05,太大的话会把收敛结果打散,太小则跳不出局部最优。
GA里最麻烦的是合法性修正。粗糙做法是:变异后检查簇头数是否等于K,不等于就随机加或减。好一点的做法是结合Score:需要加簇头时,优先加Score最高的非簇头节点;需要减簇头时,优先减Score最低的簇头。这样修正后的解不会因为随机加减而质量大降。
这个“合法化修正”步骤对GA的性能影响是决定性的。我早期测试时试过随机修正,进化曲线剧烈震荡,很难收敛;改成Score引导修正后,大概20代内就能收敛到稳定解。
4.4 每轮剩余能量更新与死亡节点判定
能量更新的核心代码:
matlab复制% 簇头消耗
E_rem(chIdx) = E_rem(chIdx) - E_aggregate - E_txToBS;
% 成员节点消耗
E_rem(memberIdx) = E_rem(memberIdx) - E_txToCH;
% 死亡判定
aliveIdx = find(E_rem > 0);
这里有个容易被忽略的点:节点能量等于0或者小于0都应判定为死亡,且死亡节点在本轮结束后要立即从活节点列表里移除,不能在下一轮还参与簇头选举。我见过同学的实现里,节点能量为负了还在当簇头,跑出来的生命周期曲线明显偏长,数据失真。
5. 实验数据对比:OHILEACH与LEACH、MODLEACH的差异分析
仿真跑完,数据要会分析。我用三组协议做了对比:原始LEACH、MODLEACH(基于能量的改进LEACH)、OHILEACH。网络参数统一为100节点、初始能量0.5J、基站坐标(50,150)。
5.1 网络生命周期的三个关键指标对比
衡量生命周期常用的三个指标:
- FND(First Node Dies):第一个节点死亡时的轮数,代表网络进入衰落的起始点。
- HND(Half Node Dies):一半节点死亡时的轮数,代表网络服务能力的断崖点。
- LND(Last Node Dies):最后一个节点死亡的轮数,代表网络的极限寿命。
我的实验结果是:
| 协议 | FND | HND | LND |
|---|---|---|---|
| LEACH | 135 | 278 | 410 |
| MODLEACH | 176 | 312 | 445 |
| OHILEACH | 223 | 367 | 502 |
FND从135提升到223,提升了65%,这个提升主要来自能量感知的簇头选举。LND提升幅度相对小,只有22%,原因是到网络后期,绝大多数节点能量都已严重不足,无论怎么优化选举,剩余能量总量就那么多,极限寿命不会因为选举策略发生质变。这提醒我们:协议改进最见效果的时间窗口是网络中前期,后期是能量总量主导,选举策略能做的非常有限。
5.2 总能耗与网络吞吐量的变化趋势
总能耗曲线我做了累计能耗对比:前200轮,LEACH累计能耗明显高于OHILEACH,两者差距在第150轮前后达到峰值,因为此时LEACH的死亡节点开始增多,剩余活节点要承担更多转发任务,单位数据能耗上升。OHILEACH因为从第80轮开始就自动下调K值,避免了大量低效簇头,累计能耗曲线更平缓。
吞吐量方面,OHILEACH在FND之前的总数据量比LEACH高约28%。原因很清晰:节点存活时间更长,数据采集的总轮数更多,虽然每轮因为簇头数量减少导致单轮数据量略降,但整体来看,多活90轮带来的收益远大于单轮数据量的损失。
5.3 不同基站位置下的鲁棒性表现
基站的位置对协议性能影响非常大,很多论文只测基站位于网络上方中心这一种场景,这不够。我额外测了基站位于(50,50)(网络中心)和(50,200)(远离网络)两种情况。
基站位于中心时,LEACH和OHILEACH的FND差距只有40轮左右,因为通信距离短,长距离能耗差异被弱化,协议改进的空间变小。基站位于(50,200)时,FND差距扩大到100轮以上,因为OHILEACH的K自适应机制会让簇头数量向基站一侧偏移,分布在远端的簇头数量减少,节省了大量长距离传输能耗。
这说明OHILEACH的优势在基站远离网络的应用场景中更加明显。如果你的仿真场景是基站放在角落或者很远的地方,OHILEACH的收益会显著放大。
6. 工程化实现中的细节坑与调参顺序建议
最后一部分是落地经验。我在复现和改代码过程中踩过不少坑,写出来希望读者少走弯路。
6.1 距离阈值d0对结果的影响
d0 = sqrt(ε_fs / ε_mp),代入基准参数后,d0大约在87.7m左右。在100m×100m的区域内,基站到大多数节点的距离都小于d0,所以多数通信用的是自由空间模型。但如果把网络区域扩大到200m×200m,或者把基站放在远离网络的位置,距离超过d0的概率大增,多径衰落模型开始主导,此时若不更新代码里的能量计算公式,仿真结果会严重偏乐观。
解决办法是写一个统一的发送能耗函数,每次调用时判断距离,而不是在某个模块里写死为d²或d⁴。
matlab复制function energy = calcTxEnergy(packetLength, dist, E_elec, eps_fs, eps_mp)
d0 = sqrt(eps_fs / eps_mp);
if dist < d0
energy = packetLength * E_elec + packetLength * eps_fs * dist^2;
else
energy = packetLength * E_elec + packetLength * eps_mp * dist^4;
end
end
6.2 自适应机制的震荡问题
K值的自适应计算公式里如果系数设置不当,会出现K值剧烈震荡:第50轮K=7,第51轮K=4,第52轮又变回6。震荡的根源是E_avg和n_alive在每轮跳变太大,导致K对它们的变化过于敏感。
处理方法是对K做指数平滑:
matlab复制K_smooth = 0.7 * K_calc + 0.3 * K_prev;
或者限制K的单轮变化幅度,比如最多比上一轮增减1。这个平滑措施在实践中很有效,网络生命周期比不做平滑长约10%左右。原理是稳定的簇头数量减少了节点在不同簇间的频繁切换,降低了控制消息的开销。
6.3 距离矩阵预计算与内存平衡
节点数在500以下时,预计算n×n距离矩阵完全可行。节点数到1000时,距离矩阵就要8MB(double类型),到2000时变成32MB,每轮还要基于这个矩阵算分配,时间空间都开始吃紧。
我的建议是节点数500以下直接预计算,500到1000使用稀疏矩阵,超过1000就要改成只预计算通信半径内的近邻关系,通信半径之外的节点之间直接视作“不可达”。这样能省掉90%以上的距离计算量。代价是半径设得太小可能找不到可用的簇头,所以要结合节点密度设定通信半径——我的经验是半径取网络边长的10%~15%,100m的区域内用15到25m比较合适。
6.4 调参顺序:先定场景,再定权重,最后调启发式参数
很多人拿到代码就急着调PSO的粒子数、迭代次数,这个顺序是错的。调参的正确路线是:
- 先固定网络场景:节点数、区域大小、基站位置、初始能量,这些定了才有比较基准。
- 再调目标函数里的权重w1、w2、w3和α、β、γ。这些决定了协议偏重省电还是偏重均衡还是偏重覆盖。先给一组默认权重跑出基线,再针对你的需求调整。我常用的起点是w=(0.5, 0.3, 0.2),α、β、γ=(0.4, 0.3, 0.3)。
- 最后才调启发式参数:粒子数、迭代次数、交叉变异概率。这些参数只要合理范围内,对最终结果影响不超过几个百分点。
- 每次只动一个参数,跑三组不同随机种子取平均,不要单次跑完就下结论。
6.5 一个提高仿真真实度的可选扩展:信道竞争损耗
标准能耗模型只考虑了发送、接收、聚合,没有考虑信道竞争和重传带来的额外损耗。如果你的论文要求更高,可以加一个信道损耗系数,在每次传输能耗上乘一个1.1到1.3的系数,模拟CSMA冲突导致的额外能耗。我实测加上这个系数后,所有协议的绝对寿命都会缩短,但协议间的相对优劣次序不变,所以它对结论影响不大,但让数据更贴近真实硬件表现。
最后分享一个我自己的小经验:做WSN协议对比实验,别只盯着FND一个指标。FND反映的是协议对弱节点的保护能力,LND反映的是对总能量的利用效率,两者经常此消彼长。一个协议如果FND特别好但LND特别差,说明它把所有能量都集中在少数节点上保证这些节点长寿,其他节点早死了;反过来,FND差但LND好,说明协议在牺牲小部分节点的前提下换取了整体寿命。OHILEACH的FND和LND都优于LEACH,说明它在“保护弱节点”和“整体能耗效率”两层都做了正向优化,这正是集成式设计相对单一改进方案的优势所在。你在自己的研究里做改进时,也建议同时关注这两个指标,避免顾此失彼。
