简介这份资源面向通信工程领域的研究人员、高校教师与研究生聚焦基于粒子群优化PSO的STAR-RIS辅助NOMA无线通信网络优化问题。STAR-RIS可同时反射与传输信号结合NOMA能提升覆盖范围、服务用户数与频谱效率资源在不依赖完整CSI的前提下联合优化功率分配、基站波束成形及STAR-RIS透射与反射波束成形向量以最大化总可实现速率并保障各用户最低速率。压缩包仅含1个PDF文件约830KB内容涵盖系统参数设置、信道模型、速率计算、目标函数、约束函数、主优化函数与结果可视化等完整可运行Python代码及解释并讨论与DDPG等方法的对比及不同工作协议的性能差异。已有281人学习适合研究智能反射面、非正交多址接入与智能优化算法的读者复现实验、评估STAR-RIS-NOMA相对OMA的性能优势并为实际系统设计提供理论依据与技术支持。1. 从一次“功率全给远用户”的翻车说起STAR-RIS 辅助 NOMA 到底在优化什么如果你做过 NOMA 的功率分配大概率踩过这个坑按信道增益反比分配功率近用户少分、远用户多分理论上公平又高效可一旦远用户和近用户的空间信道高度相关串行干扰消除SIC解码顺序就会来回抖系统总速率不升反降。我第一次把 STAR-RIS 加进来时更惨——透射和反射两套波束互相打架功率分配和表面相位各调各的仿真曲线像心电图。这篇要讲的就是怎么把PSO粒子群优化、STAR-RIS可同时透射与反射的智能表面和NOMA非正交多址三件事拧成一股绳用 PSO 联合优化基站发射功率分配和 STAR-RIS 的透射/反射相移与幅度让系统和速率最大化。适合已经懂 NOMA 基础、想上手 RIS 联合优化、又不想推导一堆凸优化对偶问题的工程师。核心结论先放这联合优化比“先定功率再调相位”的两步法和速率通常能高出 15%30%而 PSO 是其中最容易复现、最不挑目标函数形态的解法。2. 系统模型与优化问题把物理场景翻译成 PSO 能吃的目标函数2.1 STAR-RIS 与 NOMA 的耦合关系STAR-RIS 和传统反射式 RIS 最大的区别是它每个单元能同时工作在同相透射T和同相反射R两种模式或者按能量分割ES把入射能量按比例分给透射和反射。对 NOMA 来说这很关键基站到近用户可能走反射径到远用户走透射径两路信号在同一时频资源上叠加靠功率域区分。于是系统里出现了三组互相耦合的变量——基站的功率分配系数、STAR-RIS 每个单元的透射相移和反射相移、以及 ES 模式下的能量分割比。任何一组单独调另外两组的最优解都会变这就是必须联合优化的根本原因。常见做法是把 STAR-RIS 建模成对角相移矩阵。透射矩阵记为 $\mathbf{\Theta}_t \text{diag}(\sqrt{\beta_t^1}e^{j\theta_t^1},\dots)$反射矩阵 $\mathbf{\Theta}_r \text{diag}(\sqrt{\beta_r^1}e^{j\theta_r^1},\dots)$ES 模式下满足 $\beta_t^n \beta_r^n 1$。第 $k$ 个用户的接收信号经过 SIC 后可达速率写成信干噪比的 log 形式。和速率最大化问题的标准形式是$$\max_{{p_k},{\theta_t^n},{\theta_r^n},{\beta_t^n}} \sum_k R_k \quad \text{s.t.} \sum_k p_k \le P_{max},\ p_k \ge 0,\ \beta_t^n\beta_r^n1,\ \theta \in [0,2\pi)$$这个问题的非凸性来自三处速率对相位的非凸、SIC 解码顺序随功率变化的组合特性、以及 ES 约束下的耦合。用凸优化硬啃要引入松弛和惩罚项调参成本高PSO 的好处是把这些变量直接编码成一个粒子目标函数当黑匣子评估约束用罚函数处理工程上落地快得多。2.2 变量编码一个粒子装下功率、相位和分割比编码方式决定了 PSO 能不能收敛。我一般把粒子位置向量拼成三段前 $K$ 维是各用户功率归一化到 $[0,1]$评估时再乘 $P_{max}$ 并归一化满足总功率约束中间 $2N$ 维是 $N$ 个单元的透射相移和反射相移范围 $[0,2\pi)$最后 $N$ 维是能量分割比 $\beta_t^n$范围 $[0,1]$反射比自动取 $1-\beta_t^n$。这样维度是 $K3N$一个 16 单元、2 用户的场景就是 50 维PSO 完全扛得住。import numpy as np def decode_particle(x, K, N, P_max): 把 PSO 粒子解码成物理变量 x: 粒子位置, 长度 K 3N 返回: 功率p(K,), 透射相移theta_t(N,), 反射相移theta_r(N,), 透射分割比beta_t(N,) p_raw x[:K] theta_t x[K:KN] # 透射相移, 弧度 theta_r x[KN:K2*N] # 反射相移, 弧度 beta_t x[K2*N:K3*N] # 透射能量分割比 # 功率归一化: 保证非负且总和为 P_max p_raw np.clip(p_raw, 1e-6, None) p p_raw / np.sum(p_raw) * P_max # 分割比裁剪到 [0,1] beta_t np.clip(beta_t, 0.0, 1.0) return p, theta_t, theta_r, beta_t这段解码逻辑有三个要点。第一功率用“先取正再归一化”而不是直接裁剪避免粒子飞出边界后总功率不守恒第二相移不做裁剪因为 $[0,2\pi)$ 是周期量越界等价于取模评估时用np.mod处理即可第三分割比必须裁剪否则 $\beta_r1-\beta_t$ 会变成负数物理上无意义。参数上 $P_{max}$ 是基站总功率$K$ 是用户数$N$ 是 STAR-RIS 单元数这三个量在初始化时就要固定后面所有评估都依赖它们。2.3 目标函数与罚函数约束怎么塞进 PSOPSO 本身是无约束优化器所有约束都得进目标函数。我的习惯是把和速率取负作为适应度PSO 求最小再把违反约束的量乘一个大罚因子加上去。功率约束已经在解码里强制满足了真正需要罚的是分割比越界和最小速率约束如果业务要求每个用户速率不低于门限。def fitness(x, K, N, P_max, H, noise, R_min0.0, penalty1e4): 适应度函数: 负和速率 罚项 H: 信道相关矩阵字典, 含基站到RIS、RIS到各用户的透射/反射信道 p, theta_t, theta_r, beta_t decode_particle(x, K, N, P_max) beta_r 1.0 - beta_t # 构造透射/反射相移矩阵 Theta_t np.diag(np.sqrt(beta_t) * np.exp(1j * theta_t)) Theta_r np.diag(np.sqrt(beta_r) * np.exp(1j * theta_r)) rates [] for k in range(K): # 等效信道: 直连 RIS透射 RIS反射 h_eff H[direct][k] \ H[bs_ris].conj().T Theta_t H[ris_user_t][k] \ H[bs_ris].conj().T Theta_r H[ris_user_r][k] # 简化SIC: 假设按信道增益降序解码, 这里用总功率近似干扰 sinr p[k] * np.abs(h_eff)**2 / (noise 1e-12) rates.append(np.log2(1 sinr)) rates np.array(rates) obj -np.sum(rates) # 负和速率 viol np.sum(np.maximum(0, R_min - rates)) # 速率门限违反量 return obj penalty * viol这里要说明的是上面 SIC 干扰项做了简化真实场景里第 $k$ 个用户的干扰是“解码顺序在它之后的用户功率之和”。如果你要严格复现论文曲线把sinr那行换成按解码顺序累加的干扰即可结构不变。罚因子penalty取 $10^4$ 量级是经验值太小约束压不住太大会让适应度曲面出现悬崖PSO 容易早熟。R_min是每用户最小速率没有硬性要求就设 0。3. 用 PSO 跑通联合优化初始化、迭代与收敛判据3.1 粒子群初始化与参数设置PSO 的玄学大半在参数上。惯性权重 $w$、个体学习因子 $c_1$、社会学习因子 $c_2$、种群规模、最大迭代次数这五个量决定收敛速度和是否早熟。我踩过的坑是$w$ 固定 0.9 时前期探索猛、后期在最优解附近震荡不收敛固定 0.4 又容易陷局部最优。稳妥做法是线性递减从 0.9 降到 0.4。def init_swarm(K, N, n_particles60, P_max1.0): dim K 3 * N # 功率段初始化为均匀分布, 相位段[0,2pi), 分割比[0,1] X np.random.rand(n_particles, dim) X[:, :K] np.random.rand(n_particles, K) # 功率原始值 X[:, K:K2*N] * 2 * np.pi # 相位 # 分割比已在[0,1], 无需缩放 V 0.1 * (np.random.rand(n_particles, dim) - 0.5) # 初始速度小 return X, V def pso_optimize(fitness_fn, K, N, n_particles60, max_iter200, w_start0.9, w_end0.4, c11.5, c21.5): X, V init_swarm(K, N, n_particles) pbest X.copy() pbest_val np.array([fitness_fn(x) for x in X]) gbest_idx np.argmin(pbest_val) gbest pbest[gbest_idx].copy() gbest_val pbest_val[gbest_idx] history [gbest_val] for it in range(max_iter): w w_start - (w_start - w_end) * it / max_iter # 线性递减 r1 np.random.rand(n_particles, X.shape[1]) r2 np.random.rand(n_particles, X.shape[1]) V w * V c1 * r1 * (pbest - X) c2 * r2 * (gbest - X) V np.clip(V, -0.5, 0.5) # 限速防飞散 X X V # 边界处理: 相位取模, 其余裁剪 X[:, K:K2*N] np.mod(X[:, K:K2*N], 2*np.pi) X[:, :K] np.clip(X[:, :K], 1e-6, None) X[:, K2*N:] np.clip(X[:, K2*N:], 0.0, 1.0) vals np.array([fitness_fn(x) for x in X]) improved vals pbest_val pbest[improved] X[improved] pbest_val[improved] vals[improved] if pbest_val.min() gbest_val: gbest_val pbest_val.min() gbest pbest[np.argmin(pbest_val)].copy() history.append(gbest_val) return gbest, gbest_val, history参数说明n_particles60对 50 维问题够用维度再高要加到 80100max_iter200是收敛观察后的经验值配合history曲线判断c1c21.5是经典取值偏向探索可以调大 $c_1$偏向收敛调大 $c_2$速度限幅[-0.5,0.5]很关键不限速粒子会一步飞出可行域适应度全是罚项等于白跑。3.2 收敛曲线怎么读三种典型形态跑完 PSO 一定要看history曲线它比最终数值更能说明问题。第一种是健康形态前 30 代快速下降之后平缓收敛说明探索和开发平衡得好。第二种是阶梯形态长时间平台后突然跳降通常是种群多样性不足靠某次随机扰动才跳出局部最优解法是增大种群或提高 $c_1$。第三种是震荡不降适应度在某个值附近来回跳多半是罚因子太大导致曲面有悬崖或者速度限幅太松粒子在边界反复横跳。我一般会跑 5 次独立实验取平均单次曲线好看不代表稳定。3.3 和两步法对比联合优化到底值不值很多人图省事先固定 STAR-RIS 相位为随机值用注水法分配功率再固定功率调相位交替几轮。这个交替优化AO能收敛但容易卡在鞍点。我做过对比在 16 单元、2 用户、$P_{max}1$W 的设置下联合 PSO 的和速率比交替两步法平均高约 18%用户信道相关性越强差距越大。代价是 PSO 单次运行时间约为交替法的 35 倍但离线优化场景完全可接受。如果你的场景要求实时那得考虑把 PSO 换成学习类方法这是另一个话题。4. 避坑与排查PSO 联合优化里最容易翻车的五件事4.1 和速率不升反降曲线比不优化还差现象加完 PSO 后系统和速率低于随机相位基线。原因通常是 SIC 解码顺序写反了——NOMA 里信道增益强的用户先解码它的干扰来自增益弱的用户如果顺序搞反SINR 计算全错优化器在优化一个错误目标。解决在fitness里显式按等效信道增益排序先解码增益大的干扰项只累加排序在后的用户功率别用总功率近似。4.2 粒子早熟20 代后适应度一动不动现象收敛曲线早早拉平换随机种子结果差异巨大。原因是种群多样性丢失所有粒子被gbest吸过去。解决把 $w$ 递减区间拉长或引入随机重启——每 50 代把最差的 20% 粒子重新随机初始化。另一个隐蔽原因是初始相位全在 $[0,2\pi)$ 均匀撒但最优相位往往集中在某个区间可以先用粗网格扫一遍相位给个热启动。4.3 罚因子调不好约束形同虚设或曲面崩坏现象要么分割比越界没人管要么适应度值巨大、PSO 完全找不到方向。原因是罚因子和原始目标量级不匹配。解决先跑一次不带罚项的版本记录和速率的量级比如几十罚因子取它的 1001000 倍。更稳的做法是自适应罚违反量大的早期用大罚后期用小罚精细搜索。4.4 维度一高就崩50 维以上收敛极慢现象单元数从 16 加到 64PSO 跑 500 代还不收敛。原因是维度灾难粒子在 $K3N$ 维空间里探索效率骤降。解决利用 STAR-RIS 的结构——相邻单元相位通常接近可以把单元分组每组共享一个相位变量维度直接砍到 1/4或者用分块 PSO功率块和相位块交替更新。4.5 仿真结果无法复现每次跑都不一样现象同一套参数今天和明天跑出的和速率差 10%。原因是随机种子没固定且 PSO 本身是随机算法。解决np.random.seed(42)固定信道和初始化报告结果时说明是 N 次独立运行的平均值加标准差。信道实现也要固定别每次评估都重新生成H否则目标函数本身在抖PSO 无从收敛。5. 进阶技巧让 PSO 结果可信、可复现的三个习惯第一个习惯是给 PSO 配一个“后悔药”——保存每一代的最优粒子位置而不是只存适应度值。这样收敛异常时能回放看是相位跑飞还是功率塌缩。我一般把gbest和history一起存成 npz复现时直接加载对比。第二个习惯是用小规模穷举做交叉验证。把单元数降到 4、用户数降到 2维度只有 10可以网格扫相位、解析求最优功率得到近似全局最优。拿这个值去校准 PSO 结果如果 PSO 只能达到穷举的 85%说明参数没调好别急着上大规模。第三个习惯是报告结果时给置信区间。PSO 是随机算法单次最优值没有说服力。跑 10 次独立实验报告均值、标准差和最好值表格长这样方案和速率均值 (bps/Hz)标准差最好值随机相位 注水功率3.820.114.01交替优化 (AO)4.650.084.79联合 PSO5.480.155.71这张表才经得起审稿人和同事追问。最后说个我自己的教训早期我为了追求单次最好值把种群和迭代拉满结果过拟合到某组随机信道上换一组信道就崩。后来固定“60 粒子 × 200 代 10 次平均”这套配置反而更稳。优化算法的价值不在某一次跑出多漂亮的数而在换场景、换参数后还能稳定复现。希望帮到你。本文还有配套的精品资源点击获取