说实话,现在在无线通信圈子里,NOMA和D2D这对组合已经不算新鲜词了,但每次带新生或者给合作方讲方案时,我仍然会从这对“老搭档”讲起。原因很简单——NOMA(非正交多址接入)和 D2D(设备到设备通信)的组合,是理解 5G-Advanced 和 6G 候选技术的一块基石,几乎所有关于频谱效率提升、大规模用户接入的研究,最后都会绕回这个基础模型上。这篇笔记记录的是我梳理的 NOMA+D2D 基础模型第一版,主要面向两类人:刚进实验室、需要快速复现一篇 NOMA+D2D 论文的研一新生;做资源分配算法、但对物理层建模细节有点生疏的工程开发人员。我会从系统模型怎么搭、信道怎么建、SIC 译码和 SINR 怎么推,一路写到仿真怎么落地、有哪些坑,尽量把每一个“为什么这么做”都讲透。看完这个模型,你再去读那些“NOMA+D2D 联合资源分配”“鲁棒波束成形”之类的进阶论文,就不至于卡在建模这一步了。1. 整体思路拆解:为什么要把 NOMA 和 D2D 绑在一起1.1 NOMA 的立身之本NOMA 的本质,是允许同一个时频资源块上叠加多个用户信号,然后在接收端利用串行干扰消除(SIC)把信号逐个解出来。传统 OMA 体制下,一个资源块只能服务一个用户,属于“一人一桌”。NOMA 相当于“一桌坐了好几个人,每个人嗓门大小不同”,大嗓门(强信道)用户先说话,小嗓门(弱信道)用户后说话,接收端先听清大嗓门,再把它减掉,去听小嗓门。这个机制带来的直接收益是:同样一个资源块能承载更多用户,系统总吞吐量上去了。代价是:接收机复杂度增加、必须有信道差异才能发挥增益、还要做功率域的合理分配。1.2 D2D 的不可替代性D2D 通信不考虑基站中转,让两个相距较近的设备直接通信。好处大家都清楚——时延低、链路质量高、频谱可以不经过基站复用一次。但问题也明显:D2D 用户复用蜂窝频谱时,会给蜂窝用户带来同频干扰;蜂窝用户的下行/上行信号,也会干扰 D2D 接收端;功率控制稍微不谨慎,整个小区的信干噪比就会崩。1.3 组合后的系统增益把 NOMA 和 D2D 放在同一个系统里,核心诉求是让 D2D 用户接入 NOMA 组。也就是,一个 NOMA 簇内既有蜂窝用户(CU, Cellular User),也有 D2D 用户对(DU_pair)。蜂窝用户作为簇头,D2D 发射端复用蜂窝频谱进行直连传输。组合之后有三个层面的增益:接入增益:NOMA 让一个子信道同时服务多个蜂窝/D2D 链路;距离增益:D2D 短距离通信天然省功率,干扰可控;频谱复用增益:D2D 链路复用蜂窝频谱,小区频谱效率大幅提升。理解了这个组合逻辑,再看论文里常见的“最大化系统和速率”“满足 QoS 约束下的功率分配”“NOMA 配对 + 信道分配”这些题目,你会发现它们都是在围绕这三层增益做文章。2. 基础模型 NOMA+D2D 的系统建模2.1 网络拓扑设定这一版基础模型采用单小区场景,配置如下:1 个基站(BS)位于小区中心;M 个蜂窝用户,均匀随机分布在小区内,标记为 CU_i,i = 1, 2, ..., M;N 对 D2D 用户对,每对由一个发射端 DT_j 和一个接收端 DR_j 组成,j = 1, 2, ..., N;D2D 用户复用蜂窝用户的上行频谱(上行复用是主流选择,原因在后面“避坑提示”里会讲);信道采用频率平坦瑞利衰落 + 路径损耗模型。把用户分簇:每一簇由一个蜂窝用户和一个 D2D 对组成。基站同时接收蜂窝用户的上行信号和 D2D 发射端的信号,D2D 接收端也同时受到蜂窝用户和基站下行信号的干扰。注意:这个“一簇一个蜂窝用户 + 一个 D2D 对”的配置是基础版本。实际进阶方案里一个簇里可能有多个 D2D 对,但那引入了簇内干扰加上配对复杂度,留到第三版模型再展开。2.2 信道模型细节信道系数通常建模为:h = g * (d/d0)^(-alpha/2) * sqrt(beta)其中:g 为小尺度衰落系数,服从均值为 0、方差为 1 的复高斯分布,即瑞利衰落;d 为收发之间的距离;alpha 为路径损耗指数(室内取 2~3,室外密集城区取 3~4);beta 为阴影衰落的对数正态分量。在大多数论文仿真中,为了简化分析,会把小尺度衰落和阴影衰落合并成一个等效信道增益:G = |h|^2 = |g|^2 * beta * (d/d0)^(-alpha)论文的仿真里经常用这个简化的信道增益做 SNR / SINR 计算,跟着做时不必把信道细化到每个抽头都仿真出来。2.3 用户配对策略NOMA 的核心增益来源是同一资源块上不同用户的信道增益差异。所以配对时默认规则是:信道条件好的用户分配低功率,作为近端用户,承担 SIC 先译码的角色;信道条件差的用户分配高功率,作为远端用户,在 SIC 最后被解出来,保证它的最低速率需求。具体配对算法(贪心实现):将所有蜂窝用户按信道增益降序排列;将所有 D2D 对按 D2D 链路信道增益降序排列;依次把信道增益最强的 D2D 对与信道增益最弱/最强的蜂窝用户配对(哪种更好取决于目标函数是最大化总速率还是保证公平性)。这个排序逻辑看起来简单,但它是后续所有资源分配算法的基础,一旦配对错了,后面功率分配再怎么优化也补不回来。3. 核心机制解读:SIC 译码顺序与 SINR 推导3.1 信号模型以第 m 个蜂窝用户 CU_m 的上行链路为例。CU_m 和 D2D 对 j 组成一簇,两者复用同一子信道 n。基站收到的叠加信号可以写成:y_BS = sqrt(P_m) * h_m * x_m + sqrt(P_j) * h_j * x_j + n_BS其中:P_m、P_j 分别是 CU_m 和 D2D 发射端 DT_j 的发射功率;h_m 是 CU_m 到基站的信道系数;h_j 是 DT_j 到基站的信道(这里注意,基站也会收到 D2D 发射端的信号,这对基站来说是干扰信号);n_BS 是基站处的加性高斯白噪声,功率谱密度为 N_0。D2D 接收端收到信号表示为:y_DR = sqrt(P_j) * h_jj * x_j + sqrt(P_m) * h_mj * x_m + n_DRh_jj 是 DT_j 到 DR_j 的 D2D 直连信道;h_mj 是 CU_m 到 DR_j 的干扰信道;n_DR 是 D2D 接收端的噪声。核心点:这其实是一个两用户的 NOMA 簇,只不过第二个用户不是另一个蜂窝用户,而是 D2D 链路。3.2 SIC 译码顺序的确定NOMA 的 SIC 译码顺序并不是随便定的。理论推导可以证明,为了最大化系统容量,应该按照信道增益从强到弱的顺序依次译码——信道强的用户先被译出并消除,信道弱的用户最后译出。这是因为信道强的用户本身信号质量好,容易译码成功,把它先消掉,就能更好解码弱用户的信号。假设在基站侧:|h_m|² > |h_j|²,即 CU_m 信道强于 DT_j 到基站的信道;那么 SIC 顺序为:基站先解码 CU_m 的信号,此时把 DT_j 的信号当作干扰;基站在解码 CU_m 后,将 CU_m 的信号做重建、相减、消除;再解码 DT_j 的信号,此时干扰只剩噪声。对应 SINR 表达式:CU_m 的 SINR:SINR_m = P_m * |h_m|^2 / (P_j * |h_j|^2 + N_0 * B)DT_j→BS 这条链路在 SIC 后的 SINR:SINR_j_BS = P_j * |h_j|^2 / N_0 * B在 D2D 接收端侧,直接解码 DT_j 的信号,CU_m 的信号是干扰:SINR_j_DR = P_j * |h_jj|^2 / (P_m * |h_mj|^2 + N_0 * B)我见过不少刚入门的人犯同一个错误——把基站侧和 D2D 接收端的 SINR 混在一起算。记住:这是两条链路,但只有一个是 NOMA 簇内的 SIC 关系,另一个是纯干扰受限链路。搞混了,后面中断概率能算错 3 个数量级。3.3 可达速率的表达式根据香农公式,可达速率:R_m = B * log2(1 + SINR_m) R_j = B * log2(1 + SINR_j_DR)系统总速率:R_total = sum(R_m) + sum(R_j)这里的 B 是子信道带宽。注意,由于 D2D 是复用蜂窝频谱的,它在速率计算中不单独占用新的带宽资源。这个特点正是 D2D 增益的来源——不增加带宽的情况下多了一路传输。4. 关键约束条件与目标函数4.1 必列的约束条件论文里做优化时,约束条件通常长这样:约束1(保证SIC可行): R_m >= R_min 约束2(满足D2D QoS): R_j >= R_j_min 约束3(发射功率非负且有上界): 0 <= P_m <= P_max_BS, 0 <= P_j <= P_max_D2D 约束4(信道分配互斥): 一个子信道在同一时刻最多只能被一个簇复用约束 1 很重要,如果 CU_m 的速率都达不到最小要求,那么 SIC 第一层就会解码失败,整个簇都崩了。所以功率分配的首要原则不是最大化总速率,而是先保 SIC 的可行性。4.2 常见目标函数基础模型中常做的优化目标有三种:目标数学形式适用场景最大化系统和速率max sum(R_m + R_j)吞吐量优先最大化最小速率max min(R_m, R_j)公平性优先最小化总功率min sum(P_m + P_j)节能 / 干扰控制没有绝对的“最优目标”,只有适不适合当前场景。做基础复现的时候,先从最大化系统和速率开始,因为最直观、最容易验证。4.3 一个关键权衡:公平性与总速率的对抗NOMA 的经典研究结论**“用户的信道条件差异越大,NOMA 相对 OMA 的增益越大”**,在 NOMA+D2D 场景里同样成立。信道差异越大的簇,SIC 越容易实现,弱用户的增益越明显;反过来,如果两个用户信道条件太接近,SIC 增益很小,还要额外承受接收机复杂度,这时 OMA 反而更优。这引出一个非常实用的设计准则:在配对时优先选信道差异大的用户组簇。如果簇内两个用户的信道增益比小于某个阈值(比如 3 dB),这个簇就不要建了,直接用 OMA 方式通信,总性能可能更好。这个准则很多论文里不会明说,但实测下来对系统性能影响极大。5. 仿真实现与代码级落地5.1 仿真场景参数照着基础模型复现时,我常用的参数如下:参数值小区半径500 m子信道带宽15 kHz子载波数1(单载波)蜂窝用户数 M4D2D 对数量 N4蜂窝用户最大功率23 dBmD2D 发射功率10~20 dBm路径损耗指数3.5噪声功率谱密度-174 dBm/Hz用户最小速率要求0.5 bps/Hz仿真用 MATLAB 或者 Python 都可以。如果只是想验证模型趋势,Python 就够了,不用上重型仿真平台。5.2 Python 仿真核心流程仿真流程可以这样拆:随机撒点生成用户位置,计算距离;生成瑞利衰落信道增益(复数高斯采样取模平方);计算信道增益 |h|² 并排降序;按贪心规则配对簇;分配功率——这里可以先固定等功率,再逐步验证功率分配的效果;计算 SINR 和速率;重复 10000 次 Monte Carlo,取平均。核心代码片段如下(可直接替换成自己的实现):import numpy as np R_cell = 500.0 alpha = 3.5 N0 = -174 B = 15e3 # 生成用户位置 def gen_users(n): angles = 2 * np.pi * np.random.rand(n) radii = R_cell * np.sqrt(np.random.rand(n)) return radii * np.cos(angles), radii * np.sin(angles) # 生成瑞利信道增益 def gen_channel_gain(d, alpha=3.5): h_small = (np.random.randn() + 1j * np.random.randn()) / np.sqrt(2) pl = d ** (-alpha / 2) return (np.abs(h_small) ** 2) * (pl ** 2) # 计算 SINR def compute_sinr(P_sig, P_int, G_sig, G_int, N0_dbm, B): N0 = 10 ** ((N0_dbm - 30) / 10) * B return (P_sig * G_sig) / (P_int * G_int + N0)注意:噪声功率的计算很容易出错。dBm 要先减去 30 变成 dBW,再转成线性值乘带宽,换算公式:N_lin = 10^((N0_dbm - 30) / 10) * B这个细节能直接决定你仿真的绝对工作点是否正确,虽然不影响相对趋势,但影响和论文结果对比的可信度。5.3 仿真结果验证方法判断仿真是否正确,最简单的验证:等功率情况下,信道增益最强的用户应当获得最大速率——如果结果不符合直觉,大概率是配对或信道生成弄错了;没有 D2D 用户的场景直接退化成纯 NOMA,速率应等于传统 NOMA 结果;D2D 发射功率趋近于 0时,D2D 速率应趋近于 0,同时蜂窝用户的速率趋近于没有 D2D 干扰的情况。我每次跑新代码都会先做这三个 sanity check,确认没问题再继续调算法。6. 典型问题与避坑记录6.1 干扰链路被忽略最常见的问题就是只算了蜂窝链路和 D2D 链路各自的 SINR,忘了 D2D 发射端对基站、蜂窝用户对 D2D 接收端的干扰。这两条干扰链路在功率接近时影响巨大。干扰链路影响对象影响程度DT → BS基站解码 CU 信号高CU → DRD2D 接收端解码高BS → DRD2D 接收端(下行干扰)中尤其当 D2D 发射功率较高或 D2D 对距离蜂窝用户很近时,干扰会造成系统性速率下降。处理方式通常是做功率控制,而不只是调信道分配。6.2 D2D 复用蜂窝频谱的下行/上行选择基础模型的默认选择是复用上行频谱。原因是:上行频谱在基站端相对空闲,干扰更好控制;基站本身是功率充足的节点,它在下行方向上对 D2D 接收端的干扰非常强,复用下行频谱对功率分配要求苛刻得多。如果你在论文里看到有人说复用下行频谱,关注一下他们有没有做基站侧的功率控制和波束赋形,如果没有,可以用审稿人视角先质疑一下,再自己跑仿真验证。6.3 SIC 的误码传播效应SIC 的模型里有个隐含假设:前一层译码是完美译码。但实际系统译码后会有残留误差,这个误差会传导到后面的解码阶段,这就是“误差传播”效应。基础模型阶段,大多数论文用理想 SIC 假设;到了实际系统设计,需要在 SINR 公式里加一个残余干扰因子,通常表示为:SINR_m = P_m * G_m / (P_j * G_j * eta + N0)其中 eta 是残余干扰系数,通常取 0.01~0.1。等做到基于实测信道模型的系统级仿真时,你会回头看这个系数的。6.4 用户配对策略对结果影响巨大配对策略决定了簇内的信道差异,进而决定了 SIC 的可行性。这里提供三种常见的配对方式:随机配对:最简单的 baseline,性能最差;按信道增益排序配对:强信道用户配弱信道用户,性能中等,适用于公平性优先场景;最优配对:通过匈牙利算法等做指派问题求解,性能最稳定,但计算复杂度高。如果某篇论文只给出了“通过穷举找到最优配对”的说法,并没有给出具体的配对算法步骤,那这部分你大概率要自己补——这也是复现 NOMA+D2D 文献最耗时的地方。7. 给复现者的一条实用建议这个基础模型我带着不同背景的人搭过很多遍,总结一句:在动手写代码之前,先用手推一遍两个用户的闭式解。怎么做:假设 M = 1、N = 1,给定功率 P_m、P_j 和两组信道增益,直接在纸上推出 SINR、速率、以及满足 QoS 的功率可行域。然后再上代码。这个“推公式—写代码—对比趋势”的流程,基本能帮你避开 80% 的建模错误。基础模型是所有进阶内容的锚点。后续无论产品里谈资源调度、博弈论定价、多天线 MIMO-NOMA,还是智能反射面辅助的 NOMA+D2D,本质上都在这个模型骨架上加东西。把这个骨架理解透了,后面所有论文里的“改进”“创新”读起来就是在看“在哪个模块做了什么手脚”,看一眼就能明白个大概。下一篇笔记里,我会在这个基础模型中加入功率分配的闭式解推导,把 Karush-Kuhn-Tucker 条件应用到 NOMA+D2D 簇的优化问题上,并给出完整推导流程,到时候继续记录。
说实话,现在在无线通信圈子里,NOMA和D2D这对组合已经不算新鲜词了,但每次带新生或者给合作方讲方案时,我仍然会从这对“老搭档”讲起。原因很简单——NOMA(非正交多址接入)和 D2D(设备到设备通信)的组合,是理解 5G-Advanced 和 6G 候选技术的一块基石,几乎所有关于频谱效率提升、大规模用户接入的研究,最后都会绕回这个基础模型上。这篇笔记记录的是我梳理的 NOMA+D2D 基础模型第一版,主要面向两类人:刚进实验室、需要快速复现一篇 NOMA+D2D 论文的研一新生;做资源分配算法、但对物理层建模细节有点生疏的工程开发人员。我会从系统模型怎么搭、信道怎么建、SIC 译码和 SINR 怎么推,一路写到仿真怎么落地、有哪些坑,尽量把每一个“为什么这么做”都讲透。看完这个模型,你再去读那些“NOMA+D2D 联合资源分配”“鲁棒波束成形”之类的进阶论文,就不至于卡在建模这一步了。1. 整体思路拆解:为什么要把 NOMA 和 D2D 绑在一起1.1 NOMA 的立身之本NOMA 的本质,是允许同一个时频资源块上叠加多个用户信号,然后在接收端利用串行干扰消除(SIC)把信号逐个解出来。传统 OMA 体制下,一个资源块只能服务一个用户,属于“一人一桌”。NOMA 相当于“一桌坐了好几个人,每个人嗓门大小不同”,大嗓门(强信道)用户先说话,小嗓门(弱信道)用户后说话,接收端先听清大嗓门,再把它减掉,去听小嗓门。这个机制带来的直接收益是:同样一个资源块能承载更多用户,系统总吞吐量上去了。代价是:接收机复杂度增加、必须有信道差异才能发挥增益、还要做功率域的合理分配。1.2 D2D 的不可替代性D2D 通信不考虑基站中转,让两个相距较近的设备直接通信。好处大家都清楚——时延低、链路质量高、频谱可以不经过基站复用一次。但问题也明显:D2D 用户复用蜂窝频谱时,会给蜂窝用户带来同频干扰;蜂窝用户的下行/上行信号,也会干扰 D2D 接收端;功率控制稍微不谨慎,整个小区的信干噪比就会崩。1.3 组合后的系统增益把 NOMA 和 D2D 放在同一个系统里,核心诉求是让 D2D 用户接入 NOMA 组。也就是,一个 NOMA 簇内既有蜂窝用户(CU, Cellular User),也有 D2D 用户对(DU_pair)。蜂窝用户作为簇头,D2D 发射端复用蜂窝频谱进行直连传输。组合之后有三个层面的增益:接入增益:NOMA 让一个子信道同时服务多个蜂窝/D2D 链路;距离增益:D2D 短距离通信天然省功率,干扰可控;频谱复用增益:D2D 链路复用蜂窝频谱,小区频谱效率大幅提升。理解了这个组合逻辑,再看论文里常见的“最大化系统和速率”“满足 QoS 约束下的功率分配”“NOMA 配对 + 信道分配”这些题目,你会发现它们都是在围绕这三层增益做文章。2. 基础模型 NOMA+D2D 的系统建模2.1 网络拓扑设定这一版基础模型采用单小区场景,配置如下:1 个基站(BS)位于小区中心;M 个蜂窝用户,均匀随机分布在小区内,标记为 CU_i,i = 1, 2, ..., M;N 对 D2D 用户对,每对由一个发射端 DT_j 和一个接收端 DR_j 组成,j = 1, 2, ..., N;D2D 用户复用蜂窝用户的上行频谱(上行复用是主流选择,原因在后面“避坑提示”里会讲);信道采用频率平坦瑞利衰落 + 路径损耗模型。把用户分簇:每一簇由一个蜂窝用户和一个 D2D 对组成。基站同时接收蜂窝用户的上行信号和 D2D 发射端的信号,D2D 接收端也同时受到蜂窝用户和基站下行信号的干扰。注意:这个“一簇一个蜂窝用户 + 一个 D2D 对”的配置是基础版本。实际进阶方案里一个簇里可能有多个 D2D 对,但那引入了簇内干扰加上配对复杂度,留到第三版模型再展开。2.2 信道模型细节信道系数通常建模为:h = g * (d/d0)^(-alpha/2) * sqrt(beta)其中:g 为小尺度衰落系数,服从均值为 0、方差为 1 的复高斯分布,即瑞利衰落;d 为收发之间的距离;alpha 为路径损耗指数(室内取 2~3,室外密集城区取 3~4);beta 为阴影衰落的对数正态分量。在大多数论文仿真中,为了简化分析,会把小尺度衰落和阴影衰落合并成一个等效信道增益:G = |h|^2 = |g|^2 * beta * (d/d0)^(-alpha)论文的仿真里经常用这个简化的信道增益做 SNR / SINR 计算,跟着做时不必把信道细化到每个抽头都仿真出来。2.3 用户配对策略NOMA 的核心增益来源是同一资源块上不同用户的信道增益差异。所以配对时默认规则是:信道条件好的用户分配低功率,作为近端用户,承担 SIC 先译码的角色;信道条件差的用户分配高功率,作为远端用户,在 SIC 最后被解出来,保证它的最低速率需求。具体配对算法(贪心实现):将所有蜂窝用户按信道增益降序排列;将所有 D2D 对按 D2D 链路信道增益降序排列;依次把信道增益最强的 D2D 对与信道增益最弱/最强的蜂窝用户配对(哪种更好取决于目标函数是最大化总速率还是保证公平性)。这个排序逻辑看起来简单,但它是后续所有资源分配算法的基础,一旦配对错了,后面功率分配再怎么优化也补不回来。3. 核心机制解读:SIC 译码顺序与 SINR 推导3.1 信号模型以第 m 个蜂窝用户 CU_m 的上行链路为例。CU_m 和 D2D 对 j 组成一簇,两者复用同一子信道 n。基站收到的叠加信号可以写成:y_BS = sqrt(P_m) * h_m * x_m + sqrt(P_j) * h_j * x_j + n_BS其中:P_m、P_j 分别是 CU_m 和 D2D 发射端 DT_j 的发射功率;h_m 是 CU_m 到基站的信道系数;h_j 是 DT_j 到基站的信道(这里注意,基站也会收到 D2D 发射端的信号,这对基站来说是干扰信号);n_BS 是基站处的加性高斯白噪声,功率谱密度为 N_0。D2D 接收端收到信号表示为:y_DR = sqrt(P_j) * h_jj * x_j + sqrt(P_m) * h_mj * x_m + n_DRh_jj 是 DT_j 到 DR_j 的 D2D 直连信道;h_mj 是 CU_m 到 DR_j 的干扰信道;n_DR 是 D2D 接收端的噪声。核心点:这其实是一个两用户的 NOMA 簇,只不过第二个用户不是另一个蜂窝用户,而是 D2D 链路。3.2 SIC 译码顺序的确定NOMA 的 SIC 译码顺序并不是随便定的。理论推导可以证明,为了最大化系统容量,应该按照信道增益从强到弱的顺序依次译码——信道强的用户先被译出并消除,信道弱的用户最后译出。这是因为信道强的用户本身信号质量好,容易译码成功,把它先消掉,就能更好解码弱用户的信号。假设在基站侧:|h_m|² > |h_j|²,即 CU_m 信道强于 DT_j 到基站的信道;那么 SIC 顺序为:基站先解码 CU_m 的信号,此时把 DT_j 的信号当作干扰;基站在解码 CU_m 后,将 CU_m 的信号做重建、相减、消除;再解码 DT_j 的信号,此时干扰只剩噪声。对应 SINR 表达式:CU_m 的 SINR:SINR_m = P_m * |h_m|^2 / (P_j * |h_j|^2 + N_0 * B)DT_j→BS 这条链路在 SIC 后的 SINR:SINR_j_BS = P_j * |h_j|^2 / N_0 * B在 D2D 接收端侧,直接解码 DT_j 的信号,CU_m 的信号是干扰:SINR_j_DR = P_j * |h_jj|^2 / (P_m * |h_mj|^2 + N_0 * B)我见过不少刚入门的人犯同一个错误——把基站侧和 D2D 接收端的 SINR 混在一起算。记住:这是两条链路,但只有一个是 NOMA 簇内的 SIC 关系,另一个是纯干扰受限链路。搞混了,后面中断概率能算错 3 个数量级。3.3 可达速率的表达式根据香农公式,可达速率:R_m = B * log2(1 + SINR_m) R_j = B * log2(1 + SINR_j_DR)系统总速率:R_total = sum(R_m) + sum(R_j)这里的 B 是子信道带宽。注意,由于 D2D 是复用蜂窝频谱的,它在速率计算中不单独占用新的带宽资源。这个特点正是 D2D 增益的来源——不增加带宽的情况下多了一路传输。4. 关键约束条件与目标函数4.1 必列的约束条件论文里做优化时,约束条件通常长这样:约束1(保证SIC可行): R_m >= R_min 约束2(满足D2D QoS): R_j >= R_j_min 约束3(发射功率非负且有上界): 0 <= P_m <= P_max_BS, 0 <= P_j <= P_max_D2D 约束4(信道分配互斥): 一个子信道在同一时刻最多只能被一个簇复用约束 1 很重要,如果 CU_m 的速率都达不到最小要求,那么 SIC 第一层就会解码失败,整个簇都崩了。所以功率分配的首要原则不是最大化总速率,而是先保 SIC 的可行性。4.2 常见目标函数基础模型中常做的优化目标有三种:目标数学形式适用场景最大化系统和速率max sum(R_m + R_j)吞吐量优先最大化最小速率max min(R_m, R_j)公平性优先最小化总功率min sum(P_m + P_j)节能 / 干扰控制没有绝对的“最优目标”,只有适不适合当前场景。做基础复现的时候,先从最大化系统和速率开始,因为最直观、最容易验证。4.3 一个关键权衡:公平性与总速率的对抗NOMA 的经典研究结论**“用户的信道条件差异越大,NOMA 相对 OMA 的增益越大”**,在 NOMA+D2D 场景里同样成立。信道差异越大的簇,SIC 越容易实现,弱用户的增益越明显;反过来,如果两个用户信道条件太接近,SIC 增益很小,还要额外承受接收机复杂度,这时 OMA 反而更优。这引出一个非常实用的设计准则:在配对时优先选信道差异大的用户组簇。如果簇内两个用户的信道增益比小于某个阈值(比如 3 dB),这个簇就不要建了,直接用 OMA 方式通信,总性能可能更好。这个准则很多论文里不会明说,但实测下来对系统性能影响极大。5. 仿真实现与代码级落地5.1 仿真场景参数照着基础模型复现时,我常用的参数如下:参数值小区半径500 m子信道带宽15 kHz子载波数1(单载波)蜂窝用户数 M4D2D 对数量 N4蜂窝用户最大功率23 dBmD2D 发射功率10~20 dBm路径损耗指数3.5噪声功率谱密度-174 dBm/Hz用户最小速率要求0.5 bps/Hz仿真用 MATLAB 或者 Python 都可以。如果只是想验证模型趋势,Python 就够了,不用上重型仿真平台。5.2 Python 仿真核心流程仿真流程可以这样拆:随机撒点生成用户位置,计算距离;生成瑞利衰落信道增益(复数高斯采样取模平方);计算信道增益 |h|² 并排降序;按贪心规则配对簇;分配功率——这里可以先固定等功率,再逐步验证功率分配的效果;计算 SINR 和速率;重复 10000 次 Monte Carlo,取平均。核心代码片段如下(可直接替换成自己的实现):import numpy as np R_cell = 500.0 alpha = 3.5 N0 = -174 B = 15e3 # 生成用户位置 def gen_users(n): angles = 2 * np.pi * np.random.rand(n) radii = R_cell * np.sqrt(np.random.rand(n)) return radii * np.cos(angles), radii * np.sin(angles) # 生成瑞利信道增益 def gen_channel_gain(d, alpha=3.5): h_small = (np.random.randn() + 1j * np.random.randn()) / np.sqrt(2) pl = d ** (-alpha / 2) return (np.abs(h_small) ** 2) * (pl ** 2) # 计算 SINR def compute_sinr(P_sig, P_int, G_sig, G_int, N0_dbm, B): N0 = 10 ** ((N0_dbm - 30) / 10) * B return (P_sig * G_sig) / (P_int * G_int + N0)注意:噪声功率的计算很容易出错。dBm 要先减去 30 变成 dBW,再转成线性值乘带宽,换算公式:N_lin = 10^((N0_dbm - 30) / 10) * B这个细节能直接决定你仿真的绝对工作点是否正确,虽然不影响相对趋势,但影响和论文结果对比的可信度。5.3 仿真结果验证方法判断仿真是否正确,最简单的验证:等功率情况下,信道增益最强的用户应当获得最大速率——如果结果不符合直觉,大概率是配对或信道生成弄错了;没有 D2D 用户的场景直接退化成纯 NOMA,速率应等于传统 NOMA 结果;D2D 发射功率趋近于 0时,D2D 速率应趋近于 0,同时蜂窝用户的速率趋近于没有 D2D 干扰的情况。我每次跑新代码都会先做这三个 sanity check,确认没问题再继续调算法。6. 典型问题与避坑记录6.1 干扰链路被忽略最常见的问题就是只算了蜂窝链路和 D2D 链路各自的 SINR,忘了 D2D 发射端对基站、蜂窝用户对 D2D 接收端的干扰。这两条干扰链路在功率接近时影响巨大。干扰链路影响对象影响程度DT → BS基站解码 CU 信号高CU → DRD2D 接收端解码高BS → DRD2D 接收端(下行干扰)中尤其当 D2D 发射功率较高或 D2D 对距离蜂窝用户很近时,干扰会造成系统性速率下降。处理方式通常是做功率控制,而不只是调信道分配。6.2 D2D 复用蜂窝频谱的下行/上行选择基础模型的默认选择是复用上行频谱。原因是:上行频谱在基站端相对空闲,干扰更好控制;基站本身是功率充足的节点,它在下行方向上对 D2D 接收端的干扰非常强,复用下行频谱对功率分配要求苛刻得多。如果你在论文里看到有人说复用下行频谱,关注一下他们有没有做基站侧的功率控制和波束赋形,如果没有,可以用审稿人视角先质疑一下,再自己跑仿真验证。6.3 SIC 的误码传播效应SIC 的模型里有个隐含假设:前一层译码是完美译码。但实际系统译码后会有残留误差,这个误差会传导到后面的解码阶段,这就是“误差传播”效应。基础模型阶段,大多数论文用理想 SIC 假设;到了实际系统设计,需要在 SINR 公式里加一个残余干扰因子,通常表示为:SINR_m = P_m * G_m / (P_j * G_j * eta + N0)其中 eta 是残余干扰系数,通常取 0.01~0.1。等做到基于实测信道模型的系统级仿真时,你会回头看这个系数的。6.4 用户配对策略对结果影响巨大配对策略决定了簇内的信道差异,进而决定了 SIC 的可行性。这里提供三种常见的配对方式:随机配对:最简单的 baseline,性能最差;按信道增益排序配对:强信道用户配弱信道用户,性能中等,适用于公平性优先场景;最优配对:通过匈牙利算法等做指派问题求解,性能最稳定,但计算复杂度高。如果某篇论文只给出了“通过穷举找到最优配对”的说法,并没有给出具体的配对算法步骤,那这部分你大概率要自己补——这也是复现 NOMA+D2D 文献最耗时的地方。7. 给复现者的一条实用建议这个基础模型我带着不同背景的人搭过很多遍,总结一句:在动手写代码之前,先用手推一遍两个用户的闭式解。怎么做:假设 M = 1、N = 1,给定功率 P_m、P_j 和两组信道增益,直接在纸上推出 SINR、速率、以及满足 QoS 的功率可行域。然后再上代码。这个“推公式—写代码—对比趋势”的流程,基本能帮你避开 80% 的建模错误。基础模型是所有进阶内容的锚点。后续无论产品里谈资源调度、博弈论定价、多天线 MIMO-NOMA,还是智能反射面辅助的 NOMA+D2D,本质上都在这个模型骨架上加东西。把这个骨架理解透了,后面所有论文里的“改进”“创新”读起来就是在看“在哪个模块做了什么手脚”,看一眼就能明白个大概。下一篇笔记里,我会在这个基础模型中加入功率分配的闭式解推导,把 Karush-Kuhn-Tucker 条件应用到 NOMA+D2D 簇的优化问题上,并给出完整推导流程,到时候继续记录。