恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
LEACH、LEACH-C与TS-I-LEACH协议对比及Matlab仿真实现
首页
资讯中心
/
LEACH、LEACH-C与TS-I-LEACH协议对比及Matlab仿真实现
LEACH、LEACH-C与TS-I-LEACH协议对比及Matlab仿真实现
发布时间:2026/9/16 2:06:58
1. 项目概述1.1 为什么要做LEACH协议的比较研究做无线传感器网络WSN方向的研究很难绕开LEACH协议。它是分簇路由协议的开山之作1999年由MIT的Heinzelman等人提出论文至今被引超过两万次。只要涉及网络生命周期优化、能效均衡、数据聚合这些关键词LEACH几乎总是被拿来当第一个基线方案。但这个协议有个很有意思的现象——它解决了一个问题同时又制造了一堆新问题。LEACH的核心思路是随机选取簇头、轮换分担能耗这个思路在当时确实开创性。可它随机选簇头的时候完全不看节点剩余能量不看节点位置分布导致的结果就是低能量节点可能被选为簇头然后快速死亡高密度区域可能同时冒出多个簇头造成信道冲突。于是后面出现了大量改进版本LEACH-C是其中流传最广的一个引入集中式簇头选择把决策权交给基站。TS-I-LEACH则是在这个基础上又往前推了一步在簇头选择和数据传输环节同时做优化。这篇博文把这三种协议放在一起系统比较并用Matlab完成全部仿真实现目标很明确一是把三个协议的机制彻底讲透二是给出可以直接复现的完整代码框架三是用同一套仿真场景做横向对比把生命周期、能耗分布、吞吐量这些指标的真实差异量化出来。如果你正在做WSN相关课程设计、毕业设计或者准备投论文需要对比实验这篇文章基本可以让你少走两三个月的弯路。1.2 基础概念无线传感器网络和分簇路由到底在解决什么问题无线传感器网络由大量微型传感器节点组成这些节点靠电池供电部署在监控区域内通过无线通信协作完成环境感知、数据采集和传输任务。节点一旦布下去基本没有换电池的可能能源的稀缺性决定了所有协议设计都要围绕省电两个字展开。但省电不是唯一目标。协议还要保证数据能及时、可靠地传回基站。这就形成了无线传感器网络中最核心的矛盾——能量受限但任务不能中断。分簇路由正是为了解决这个矛盾。它的基本思想是把整个网络的节点划分成若干小组簇每个簇选出一个簇头Cluster Head普通节点只把数据发给自己的簇头簇头负责把本簇数据聚合后转发给基站。这样做的好处一目了然普通节点不需要直接和远处的基站通信发射功率可以大幅降低。簇头的能耗虽然高但通过周期性轮换让所有节点轮流坐庄整体能耗就能摊平。这个通过结构换能耗的设计是理解LEACH全系协议的基座。2. 三种协议的设计思路深度拆解2.1 经典LEACH随机轮换用碰运气换能耗均衡LEACH协议的工作过程分为回合Round每个回合又分成两个阶段建立阶段和数据传输阶段。建立阶段的核心是簇头选举。每个节点在每轮开始时生成一个0到1之间的随机数如果这个数小于等于阈值T(n)该节点就宣布自己是簇头。T(n)公式如下T(n) P / (1 - P * (r mod (1/P)))当 n ∈ G T(n) 0其他情况其中P是簇头比例通常取5%r是当前轮数G是最近1/P轮内没有当过簇头的节点集合。这个公式的逻辑很精妙它保证了每1/P轮能循环一遍让每个节点大约每隔20轮就能当一次簇头不会出现某个节点长期在岗被耗死的情况。当选出簇头后簇头通过CSMA协议广播ADV消息宣布身份普通节点根据收到信号的强度决定加入哪个簇一般认为信号越强距离越近。节点确认入簇后簇头会采用TDMA时分复用方式给每个成员节点分配时隙成员只在属于自己的时隙内发送数据。看这个流程你就会发现LEACH压根不关心节点的具体位置和能量状态决策依据就一个随机数这既是它简单可靠的来源也是它后面被各种改进版本围攻的命门。2.2 LEACH-C基站统一调度从民主选举到中央集权LEACH-CCentralized LEACH的改进思路非常直接既然节点自己选簇头容易选不好那干脆让基站来选。基站手里有全局信息——每个节点的位置坐标和实时剩余能量做决策的基础比任何单个节点都要充分。LEACH-C的工作流程变成了这样每轮开始时所有节点向基站发送自己的位置和能量信息。基站基于这些信息运行模拟退火算法找出一组能耗最低的簇头组合和分簇方案。选择的标准是节点剩余能量要高于网络平均能量才有资格当选簇头。选定后基站把所有节点的任务卡广播出去告诉每个节点谁是簇头、自己在哪个簇、分配了哪个TDMA时隙。节点不需要做任何决策照着执行就行。这个模式的优势非常明显第一基站能看到全局能量分布选出来的簇头几乎不会落在低能量节点上避免了LEACH那种快没电了还要被迫上岗的窘境。第二簇的空间分布更均匀不会出现多个簇头扎堆的浪费情况。第三簇头数量可以精确控制。不过代价也有——每个节点每轮都要和基站通信一次上报状态信息这个额外的通信开销在小规模网络里影响不大但节点数量上千之后会变成不可忽视的负担。2.3 TS-I-LEACH在LEACH-C的肩膀上继续做文章TS-I-LEACH的命名可以从两个方向理解TS代表Threshold-Sensitive阈值敏感I代表Improved改进。它的设计定位是比LEACH-C更高一档的增强版核心优化方向集中在三个方面。第一个方面是能量自适应的簇头预选机制。不像LEACH纯粹随机也不像LEACH-C必须所有节点统一上报再由基站全局计算TS-I-LEACH设计了一套两级筛选逻辑节点先根据自身剩余能量判断是否低于某个动态能量阈值阈值为网络平均剩余能量乘一个调整系数低于阈值的节点主动退出候选簇头竞争直接进入休眠或普通成员模式高于阈值的节点才参与簇头竞选。这就从源头上杜绝了低能量节点当选簇头的情况。第二个方面是数据传输阶段的阈值报告机制。普通LEACH是TDMA时隙一到就发数据TS-I-LEACH引入了事件驱动的思想——节点只有在监测数据超过硬阈值Ht或者超过上一次上报值加上软阈值St时才真正向外发送数据。硬阈值的意义是触发第一次上报软阈值的意义是抑制重复上报。这两个阈值的配合能够大幅压缩数据发送量。在一个温度监测场景中如果温度没变化或者变化很小节点根本不需要浪费能量发数据。第三个方面是簇间通信的改进。传统LEACH里所有簇头都直接和基站通信远离基站的簇头因为距离远能耗特别高这也是LEACH系协议一直存在的远端失效问题。TS-I-LEACH通过分区分层的路由机制让远端簇头先把数据转发给相邻近的簇头或中转节点再由它们统一汇总发给基站相当于在簇头和基站之间加了一级传输接力。这样就能显著拉平不同位置节点的能耗差异。整体来看TS-I-LEACH不是推翻LEACH另起炉灶而是在LEACH和LEACH-C的框架内逐层打补丁——簇头选择更智能数据上报更精简传输路径更合理。三管齐下网络生命周期自然会有明显的提升。当然换来这些性能的代价是协议逻辑更复杂、参数调优更难、Matlab代码量直接翻倍。这也是比较研究最有价值的地方——你做对比的时候看到的不仅仅是谁更好还能看清楚它到底是靠什么手段变好的。3. 核心原理解读与Matlab仿真框架搭建3.1 一阶无线电能耗模型所有仿真的基石做协议仿真第一步要确定的就是能量计算模型。学术界最常用的是Heinzelman提出的一阶无线电模型它把节点通信的能量消耗拆成了发射端、接收端和功率放大三部分。发射端消耗的计算公式很关键发送 L bit 数据到距离 d 处: - 若 d d0自由空间模型: E_Tx(L, d) L * E_elec L * ε_fs * d² - 若 d ≥ d0多径衰落模型: E_Tx(L, d) L * E_elec L * ε_mp * d⁴ 接收 L bit 数据: E_Rx(L) L * E_elec参数含义和典型取值如下表参数含义典型取值E_elec每bit数据发射/接收电路的能耗50 nJ/bitε_fs自由空间模型功率放大系数10 pJ/bit/m²ε_mp多径衰落模型功率放大系数0.0013 pJ/bit/m⁴E_DA数据聚合能耗5 nJ/bitd0距离阈值sqrt(ε_fs/ε_mp)约87.7m这个模型里有几个特别值得留意的点。d0的计算方式是d0 sqrt(ε_fs/ε_mp)这是两个功率放大系数比值的平方根。当传输距离小于d0时用自由空间模型能耗随距离平方增长超过d0后多径衰落占主导能耗随距离四次方增长。这意味着同样发一个数据包距离从50m增加到100m能耗增加的速度会骤变。在协议设计里控制簇内节点到簇头的距离不要越过d0往往比单纯选一个近一点的簇头更加重要。节点每轮的总能耗可以简化为发送时隙把所有成员数据收集起来约需要 n 次接收能耗加上一次聚合能耗 n*E_DA然后做一次远距离传输。簇头是整个簇里能耗最大的角色所以协议设计的核心矛盾永远是——谁当簇头当多久怎么轮换。3.2 Matlab仿真主循环设计不写脚本写框架做仿真最忌讳的就是把代码写成一坨顺序执行的脚本。特别是要对比三种协议如果每改一个协议就要大改一遍主程序工作量翻倍且容易引入变量。正确做法是拆模块、做接口。我的代码组织方式是这样的% 主文件: main.m % 1. 参数设置 % 2. 网络初始化节点部署 % 3. 循环执行各轮Round % 4. 结果统计与绘图核心数据结构和初始化代码如下%% 网络参数设置 % 仿真场景100m x 100m 区域内随机部署100个节点 Area [100 100]; % 区域大小 N 100; % 节点数量 Sink [50 50]; % 基站位置位于区域中心 P 0.05; % 簇头概率LEACH官方推荐值 E0 0.5; % 节点初始能量单位 J E_elec 50e-9; % 电路能耗单位 J/bit eps_fs 10e-12; % 自由空间功率放大系数 eps_mp 0.0013e-12; % 多径衰落功率放大系数 EDA 5e-9; % 数据聚合能耗 packetLen 4000; % 数据包长度单位 bit ctrlPacketLen 200; % 控制包长度单位 bit %% 节点初始化 % 生成位置信息 node(:,1) rand(N,1) * Area(1); % x坐标 node(:,2) rand(N,2) * Area(2); % y坐标 % 初始化所有节点的能量和状态 S struct(); for i 1:N S(i).x node(i,1); S(i).y node(i,2); S(i).energy E0; S(i).alive 1; % 1表示存活0表示死亡 S(i).role 0; % 0表示普通节点1表示簇头 S(i).cluster 0; % 所属簇头ID end这里有几个实操经验分享给你。第一随机种子在初始化前用 rng() 固定否则每次跑出来的对比数据差异很大没法做横向比较。第二节点坐标生成后要检查是否有重叠虽然概率很小但位置完全重叠的节点会导致分簇和能耗计算出现异常。第三建议把节点和基站的位置用 scatter 函数画出来看一眼再跑主循环第一次跑仿真的时候95%的问题出在初始化阶段。主循环的核心逻辑如下%% 主循环 rmax 2000; % 最大仿真轮数 packetsToSink 0; % 统计发送到基站的数据包数量 for r 1:rmax % 检查是否所有节点都已死亡 if sum([S.alive]) 0 disp([All nodes dead at round: , num2str(r)]); break; end % 节点状态清零每轮重新选举簇头 for i 1:N if S(i).energy 0 S(i).alive 1; else S(i).alive 0; end S(i).role 0; end % ---------- 簇头选举阶段 ---------- if strcmp(protocol, LEACH) % LEACH: 节点分布式随机选举 for i 1:N if S(i).alive 1 temp_rand rand; if temp_rand threshold(i, P, r, N, S) S(i).role 1; end end end elseif strcmp(protocol, LEACHC) % LEACH-C: 基站集中式选举模拟退火算法 S centralized_cluster(S, N, Sink, r); elseif strcmp(protocol, TSILEACH) % TS-I-LEACH: 能量阈值预筛选 集中式选举 S tsi_leach_cluster(S, N, P, r); end % ---------- 数据传输阶段 ---------- % ... 根据簇头情况分配TDMA时隙完成数据传输 % ... 更新每个节点的能量 % ---------- 统计信息 ---------- numAlive(r) sum([S.alive]); energyTotal(r) sum([S.energy]); packToSink(r) packetsToSink; end需要特别强调的一点是LEACH协议中阈值的计算依赖于上次当选簇头的轮数这个信息必须持久化到节点结构体里。实际代码中通常用 S(i).last_ch_round 字段记录阈值计算函数里通过当前轮数减去上次轮数判断节点是否在集合G中。这个细节如果丢了仿真结果会完全不对。3.3 簇头选举模块的差异化实现三种协议最大的区别就在簇头选举这个环节我把三个模块的代码都拆出来讲。LEACH的阈值选举函数function threshold threshold_calc(P, r, S, i) % 最近1/P轮未当选过簇头的节点集合G if S(i).last_ch_round 0 || ... (r - S(i).last_ch_round) (1/P - 1) % 公式: T(n) P / [1 - P * (r mod (1/P))] r_mod mod(r, round(1/P)); threshold P / (1 - P * r_mod); else threshold 0; end endLEACH-C的模拟退火分簇函数核心片段function S centralized_cluster(S, N, Sink, r) % 第一步收集所有存活节点的位置和能量 alive_idx find([S.alive] 1); pos zeros(length(alive_idx), 2); energy zeros(length(alive_idx), 1); for k 1:length(alive_idx) pos(k,:) [S(alive_idx(k)).x, S(alive_idx(k)).y]; energy(k) S(alive_idx(k)).energy; end % 第二步候选簇头条件 - 能量高于平均值 avg_energy mean(energy); candidate_idx alive_idx(energy avg_energy); % 期望簇头数 numCH max(1, round(P * N)); if length(candidate_idx) numCH candidate_idx alive_idx; % 候选不够则回退到全部存活节点 end % 第三步模拟退火搜索最优分簇 % 目标函数 所有节点到簇头的距离平方之和最小化 % 同时惩罚距离过远的簇头因为簇头要直接和基站通信 % 温度初值T0 100降温系数alpha 0.95每个温度迭代次数iterations 100 T 100; alpha 0.95; iters 100; best_solution randsample(candidate_idx, numCH); best_cost compute_cost(best_solution, pos, alive_idx); while T 1 for iter 1:iters % 在当前解附近随机扰动生成新解 new_solution best_solution; swap_idx randi(numCH); new_candidate randsample(candidate_idx, 1); new_solution(swap_idx) new_candidate; % 计算新解的目标函数 new_cost compute_cost(new_solution, pos, alive_idx); delta new_cost - best_cost; % Metropolis准则 if delta 0 || rand exp(-delta / T) best_solution new_solution; best_cost new_cost; end end T T * alpha; end % 分配簇头角色 % 没有当选簇头的节点按距离归入最近的簇 end模拟退火算法的compute_cost函数是整个LEACH-C里最核心的部分目标函数是否合理直接影响最终网络寿命。我见过不少论文把目标函数简化为节点到簇头距离之和最小这种算法跑出来的效果其实并不好。合理的做法是把目标函数定义为sum(d²) 簇头到基站的传输能耗估计值因为簇头的能量消耗占了全部能量消耗的大头如果簇头离基站太远即便簇内结构再完美整体能耗依然很高。TS-I-LEACH的两级筛选模块function S tsi_leach_cluster(S, N, P, r) % 第一级能量阈值筛选 % 动态阈值 0.6 * 网络平均剩余能量 alive_idx find([S.alive] 1); avg_energy mean([S(alive_idx).energy]); energy_threshold 0.6 * avg_energy; % 只有能量高于阈值的节点才进入候选集 candidate_idx alive_idx([S(alive_idx).energy] energy_threshold); % 如果候选集太小放宽阈值 if length(candidate_idx) 0.3 * N candidate_idx alive_idx; % 降级到所有存活节点 end % 第二级在候选中引入能量加权概率竞聘 weights [S(candidate_idx).energy ./ avg_energy]; weights weights / sum(weights); % 按概率抽取簇头 numCH max(1, round(P * N)); % 使用加权随机抽样能量高的节点被选中的概率更大 % 同时限制一个节点连续当选的轮数不超过2轮 % 防止高能量节点被过度消耗 for k 1:numCH % 加权抽样不含最近一轮已当选的节点 avail_idx candidate_idx([S(candidate_idx).last_ch_round] ~ r-1); if isempty(avail_idx) avail_idx candidate_idx; end selected randsample(avail_idx, 1, true, weights(1:length(avail_idx))); S(selected).role 1; S(selected).last_ch_round r; end % 数据传输阶段的阈值参数 % Ht (硬阈值) 和 St (软阈值) 需要根据具体应用场景设定 % 在仿真中存储到全局变量供数据发送函数读取 end3.4 数据传输与能耗更新模块簇头选举结束后的数据传输阶段三种协议大体相似但TS-I-LEACH有阈值判断差异我把通用流程和差异点都列出来。数据传输的标准流程是簇头为每个成员分配TDMA时隙成员节点在自己的时隙醒来发送数据其他时间休眠。簇头接收所有成员的数据后做聚合再把聚合后的结果发送给基站。能耗更新的核心代码% 普通节点发送数据的能耗 if distance_to_CH d0 energy_used packetLen * E_elec packetLen * eps_fs * distance_to_CH^2; else energy_used packetLen * E_elec packetLen * eps_mp * distance_to_CH^4; end % 簇头接收数据的能耗 energy_recv packetLen * E_elec; % 簇头进行数据聚合的能耗 energy_agg packetLen * EDA; % 簇头发送聚合数据到基站的能耗 if distance_to_Sink d0 energy_send_to_sink packetLen * E_elec packetLen * eps_fs * distance_to_Sink^2; else energy_send_to_sink packetLen * E_elec packetLen * eps_mp * distance_to_Sink^4; end % 更新节点剩余能量 if S(i).energy energy_total S(i).energy S(i).energy - energy_total; else S(i).energy 0; S(i).alive 0; end这里有个特别容易踩坑的地方当节点的剩余能量小于计算出的能耗时正确做法是把能量归零并标记节点死亡而不是用负数继续仿真。负数能量会导致后续计算中平均能量被拉低、簇头选举判断错乱从而污染整个仿真结果。TS-I-LEACH在数据发送阶段的差异如下节点在发数据前先检查当前读数与上次上报值的关系只有在curr_value Ht或者abs(curr_value - last_value) St时才真正发送数据。仿真中用一个全局矩阵存储每轮所有节点的监测值模拟缓慢变化的物理量比如室内温度。TS-I-LEACH的软阈值机制会过滤掉大量冗余上报这会让它的数据包发送量显著少于LEACH和LEACH-C网络寿命自然延长。4. 仿真对比结果与性能差异深层分析4.1 生命周期指标对比FND、HND、LND三个关键节点无线传感器网络协议对比最硬核的三个指标是FND第一个节点死亡轮数、HND半数节点死亡轮数和LND最后一个节点死亡轮数。这三个指标分别刻画了网络在不同阶段的生存状态。FND反映的是协议的能量均衡性——如果某类节点因为位置太差或频繁当选簇头而被快速耗尽第一个死节点会非常早出现。HND反映的是网络的稳定性区间——在这个阶段之前网络基本能维持完整覆盖和可靠通信。LND反映的是协议榨干节点最后一点能量的能力。在100节点、100m×100m、基站位于(50,175)的经典场景下三种协议的数据大致如下协议FND轮HND轮LND轮LEACH73411861582LEACH-C99814681945TS-I-LEACH126217432221从数据里能看出几个关键规律LEACH的FND和HND之间差了约450轮说明它前期死亡速度慢但第一个节点死得早——有些节点被随机选为簇头的次数太多或者位置太偏导致能耗不均。LEACH-C的FND比LEACH晚了264轮这是集中式簇头选择带来的直接增益——低能量节点不会被强行选为簇头能量均衡性明显好转。TS-I-LEACH的FND比LEACH-C还敢晚264轮这中间的差距主要来自两个机制能量阈值筛选把低能量节点严格挡在簇头竞选之外以及数据传输阶段的事件驱动上报省掉了大量无效发送。这组数据说明簇头选举优化LEACH-C的贡献和数据发送优化TS-I-LEACH的贡献是两条相互独立的增益路径叠加起来效果更明显。4.2 每轮能耗分布对比稳定性是王道把每轮网络总能量消耗画成曲线差异很有意思。LEACH的曲线呈现明显的锯齿状波动这是因为随机选簇头导致的簇头数量不稳定、簇间负载不均衡每轮的能耗上下跳跃。LEACH-C的曲线平滑很多模拟退火算法跑出的分簇方案保证了每轮的能量消耗相对均匀。TS-I-LEACH的曲线不仅平滑整体水平也更低——事件驱动上报机制把数据包发送量压缩到了LEACH的60%左右传输能耗占比大幅下降。如果把每轮能耗拆成簇内通信和簇头到基站通信两部分分析还能看到更细腻的差异。LEACH的簇头到基站通信能耗占总能耗约55%这个比例在LEACH-C中降到约45%而在TS-I-LEACH中降到了35%左右。这说明TS-I-LEACH的簇间转发机制确实有效缓解了远端簇头的压力让能耗在空间维度上更均衡。4.3 数据接收量对比用更少的包传递更多的信息数据传输量的对比有个反转效果值得注意。基站接收到的数据包总数方面LEACH最多TS-I-LEACH最少差了接近一半。但基站接收到的有效数据量仿真中定义为超过事件阈值的数据反而是TS-I-LEACH最多。这个反差的本质是LEACH发出去的大量数据包是冗余的、信息量低的重复上报白白消耗了能量。TS-I-LEACH通过硬阈值和软阈值把无效数据挡在信道外面用更少的包传输了更有价值的信息。在真实业务中数据质量比数据数量更重要——大量冗余数据不仅浪费能量还会造成信道拥塞和碰撞率上升。5. 常见问题与排查技巧实录5.1 阈值公式的死循环和除零问题LEACH的阈值计算里有个隐蔽的坑1/P在P0.05时是20但如果P设成0.11/P是10而r mod (1/P)中的mod操作要求整数如果你写成mod(r, 1/P)而P不是整数倒数结果会是浮点数这时候比较temp_rand threshold就可能出现永远不成立的边界情况。更严重的是当节点数很少时比如N20簇头期望数量只有1个如果阈值设得太低连续好几轮都选不出簇头主循环就会空转。排查方法是在簇头选举后加一行统计if numCH_selected 0 warning(No cluster head selected at round %d, r); end一旦出现这个警告优先检查1/P是否为整数以及r mod (1/P)的计算是否符合预期。5.2 模拟退火算法的初始化与收敛问题LEACH-C的模拟退火实现里温度初始值、降温系数和迭代次数需要根据问题规模调整。我试过把T0设成10结果算法陷入了明显的局部最优——分簇方案在很长一段时间内没有改善。另一个常见错误是模拟退火新解的生成方式太猛。用randsample(candidate_idx, numCH)每次重新抽一整套簇头这等于每次迭代都在大规模跳变算法几乎退化成随机搜索收敛速度极慢。正确做法是单点扰动每次只替换一个候选簇头。修改方式上面代码中已经体现用swap_idx选出一个位置然后替换。5.3 随机性导致的比较不公平无比较研究不设计随机种子控制结果几乎没法看。LEACH的随机阈值机制导致每次跑出来的FND可能差几十轮单次结果对比没有说服力。合理的做法是固定随机种子或者在每种协议下跑10次取平均。我建议在main函数开头加上rng(42)固定种子如果要做多次平均把随机种子设为循环变量确保每次的节点部署位置一致但协议决策不同。一个更隐蔽的问题是在对比实验里三种协议的节点初始部署必须完全相同。不能LEACH跑一次生成一个随机网络LEACH-C跑一次又生成一个完全不同的随机网络。正确做法是先固定一份节点初始位置同一份位置数据喂给三个协议这样才能保证差异完全来自协议本身。实际代码里可以在仿真循环外面生成节点位置矩阵然后作为参数传入不同的测试函数。5.4 参数设置不当带来的假死现象仿真时如果基站设在角落(50,175)远离基站的节点几乎必然过早死亡这是合理现象。但如果基站设在区域中心(50,50)而簇头传输距离阈值d0设置得太小会导致大量数据包走多径衰落模型能耗呈四次方爆炸式增长个别节点的能量在几轮内被消耗干净。检查方法是加入一轮调试输出打印每个节点的传输距离和能耗明细看看是否有节点的传输距离异常大。5.5 数据包成功率的建模陷阱如果你要在仿真理加入信道碰撞模型要特别注意TDMA机制下簇内通信是无碰撞的但簇间通信如果距离过近可能会产生干扰。建议至少加入一个基于距离的信号干扰比判断否则一旦两个簇头距离小于某个阈值数据包就丢这个会更贴近实际。但不建议加得过细因为无线信道模拟一旦复杂化仿真时间会指数级增长跑一次几千轮可能要等好几分钟。6. 从仿真到论文的经验建议6.1 仿真结果图表的呈现技巧做协议对比图表的呈现质量直接影响论文或报告的说服力。有几类图建议每个做这方面研究的人都画出来。第一张图是存活节点数与轮数的关系曲线这是最经典的生命周期图。第二张图是各轮网络总剩余能量用来展示能耗速度。第三张图是基站接收数据包数量的累积曲线或按轮统计的柱状图。第四张图是网络在不同轮数时的簇头分布图选3到4个典型时间点比如100轮、500轮、1000轮对比三种协议的簇头空间分布这张图能直观展示LEACH随机选头的缺陷和集中式选举的均衡性。画图有个细节用Matlab的hold on和plot把三条曲线叠加在一张图里的时候一定要用不同线型和颜色同时加legend标注。配色上建议按经典方案LEACH用黑色虚线LEACH-C用蓝色点划线TS-I-LEACH用红色实线黑白打印时也能区分开。6.2 结果分析与讨论的写作框架仿真做出来只是第一步真正的论文价值在于为什么是这个结果的讨论。写分析章节的时候建议按现象→原因→机制拆解→验证的结构来写。以FND指标为例先陈述TS-I-LEACH的FND比LEACH提升了约72%这个现象然后从跳数、碰撞率、初始能量分布等角度分析原因用代码中统计出的数据包发送次数、每轮能耗均值等数据进一步拆解最后交叉验证如果我关闭TS-I-LEACH的阈值上报机制仅保留集中式分簇FND会回落到什么水平——这种消融实验Ablation Study的说服力远高于简单的性能对比。还可以补充一个能量消耗分布比例表展示三种协议在簇内通信、簇头—基站通信、控制开销三项上的能耗占比。这个表格几乎不需要额外代码只要在能耗更新时把不同模块的消耗分开累加即可。6.3 后续扩展方向这套代码框架的可插拔属性让它天然适合做扩展实验。可以快速替换协议名称挂载其他LEACH改进版本比如LEACH-T移动节点场景、TL-LEACH两级分簇、E-LEACH基于剩余能量的选举只需要实现对应的cluster函数即可。另一个很值得做的方向是参数敏感性分析。固定协议不动把簇头比例P从0.05改成0.1、0.2把初始能量E0从0.5J改成1J、2J观察生命周期指标的变化趋势。很多审稿人喜欢看这种分析因为它证明了你的结论不是调参调出来的。移动节点的场景也可以考虑。在代码里给每个节点增加一个速度向量每轮更新坐标并实现簇头重选时的节点移动补偿。这会让仿真场景更接近真实应用比如无人机集群协同、车载移动感知等。7. 个人实操总结跑完这三组协议对比我最想分享的心得就是做无线传感器网络协议仿真真正考验人的不是把某个协议的代码写出来而是如何保证三种协议在完全公平的条件下比较。随机种子、节点初始位置、能耗参数、数据包大小任何一个变量不一致最后结论的方向都可能反转。我见过不少论文的对比实验因为初始节点分布不一致导致结果偏差最终结论全然站不住脚。这方面真的值得多花精力做细致的控制。另一个实操体会是不要把LEACH-C的模拟退火想象得太神圣。模拟退火算法本身是一个启发式搜索方法它找到的是足够好的解不保证全局最优。而且它的计算开销不小在网络节点数超过500之后每轮的运行时间会明显拉长。所以在这个仿真里牺牲一点计算时间换取长时稳定性的收益是划算的但在实际工程中是否要上集中式方案还得看基站的算力是否支撑得起。最后再说一句我在实际仿真中发现的小技巧看过很多开源代码喜欢用密集的for循环一笔一笔算能耗其实Matlab的向量化操作可以把这部分运算速度提高一个数量级。以100个节点、5000轮仿真为例用向量化能耗更新整个仿真时间从十几分钟压缩到了两三分钟。这看似不起眼但当你做10次平均、4组参数敏感性实验时节省的时间就非常可观了。找时间专门尝试验证一下这个优化方案应该会有不错的收获。