☰
频谱共享下的反向散射通信:联合能量与干扰约束的凸优化设计
2026/10/9 23:29:28 网站建设 项目流程

简介:面向无线通信与物联网研究者的PDF资料,聚焦环境反向散射通信与无线供电设备的频谱共享优化,提出“搭乘主信号”(ROP)模型,联合优化主信号发射功率与反射系数,在满足主系统干扰约束的前提下最大化次级系统遍历容量。资源共1个PDF文件,压缩包仅754KB,内容包含论文详解与可运行的Python代码,覆盖瑞利衰落信道建模、CVXPY凸优化求解以及不同速率/中断概率约束下的性能仿真。目前已有163人学习,适合从事频谱共享、反向散射通信方向的研究生和技术人员,可用于复现实验、评估系统性能并理解理论模型与工程实现间的映射。资源重点补充了现有研究在互干扰理论分析方面的不足,通过完整建模展示了次级发射器如何从主信号收集能量并将调制信息反射给次级接收器;代码注释清晰,便于读者修改信道参数、约束条件并扩展至其他无线供电物联网场景。

1. 从“偷电”到“偷信道”:反向散射让频谱共享不再是一厢情愿

先说我反复遇到的实际场景:一个主用户系统正在正常工作,外部又挂了一批低功耗传感节点。节点没有稳定供电,不能常换电池,唯一能用的能源是主用户发出的射频信号。节点“活下来”不难,难的是数据怎么回来——没有额外频段,也不能干扰主用户已有的通信链路。环境反向散射通信的办法,是让主用户的射频信号同时承担两件事:给设备充电,以及作为载波把设备的数据“反射”回汇聚节点。表面看,这只是一套“捡漏”的物理层设计,但真正做工程时会发现,频谱共享环境下所有东西都互相牵扯:反射功率会让主用户接收机收到额外干扰,充电时长缩短又会让设备没电可用,反射系数调大能提高自身信噪比但对共享频谱的干扰也同步抬升。这份资源给的就是一套把时间分配、反射系数、设备功率放在同一个凸优化框架里联合调度的完整模型,附带可直接运行的代码。适合正在做频谱资源管理、绿色物联网仿真的开发者,也适合想把反向散射接入自己系统仿真但不想重造轮子的同学。

2. 无线供电加频谱共享:三个变量为什么必须放一起优化

2.1 系统架构:到底谁跟谁在共享频谱

这个共享模型里通常有三方角色:主用户发射机、若干反向散射物联网设备、数据汇聚节点,外加一个需要保护的主用户接收机。主用户发射机是环境射频源,物联网设备没有自身振荡器,它靠两副天线做两件事——一副接收射频能量用于整流储能,另一副通过切换天线阻抗把数据调制到反射波里。汇聚节点收到的是“直射信号+环境反射信号”的叠加,解码时一般假设主用户信号是已知的干扰或可以被抵消。

频谱共享的含义不是简单的“允许使用同一频段”,而是必须让反向散射设备对主用户接收机造成的加性干扰低于某一个阈值。这个阈值由主用户的链路预算决定,通常写成一个显式的干扰上限 (I_{\text{max}})。很多入门资料只给结论“用反向散射不占频谱”,但工程模型里,反射功率每提高一点点,都是在对主用户接收机的信噪比“抽税”,所以优化时必须把干扰约束写在最前面。

实际搭建仿真时,我会先用一个极简拓扑去验证算法逻辑,再逐渐加节点。例如设备数量 N 从 2 加到 8,信道做瑞利衰落加路径损耗,主用户发射机的位置固定,汇聚节点放在设备群体同侧。环境中有一堵墙就增加衰减指数,没有墙就按自由空间近似。关键是第一版不要急着加随机阻塞模型,因为联合优化问题的病态会掩盖信道本身的随机性。

2.2 设备端行为:一个开关怎么同时干两件事

反向散射设备的能量来源是环境射频信号,整流后用超级电容或小容量电池缓存。数据发送时不产生新载波,而是利用一个高速开关切换反射路径的阻抗状态,把信息比特映射成反射波幅度或相位的跳变。这个开关的实质控制参数是反射系数 (\Gamma),取值在 0 到 1 之间(有时也允许复数,但直角资源模型里先按实数处理)。

反射系数决定了反射功率占入射载波功率的比例。(\Gamma=0) 表示全部吸收用于充电,(\Gamma=1) 表示最大反射,但它同时意味着整流端几乎没有能量流入。所以在时间维度上,设备必须先充电再反射,同一个时间帧被割成两段:前段用于指令校正和储能,后段用于反向散射传输。说穿了,这不是“一边充电一边发数据”的物理过程,而是“先充后发、轮流复用”的时分机制。

从建模角度,每个设备的行为被拆成三个量:分配给它的充电时长比例、反射系数、实际反射功率。反射功率不是独立量,它是充电时长、反射系数和入射功率三者的乘积。如果把它们当独立变量丢给求解器,求出来会是一堆物理上不可能的组合,这事我在最初跑模型时没少被坑,后面第五章会细说。

2.3 优化问题建模:六个约束缺一不可

把优化写完整,数学上是一个变量耦合并带非线性约束的混合问题,但可以通过变量替换和凸近似来处理。目标函数在这里取“所有设备总频谱效率最大”,单位是 bps/Hz,或者换成给定带宽之后的总吞吐量。

约束至少要有六类:

第一,时间分配约束,所有设备的充电时长比例之和不能超过 1,且每台设备必须有充电窗口。第二,反射系数边界,每个设备的反射系数在 ([0, 1]) 区间内,具体上限取决于标签天线的匹配网络设计。第三,能量因果约束,设备用于反向散射的能量不能超过它在前一段充电窗口里收集到的能量。第四,主用户干扰约束,所有设备反射信号在主用户接收机处的叠加功率必须低于阈值。第五,反射功率物理边界,每台设备的输出功率有上限,由入射功率和整流效率共同限定。第六,非负门限约束,总吞吐量或者每个设备的最低吞吐量有时会被设下限,避免“个别设备饿死、整体吞吐量好看”的假象。

公式化之后,约束的困难点集中在能量因果约束里。那个约束是充电时长乘反射系数乘入射功率,三个变量相乘让问题变成非凸。代码实现里最常见的处理方式是做变量替换:用 (r_i) 表示设备 i 的实际反射功率,把乘积项拆成线性约束。下一章就专门讲这个替换是怎么做的,以及替换后凸优化求解为什么能收敛这么快。

3. 把非凸问题“摁”成凸问题:变量替换与 CVXPY 求解

3.1 一个乘积换两个约束:问题瞬间变凸

原始问题最让人头疼的表达式是“充电时长 × 反射系数 × 入射信道增益”。入射信道增益是常数,难办的是两个变量的乘积。要摆脱非凸,我一般会引入设备实际反射功率 (P_{\text{rx},i}) 作为新的变量,然后把它和充电时长、反射系数之间的乘积关系改写成两个线性不等式的组。

具体操作是这样:先定义充电时长为 (t),设备 i 的反射系数为 (\gamma_i),入射载波功率为 (P_{\text{in},i})。实际反射功率 (r_i = t \gamma_i P_{\text{in},i})。如果把 (\gamma_i t) 整体视为一个辅助变量 (u_i),同时让 (0 \le u_i \le t),再把约束写成 (r_i \le \eta P_{\text{in},i} u_i),约束就成了线性的。

其中 (\eta) 是整流效率,刻画射频转直流的损耗。这还没完,(r_i) 还要满足主用户干扰约束 (\sum_i r_i g_{ui} \le I_{\text{max}}),其中 (g_{ui}) 是设备 i 到主用户接收机的信道增益,这也是线性约束。目标函数里,接收信噪比是 (r_i g_{di} / (\sigma^2 + I_0)),其中 (g_{di}) 是设备到汇聚节点的信道增益,(\sigma^2) 是噪声功率,(I_0) 是主用户信号造成的残差干扰。对总频谱效率取 (\log(1+\text{SNR})) 求和,log 里是 (r_i) 的一次项,整个目标是凹函数,最大化凹函数就是标准的凸优化形式。

这一步替换看着只是“把两个变量变成一个变量”,但它决定了求解器是收敛还是随机游走。之前我见过有些人图省事,直接把原目标函数丢给求解器,让非凸问题在 CVXPY 里靠自动凹凸检测去硬算,脚本跑起来非常慢,还经常报“违反 DCP 规则”。正确的做法永远是先人工做变量替换,把乘积项压成线性约束,再交给求解器计算。

3.2 求解器怎么选:不是所有 Solver 都适合这种凸问题

CVXPY 默认调用的求解器是 ECOS 或 SCS。ECOS 适合二阶锥规划,效率高,但对矩阵病态敏感;SCS 走一阶方法,内存占用小,但精度稍微粗一点。对于这种变量数量几十、约束几十的联合优化脚本,ECOS 通常五秒内出解,我一般会固定用它。

如果设备数量放大到几百,ECOS 可能慢,这时候可以考虑切换成 Clarabel 或 OSQP,前者是新一点的二阶锥求解器,稳定性不错。注意一点:CVXPY 的目标函数若出现 (\log),问题归类为指数锥规划,ECOS 和 Clarabel 支持指数锥,OSQP 不支持。所以选 Solver 之前先看清楚自己用的目标函数形式。

我还会在代码里加一行“求解器状态打印”,如果显示optimal才继续画图。如果显示optimal_inaccurate,多半是信道增益动态范围太大,需要把路径损耗外的数值做归一化。这个问题在第四章代码里我有意留了一处,后面会讲怎么处理。

3.3 核心代码:联合优化求解的骨架

下面这段代码解决核心优化问题,直接可跑,但场景数据是随机生成的,你需要按自己拓扑替换信道部分。

import numpy as np import cvxpy as cp rng = np.random.default_rng(20240611) # ---- 场景参数 ---- N = 8 # 反向散射设备数量 PTx_dbm = 30.0 # 主用户发射功率 30 dBm PTx = 10 ** ((PTx_dbm - 30) / 10) # 转换成 W eta = 0.5 # 整流效率 sigma2 = 1e-11 # 噪声功率 W,约 -80 dBm I_max = 3e-5 # 主用户干扰阈值 W,约 -15 dBm gamma_max = 0.8 # 反射系数上限 # ---- 信道生成:路径损耗 + 瑞利衰落 ---- d_s = 3.0 + 4.0 * rng.random(N) # 主用户发射机到设备距离 d_g = 2.0 + 3.0 * rng.random(N) # 设备到汇聚节点距离 g_u = 5.0 + 6.0 * rng.random(N) # 设备到主用户接收机信道强度 h_s = (rng.normal(size=N) + 1j * rng.normal(size=N)) / np.sqrt(2) h_d = (rng.normal(size=N) + 1j * rng.normal(size=N)) / np.sqrt(2) gain_s = np.abs(h_s) ** 2 / (d_s ** 2.2) gain_d = np.abs(h_d) ** 2 / (d_g ** 2.4) # ---- 优化变量 ---- alpha = cp.Variable(name="alpha") # 充电时长比例 r = cp.Variable(N, name="r") # 实际反射功率 W # ---- 目标函数:总频谱效率最大 ---- snr = r * gain_d / sigma2 rate_obj = cp.sum(cp.log1p(snr)) # 天然是凹函数 constraints = [ 0 <= alpha, alpha <= 1, r >= 0, r <= eta * PTx * gain_s * alpha * gamma_max, cp.sum(r * g_u) <= I_max ] problem = cp.Problem(cp.Maximize(rate_obj), constraints) problem.solve(solver=cp.ECOS, verbose=False) if problem.status == "optimal": print("optimal alpha =", alpha.value) print("optimal total log-rate =", problem.value) else: print("solver status:", problem.status)

代码逻辑说明:alpha是所有设备共享的时间资源,r是每个设备的实际反射功率,目标函数直接对 SNR 取log1p,这是凹函数,所以整个最大化问题是凸优化。反射功率的约束写成“不能超过充电收集的能量乘反射系数上限”,这里是简化写法,用一个不等式同时覆盖能量因果和反射上限。

参数说明里有一个容易被忽略的点:目标函数没有乘带宽,所以返回的是“总频谱效率”而不是“总吞吐量”。如果需要吞吐量数值,在代码外乘上系统带宽即可。另一点是I_max = 3e-5这个取值对应约 -15 dBm,如果主用户接收机距离设备较远可以放宽到 1e-4,具体按主用户信噪比预算反推。

4. 完整复现:从信道生成到基线对比

4.1 场景文件设计:哪个参数决定系统行为

完整复现项目建议先建一个场景参数文件,把下面六个参数单独拎出来调试:

参数典型值作用
设备数量 N2~16决定变量和约束规模
主用户发射功率20~36 dBm决定入射能量和反射功率上限
整流效率 η0.3~0.7决定能量因果约束松紧
反射系数上限0.5~1.0决定最大反射功率
干扰阈值 I_max1e-5~1e-4 W决定频谱共享是否“有实际意义”
路径损耗指数2.0~2.8决定信道增益动态范围

初跑模型时,我建议把 N 先设成 4,路径损耗指数设成 2.0,功率设成 30 dBm。这样跑出来的结果稳定,也方便画图时观察趋势。等整套流程通了,再慢慢增加设备数量,观察优化器给每个设备的反射功率分配规律。

另一个容易忽略的点是信道随机种子。如果不固定随机种子,每次跑结果不一样,基线对比就没有意义。我在上面的代码里用了default_rng(20240611),如果完全复现,你需要保持种子一致。

4.2 主脚本:三步走跑通完整实验

完整脚本分三步:生成信道、做联合优化、跑固定参数基线。下面这段代码是第二步和第三步的完整逻辑,可以直接落到main.py里。

import numpy as np import cvxpy as cp # 沿用前面场景参数与信道生成代码 # 这里直接进入求解函数 def solve_joint(N, PTx, eta, gamma_max, I_max, gain_s, gain_d, g_u): alpha = cp.Variable(name="alpha") r = cp.Variable(N, name="r") snr = r * gain_d / sigma2 objective = cp.Maximize(cp.sum(cp.log1p(snr))) constraints = [ 0 <= alpha, alpha <= 1, r >= 0, r <= eta * PTx * gain_s * alpha * gamma_max, cp.sum(r * g_u) <= I_max ] prob = cp.Problem(objective, constraints) prob.solve(solver=cp.ECOS) return alpha.value, r.value, prob.status

逻辑说明:把求解部分抽成函数,方便后续循环遍历不同参数做敏感性分析。sigma2是全局变量,按上一章定义。这个函数返回充电时长、每个设备的反射功率以及求解器状态。注意返回的r.value是一个向量,不要直接用r.value[0]来提取,除非你已经确认顺序与gain_s一一对应。

基线的做法是固定充电时长比例 0.5、固定反射系数 0.4,然后用同样的信道数据算总吞吐量。这里有个非常重要的细节:基线方案也必须满足主用户干扰约束,不然比较不公平。常见做法是对反射功率统一除以一个缩放因子,把总干扰压到阈值内,再计算吞吐量。

alpha_fix = 0.5 gamma_fix = 0.4 r_fix = eta * PTx * gain_s * alpha_fix * gamma_fix scale = np.minimum(1.0, I_max / np.sum(r_fix * g_u)) r_fix = r_fix * scale snr_fix = r_fix * gain_d / sigma2 rate_fix = np.sum(np.log1p(snr_fix))

这个缩放逻辑很关键:它对基线功率做一个“限额分配”,保证其在共享约束下可以合法运行。如果说联合优化方案是“主动优化”,基线方案就是“被动限功率”,两者的差别就是优化带来的增益。

4.3 结果怎么看:三条曲线比一个数字有用

单跑一次联合优化,你只会得到一个数值,看不出模型行为。我的习惯是做三条曲线:

  • 横轴为干扰阈值 (I_{\text{max}}),纵轴为总频谱效率
  • 联合优化与固定基线方案各画一条,再加一条“无约束上界”作为参考
  • 无约束上界就是把 (I_{\text{max}}) 设成无穷大时联合优化的结果,这个值说明“频谱共享约束到底牺牲了多少性能”

画图时还要注意横轴单位。如果以 dBm 画,从小到大的数值会让曲线看起来比较自然;如果以 W 画,曲线在低阈值区域会被压缩。我一般用 dBm,也就是把干扰阈值取对数标度。横轴范围取 -25 dBm 到 -10 dBm,每档跑一次优化。

4.4 常见误用:把反射系数当常数代入优化

别把反射系数和实际反射功率混为一谈。我在代码里直接用r作为实际反射功率,它已经包含了充电时长和反射系数的综合效果。如果有人在同一份代码里既定义gamma为变量,又定义r = gamma * ...,然后让求解器同时优化这两个量,问题就又变回非凸了。

正确写法只有两种:要么用 (u_i = \gamma_i t) 辅助变量,要么直接像这里一样把r作为核心变量。读完这章,你应该能理解为什么原项目的代码把变量定义得那么克制——本质上就是为了保持 DCP 合规,让求解器不挑刺。

5. 避坑指南:五次翻车记录与对应排查方法

5.1 能量因果约束被求解器“钻空子”

现象:优化出来的总吞吐量很高,但每个设备反射功率之和超过了充电阶段收集的能量,物理上完全不可能实现。

原因:我只写了反射功率小于某个上限的约束,没有限制“这个上限的能量来自充电时段”。当充电时长alpha被优化到接近 1,反射功率约束就非常宽松,优化器会把所有反射功率都集中在能量收入最多的时间段,忽略了“先充后发”的顺序约束。

解决:把能量因果约束写成显式不等式,即设备的反射功率不超过它收集的能量,其中收集能量来自充电时长比例乘入射功率乘整流效率。同时约束充电时长不能分配给“已经过去的时间”,所以alpha必须有一个定义域限制,通常按帧长归一化后写成 (0 \le \alpha \le 1)。最后在代码里检查所有约束的残差,不要只信目标值。

5.2 反射系数跑出上限,代码里却看不到警告

现象:结果里某个设备的反射功率远超设计上限,但求解器状态仍然是optimal。

原因:我把反射功率r的约束误写成 (r \le \eta P \alpha \gamma_{\max}),但忘了给r加非负下界。求解器在数学上可以给r一个巨大的负值来满足约束,然后目标函数里的 SNR 也变负,最后算出一个无意义的结果。CVXPY 不会自动识别你“本意是想让 r 代表功率”,它只认表达式。

解决:给r显式加r >= 0。以后所有物理量建模,我都坚持把上下界写齐全,不留隐式边界。

5.3 基线方案不公平:优化方法看起来强得离谱

现象:联合优化比基线方案性能高出 300%,我一度以为模型写错了,后来发现是基线方案没有满足干扰约束。

原因:基线方案直接把反射功率设成固定值,导致它对主用户接收机造成过量干扰,这个干扰本身就是违规的。拿一个违规方案和合规方案做对比,差距当然夸张。

解决:基线方案必须先做一个“功率限幅”,把所有反射功率统一缩放,直到总干扰小于阈值,然后再计算频谱效率。从那以后我每次做对比实验,都先把合规性校验写在最前面,两个方案先合格再比性能。

5.4 求解器状态为optimal_inaccurate,结果细节不可信

现象:脚本能跑通,但打印的反射功率在个别设备上出现极端值,比如某一个设备功率几乎为零,另一个设备功率顶到上限。

原因:信道增益动态范围太大,路径损耗指数较高时,距离远的设备增益可能是近距离设备的百分之一,矩阵条件数变差,ECOS 虽然给出解,但精度不够。

解决:把信道增益按最大增益做归一化,或者把噪声功率sigma2稍微调大,让信噪比动态范围落在 1e-3 到 100 之间。如果归一化后仍不理想,换 Clarabel 求解器再试一轮。

5.5 随机信道种子不固定,实验结论无法复现

现象:同一个脚本跑两次,曲线形状完全不同,有时候联合优化比基线差,有时候比基线好。

原因:随机数种子没有固定。信道生成使用了系统的随机状态,每次生成不同的信道衰落值,优化结果自然不同。单个随机实例上做比较,结论没有任何统计意义。

解决:固定np.random.default_rng()种子,并做多实例平均。比如随机生成 50 个信道快照,每个快照分别跑优化和基线,最后取平均频谱效率画曲线。如果时间紧张,至少固定 10 个种子,并把每次的波动范围用置信带画出来。

6. 进阶一档:公平性约束、实测修正与上线前的数值预检

6.1 把“总吞吐量最大”改成“最差设备吞吐量最大”

第三章的目标函数是最大化所有设备的频谱效率之和,这是系统级“吞吐量最大化”,但它不保证公平。实际工程里,距离主用户发射机远的设备信道差,优化器往往会把它饿死,把所有资源倾斜给近端设备。

做公平性设计时,我会把目标函数改成最大化最小的单设备吞吐量,也就是 max-min fairness。在 CVXPY 里,这个目标可以引入一个辅助标量变量 (t),加入约束 (t \le \log(1 + \text{SNR}_i)) 对所有 i 成立,然后最大化 (t)。这个约束仍然是凸的,求解速度不比原目标慢多少。改动成本很低,但结果含义完全不同——每个设备都保证有一个下限吞吐量,适合传感器网络中“每个节点都要上报最小数据包”的场景。

t = cp.Variable(name="fairness_level") constraints.append(t <= cp.log1p(snr)) objective_fair = cp.Maximize(t)

注意,这里的约束并不是把log1p(snr)直接加进目标,而是让它成为约束的一部分,CVXPY 会对凸约束自动处理。跑通后还有一个现象值得看:公平性方案的总体效率通常会略低于无约束最大化,但最差设备吞吐量会显著抬高,这一升一降的幅度就是“公平犧牲”的量化指标。

6.2 用实测 S 参数修正反射系数边界

仿真里的反射系数是被我拍脑袋限制在 0 到 0.8,但真实验证时,这个值受天线匹配网络影响很大。实测天线 S11 参数会给出不同阻抗状态下的反射损耗,你需要把反射系数上限改成实测值,而不是理论理想值。比如某个频点上实测最大反射效率只有 0.62,那gamma_max就该改成 0.62,否则仿真结果在真实环境里根本无法复现。

连信道模型也有讲究。室内短距离场景下,路径损耗指数 2.0~2.2 就够了;如果是半开放厂区,信号会有较多反射,信道衰落形态接近莱斯分布,用瑞利衰落会低估性能。我在做这类项目时,会先在目标环境录一组信道数据,反推路径损耗指数再喂给模型,而不是天天用书上的基准值。

6.3 一次参数敏感性预检,把踩坑堵在上线前

上线前我一般会跑一次参数扫描,只动一个参数,其余保持默认值,看输出会不会出现突变。比如把设备数量从 4 调到 8,再调到 16,如果总吞吐量不升反降,多半是干扰约束起了主导作用;如果充电时长alpha一直顶在 1,说明能量紧缺,反射系数上限再高也没用。

这种预检不花太多时间,但能帮我快速判断模型行为是否反常。有一次我把干扰阈值从 1e-5 改到 1e-4,优化结果总吞吐量跳升了 40%,我当时以为是算法改进,后来发现是阈值放宽导致反射功率暴涨,超出了设备实际可支撑的功率桌面。那次之后,我每次跑实验前都强制走一遍“六项预检”:反射功率非负、能量因果满足、干扰约束满足、反射系数不越界、求解器状态为 optimal、基线合规。六项全过再谈性能对比。

如果你也在做无线供电反向散射这类频谱共享的联合优化设计,建议把这个模型和代码直接拿去做第一版仿真,至少省下一周建模时间。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询