做物理层安全仿真这几年我越来越觉得一件事很反直觉把节点当成理想收发机来做多跳WSN无线传感器网络仿真往往得出来的结论搬到真实硬件上会走样得很厉害。标题里这个场景我前前后后复现过很多次——源节点到汇聚节点之间隔着好几个中继旁边蹲着一个被动窃听者节点硬件又带着非线性、相位噪声这类实际损伤这时路径选择就不是挑一条信噪比最高的路那么简单了。这篇我直接把建模思路、路径选择准则、Matlab实现框架和仿真里容易翻车的细节一一拆开讲适合正在做WSN路由、物理层安全或者保密通信仿真的同学参考。先交代一下我理解的系统边界这是一个典型的多跳收集-传输模型感知数据从传感器节点出发经过若干候选中继的逐跳转发到达sink节点。窃听者不在协作链路上它只负责偷听被发射出来的信号。硬件噪声在这里不是简单的背景热噪声而是收发机损伤带来的乘性畸变它会跟着信号一起放大导致链路容量的天花板效应。下面我从场景建模开始一步一步把整个仿真骨架搭起来。1. 多跳收集-传输场景里的核心要素和性能度量1.1 网络拓扑和收集-传输的实际含义收集-传输两个字拆开理解收集是从散布的传感器节点往汇聚节点汇聚数据典型的多对一流量传输则是数据从某个源节点到达sink要经过中继接力。我在Matlab里通常这么设计节点分布源节点放在区域的左下角sink放在右上角候选中继在中间区域随机撒点窃听者摆在主链路附近的一个侧翼位置。节点总数规模建议控制在10到30个之间这个规模既能让路径组合足够丰富又不会让穷举路径的复杂度把模拟器拖死。实际做的时候我还会区分两种情况一种是所有节点角色固定只有一条源-destination对中继是纯转发节点另一种是每个传感器都有可能成为源节点同一份数据要汇聚到sink。第一种情况用来做路径选择算法的基准测试比较容易第二种更接近真实WSN的收集场景但仿真里要额外处理多流竞争和干扰。我下面的实现默认先做单源单汇的情况把问题聚焦在路径选择如何影响保密性能上之后再扩展多流也不难。1.2 为什么不能只看可靠性和时延传统路由优化喜欢拿端到端信噪比、中断概率、时延、能耗当目标函数。但在存在窃听者的WSN里可靠性再高如果保密速率是零这条路径在安全视角下依然不可用。比如一条经过高信噪比中继的路径主链路质量很好可恰好每个中继发射的信号都被窃听者以很高的质量收了下来那主链路这端的可靠性和窃听端的偷听质量是同时增长的。这个场景最有意思的点在于路径选择的目标函数从让信号更强变成了让主链路和窃听链路的差距更大。这是完全不同的优化方向所以最大SINR路径或者最少跳数路径在安全约束下可能不是最优的这是我反复复现这个题目之后感受最深的一点。1.3 性能指标怎么选我仿真时主要盯三个指标端到端保密速率 C_s [log2((1 gamma_D) / (1 gamma_E))] 其中gamma_D是目的节点处的聚合SINRgamma_E是窃听者处的等效窃听SINR。保密中断概率 SOP Pr{C_s R_th}就是保密速率跌到目标阈值以下的概率。平均安全吞吐量定义为(1 - SOP) * R_th用来表征单位带宽上实际能安全传多少个bit。SOP在单次信道实现下意义不大它必须靠蒙特卡洛统计所以仿真框架里最外层一定是一个循环次数足够多的信道快照循环。提示如果你第一次跑这类仿真建议先把SOP结果和纯理论场景比如单跳、无硬件损伤、无窃听者对比一下确认实现没有低级错误再往多跳和硬件噪声上叠加复杂度。我习惯用一个退化基线去验证代码不然定位问题时会非常痛苦。2. 硬件噪声建模别再把非理想收发机当背景噪声2.1 硬件损伤的真实来源很多初始仿真把一切噪声都简化成加性高斯白噪声但真实收发链路里至少有几类与信号功率强相关的损伤振荡器相位噪声导致符号星座图旋转信噪比越高、阶数越高的调制对相位噪声越敏感。功率放大器非线性工作在饱和区附近会产生AM-AM和AM-PM失真。I/Q不平衡零中频接收机里的镜像信号泄漏。DAC/ADC量化误差采样精度不够时引入的基底噪声。这些损伤的共同特点是乘性它们的功率正比于信号功率而不是固定不变的热噪声功率。我最初做全理想模型仿真时提高发射功率就能线性地改善中断性能后来把硬件损伤加进去发现增大功率到一定值之后保密中断概率怎么都降不下去这才意识到必须把损伤项单独建模。2.2 常用失真噪声模型与SINR表达式目前文献里最常用的收发机损伤模型是把自己硬件产生的畸变叠加在理想信号上y sqrt(P) * h * (s eta_t) eta_r n其中eta_t是发射端畸变方差为 kappa_t^2 * Peta_r是接收端畸变方差为 kappa_r^2 * P * |h|^2n是背景热噪声方差为N0。kappa_t和kappa_r是表征收发机硬件质量的参数通常取0.01到0.1之间。这样一条单跳链路的等效SINR就变成gamma P * |h|^2 / (kappa_t^2 * P * |h|^2 kappa_r^2 * P * |h|^2 N0)当收发机对称、kappa_t kappa_r kappa时式子化简成gamma 1 / (2 * kappa^2 1 / (P * |h|^2 / N0))从这里能直接看到一个重要结论当P*|h|^2/N0趋向无穷大时gamma不会趋向无穷大而是趋向 1/(2*kappa^2)。这意味着硬件损伤给每条链路设置了一个SINR天花板。这个天花板对路径选择的影响非常大——如果某条路径经过一个kappa比较大的中继哪怕信道条件再好端到端性能都会被这个节点牢牢卡住。2.3 多跳场景下损伤是逐跳累积的多跳系统里硬件损伤不像背景热噪声那样独立分布在每一跳而是会被中继的放大/转发过程继续携带。尤其放大转发AF模式下前级节点的硬件畸变会被后级节点放大端到端失真会明显累加。解码转发DF模式下每跳重新编码畸变不会完全跨跳传递但每跳自身仍会引入新的硬件噪声。我在仿真里为了实现简单主链路用DF端到端等效SINR采用各跳SINR的调和平均近似或者更保守地用逐跳SINR的最小值。两种聚合方法都可以解释为不同的空间复用/合并策略但结论趋势不会本质反转只是数值上的保守与乐观差异。这也是仿真实操中必须记录清楚的地方否则复现出来的结果会和你的不一致。3. 路径选择方法的设计从最强信号转向最大安全差距3.1 窃听模型的建立要设计路径选择准则先得知道窃听者是怎么合并信号的。窃听者在每个源或中继发射时都能收到一份被监听的信号理论上如果它能做到完美相位对齐和最大比合并那么窃听端的等效SINR是所有被监听节点的信号功率之和。这种假设对窃听者来说过于强大但适合做保守性能分析。还有一种情况是窃听者只选其中信号最强的一跳来监听那相当于选择合并gamma_E是各跳窃听信噪比的最大值。我在实现里把两种合并方式都做成了配置项跑对比实验很方便。默认用MRC合并因为它给出了安全性能的下界也就是最保守的场景而且代码实现上只是对窃听信噪比向量求和一行代码的事情。3.2 候选路径选择准则面对路径选择问题时我对比过几类准则准则A最大最小逐跳SINR完全不考虑窃听者。这是传统路由的思路容易出现信号很好但也很容易被偷听的问题。准则B最大化端到端保密速率需要知道主链路CSI和窃听链路CSI。这是全局最优意义上的准则适合做理论基准。准则C最小化SOP的准则通过对链路衰落统计量的近似得到权重对瞬时CSI的依赖较弱更适合实际分布式的部署。准则D跳数惩罚与保密裕量的加权组合在保密性能和网络开销之间做折中。我推荐先用准则B作为基准因为它物理意义最明确Matlab里计算也简单。准则B选出来的路径不一定跳数最少可能还会故意绕开离窃听者太近的中继节点这个现象本身就很能说明问题。3.3 路径搜索的复杂度和实现方式中继数量在20个以内时全路径枚举是可行的到了30个以上就明显变慢。我通常把链路权重设置成保密速率相关的负值然后跑Dijkstra最短路。这里有个关键点保密速率取对数后是信道乘积的叠加形式并不严格满足最短路问题的非负权重前提所以如果要用Dijkstra需要对权重做一次平移或使用Bellman-Ford。我用更简单的做法限定最大跳数之后做深度优先搜索配合记忆化剪枝实测下来20个中继节点、最大4跳时运行速度完全可接受。3.4 CSI获取的开销假设仿真里最容易被诟病的地方是假设所有CSI都已知现实中获取窃听者的CSI几乎是不可能的。稳妥的做法是额外跑一个部分CSI版本即只知道主链路CSI窃听端用统计模型来估计。不同假设下路径选择的结果会有差异你的论文或博客里必须明确写出用的是哪套假设这样读者才可能复现你的对比图。注意很多保密路由研究一边假设窃听者位置和CSI未知一边又用需要精确知道窃听CSI的准则来选择路径这是矛盾的。如果走工程路线我更建议采用准则C的统计量近似或者把窃听者的位置做不确定性建模观察路径选择算法的鲁棒性。4. Matlab代码实现信道、链路SINR与路径扫描4.1 代码框架总览整个仿真程序我按下面的模块来组织参数初始化节点坐标、发射功率、路径损耗指数、硬件损伤参数kappa、阈值速率R_th、蒙特卡洛次数。信道生成瑞利衰落系数乘以路径损耗系数生成所有链路的主信道和窃听信道。链路SINR计算对每一条有向边计算考虑了硬件损伤之后的等效SINR。路径搜索根据选择准则在候选路径集合里选出最优路径。统计循环对大量信道快照重复上述过程统计SOP和安全吞吐量。模块划分的意义在于路径选择准则和信道模型解耦换一个准则只用改模块4不用动信道生成部分。4.2 核心函数一链路SINR计算这是一个最底层的函数输入发射功率P、信道系数h、噪声功率N0以及kappa_t和kappa_rfunction gamma linkSINR(P, h, N0, kappa_t, kappa_r) signal P * abs(h)^2; txDist kappa_t^2 * P * abs(h)^2; rxDist kappa_r^2 * P * abs(h)^2; gamma signal / (txDist rxDist N0); end这个函数看起来很短但最容易出错的地方是功率单位不统一。我建议所有功率量纲都统一到线性值瓦特或者毫瓦都行不要在函数内部做dB和线性值的反复切换。kappa如果从dB形式换算过来要在初始化阶段完成不能拿到函数里现算否则很容易漏掉平方项。4.3 核心函数二路径保密速率计算一条路径本质上是一个中继序列。对DF模式主链路SINR我用调和平均近似窃听端在MRC合并下就是各被监听节点的窃听SINR之和function Cs pathSecrecyRate(relayIdx, hMainPerHop, hEvePerHop, ... P, N0, kappa_t, kappa_r) gammaMainPerHop zeros(1, length(relayIdx) 1); gammaEvePerHop zeros(1, length(relayIdx) 1); % 每条发射链路源到第一跳中继、中继之间、最后一跳到目的的主信道SINR for i 1:length(gammaMainPerHop) gammaMainPerHop(i) linkSINR(P, hMainPerHop(i), N0, kappa_t, kappa_r); gammaEvePerHop(i) linkSINR(P, hEvePerHop(i), N0, kappa_t, kappa_r); end gammaD 1 / mean(1 ./ gammaMainPerHop); % 调和平均 gammaE sum(gammaEvePerHop); % MRC合并 Cs max(log2((1 gammaD) / (1 gammaE)), 0); end如果你更想保守一点直接把gammaD min(gammaMainPerHop) 也是一行代码的事。我自己跑仿真时会同时保存这两种聚合方式的结果方便在分析时讨论差异。窃听链路的hEvePerHop是从每个发射节点到窃听者的信道系数和主链路的hMainPerHop是两套独立的随机变量。4.4 蒙特卡洛主循环外层循环负责生成信道快照和统计Nmc 1e5; sopCount 0; for mc 1:Nmc % 生成所有链路的信道系数注意区分主信道和窃听信道 [hMain, hEve] generateChannels(nodePos, pathLossExp); % 枚举或搜索得到最优路径 bestPath pathSearch(hMain, hEve, P, N0, kappa_t, kappa_r); % 计算该路径的保密速率并统计SOP Cs pathSecrecyRate(bestPath, hMain, hEve, P, N0, kappa_t, kappa_r); if Cs R_th sopCount sopCount 1; end end sop sopCount / Nmc;需要提醒的一点是主循环里每轮信道快照都要重新跑路径搜索所以复杂度是蒙特卡洛次数乘以单轮搜索复杂度。为了提升速度我往往把不同参数的对比实验放在同一个大循环里完成而不是每个参数设置单独跑一遍。比如同一套信道快照下同时比较准则A、B、C的结果这样不同准则的差异不会被随机信道噪声淹没。4.5 默认参数配置参考参数推荐值说明节点总数15~25中继数量太多会显著增加路径搜索耗时路径损耗指数3~4视场景密集程度而定开阔场景取小值发射功率P10 mW 到 100 mW线性值统一为W噪声功率N0-90 dBm对应带宽和噪声系数kappa_t kappa_r0.01 到 0.10代表理想硬件作为对照基线目标保密速率R_th1 bit/s/Hz也可以取0.5或2看你想关注的工况蒙特卡洛次数10^5 起步分析低SOP区域时需要更多次数5. 仿真结果里最容易看到的几个现象和它们的物理解释5.1 硬件损伤导致SOP平台效应把kappa从0调到0.05扫描发射功率从0 dBm做到30 dBmSOP曲线会呈现一个明显的先下降后进入平台的形态。原因就是第2节讲的SINR天花板当热噪声被压制得足够低之后硬件畸变噪声成为主导增加功率只会同时放大信号和失真SINR不再提升保密速率自然也就上不去了。对这个现象的解读不要停留在硬件损伤有害这种层面。更实际的意义是在硬件条件有限的传感器节点上盲目的功率优化收效甚微应该把资源放到路径选择、节点筛选或者减少跳数上。很多论文里优化功率的结论在理想模型下成立但加入硬件损伤后弹性很有限这个仿真现象可以当作一个很好的讨论点。5.2 最大SINR路径不等于最佳保密路径同样的信道快照下我跑过三套选择准则最短路径、最大SINR路径、最大保密速率路径。结果经常出现最大SINR路径比最大保密速率路径的保密速率低不少原因是最大SINR路径上的中继可能正好分布在窃听者附近主链路信号强被窃听的信号也强。这点在结果图上表现得很直观也解释了为什么这个题目需要专门的路径选择方法不能直接拿经典路由协议套用。5.3 跳数的双刃剑效应多跳在传统认知里是降低单跳距离、减小路径损耗的好东西但在安全视角下多跳意味着更多的发射节点暴露给窃听者、更多的硬件损伤节点参与协作、更大的端到端时延。跳数太少可能导致单跳距离过长、链路SINR过低跳数太多则累积失真和窃听风险上升。路径搜索算法实际上就是在自动寻找这个平衡点。我统计过最优路径的平均跳数随kappa变化的趋势kappa增大的时候最优路径倾向于使用更少的跳数因为每增加一跳就多一份硬件损伤开销。如果想在论文里做一个路径选择鲁棒性的分析这个趋势是很值得呈现的。5.4 窃听者位置的影响窃听者位置是固定坐标还是在每次信道实现里随机撒点对SOP的影响很大。固定窃听者时路径选择算法可以在部署阶段就避开的区域随机窃听者时算法只能基于统计信息动作SOP结果会整体差一些。仿真时至少要做两种配置否则很容易把结论依赖在窃听者的具体位置上而这不是你真正想论证的。6. 调试经验与实现时容易踩的坑6.1 蒙特卡洛次数和随机种子管理SOP本质上是低概率事件的统计量如果目标速率R_th设得较高单次仿真里几万次信道快照可能只有几十次触发中断统计波动会非常大。我一般先用10^4次快速扫描参数范围确定感兴趣的工作点之后再用10^5到10^6次精跑。另外所有对比实验一定要固定随机数生成器的种子否则不同路径选择准则之间的微小性能差异会被信道随机性完全掩盖。6.2 dB与线性值混用这个错误非常隐蔽。硬件损伤参数kappa如果按工程习惯写成-15 dB你在代码里要先用 10^(kappa_dB/20) 换回线性幅度再平方才是方差。径路损耗也要小心不要直接在复数信道系数上乘dB值。我的解决办法是把所有参数在初始化阶段统一转成线性W单位并且在上层函数入口处加断言检查防止后续不小心把错误单位传进去。6.3 窃听合并模型和主链路聚合模型要写清楚注释同样的仿真参数窃听端用MRC合并还是选择合并结果完全不一样主链路用调和平均还是最小SINR也会差出几个dB的结论。这不是bug而是建模假设的问题。代码注释里至少要写明这两种假设否则过两个星期你自己回来都分不清当时跑的是哪套配置。6.4 硬件损伤方差不要重复加还有一次我处理中继转发时在DF模式下把上一跳的发射端畸变又叠加到下一跳的信号里相当于把硬件损伤作了双重计算。DF模式每跳重新解码上一跳的畸变不会以信号的形式跨跳传递正确的做法是每一跳只加本跳发射机和接收机的畸变。AF模式才需要做跨跳传递的推导。不同转发机制下硬件噪声的传播模型不同这一点实现时必须清醒。6.5 小规模基准测试先行我先建立一个只有一个中继的最简单网络手动推导出该场景下保密速率的解析表达式再用程序跑180度信道快照来做数值验证。有了这个退出条件我再放心地把中继数量往上加。没有这个步骤就贸然跑大规模仿真一旦SOP结果不符合直觉你根本分不清是算法逻辑的问题、信道实现的问题还是参数配置的问题。最后分享一个我个人的使用习惯在跑这类仿真前我会先在单跳无窃听、无硬件损伤的退化配置下复现理想模型的可靠性曲线确认信道生成和SINR计算是准的然后逐步把窃听者、硬件损伤、多跳搜索依次加回来。每加一环看一次指标变化趋势是否和理论预期一致。这样做虽然前期繁琐一点但能节省大量的后期排查时间。这个题目做完之后继续往协作干扰或者功率分配方向扩展也比较顺路径选择模块可以输出路径和每跳的SINR余量这些信息直接可以作为下一步联合优化的输入。