拓冰建站拓冰建站
首页 / 资讯中心 / 正文

柯西量子粒子群优化LTE基站覆盖率:原理与Matlab实现

前阵子终于把一个拖延了很久的项目完整收尾了基于柯西分布量子粒子群优化的LTE网络基站覆盖率求解代码全部用Matlab实现。老实说最初看到这个题目我以为是普通PSO换个名字包装一下真动手建模才发现坑不少。LTE网络覆盖问题本身是典型的非线性、多峰值工程优化问题基站发射功率一调周围一圈栅格的RSRP全部跟着变目标函数极其不光滑常规梯度类方法根本无从下手。而标准粒子群又容易早熟跑着跑着就停在某个局部最优附近不动了。后来我在量子粒子群优化QPSO里引入柯西分布做扰动效果提升非常明显。这篇文章我会把这个项目完整拆开从LTE覆盖问题建模、QPSO算法原理、柯西分布改进动机到Matlab代码实现、实验对比和调参避坑一条线讲清楚。代码和参数都是我实际跑过的适合通信方向的学生、做网络规划优化的工程师以及研究群体智能算法的同学参考。你不用完全照抄理解思路后改成自己的问题模型就行。1. 项目背景LTE基站覆盖优化到底在优化什么1.1 覆盖率不好是谁的锅LTE网络覆盖评估里最常听到的词就是弱覆盖、覆盖空洞、重叠覆盖、越区覆盖。普通用户感知到的“信号差”在网络规划工程师眼里其实是一组可以量化的指标其中最基础的就是RSRP参考信号接收功率。我们把研究区域划分成一个个栅格每个栅格算出一个最强RSRP超过门限就算被覆盖。基站覆盖优化的核心目标就是在成本和干扰可控的前提下让“被覆盖的栅格数 / 总栅格数”尽可能高。这个比例就是覆盖率本文把它作为优化目标。听起来很简单真算起来非常麻烦每个基站的发射功率改变后周围几十上百个栅格的RSRP都会变不同基站的影响区域互相重叠调一个站可能会破坏另一个站辛辛苦苦覆盖好的区域功率拉得越高覆盖越广但同时重叠覆盖也越严重终端干扰反而变大。我用的方法是固定基站位置把各基站发射功率作为决策变量用群体智能算法去寻找一组最优功率组合达到覆盖率最大化。1.2 为什么这个问题必须用智能优化算法解这问题看似只是一个“调参数”的问题实际困难在于第一目标函数没有解析梯度栅格离散化以后 RS RP 本身就是逐点比较再取最大值这个函数不连续、处处不可导梯度下降和牛顿法完全没法用第二搜索空间很大基站数量稍微多一点功率组合的规模就是天文数字枚举法和网格搜索根本不现实第三目标函数多峰非常严重局部最优解一大堆随便用一个贪心策略很容易陷入某个角落出不来。群体智能优化算法恰好是围绕这些问题设计的不依赖梯度信息对目标函数只要求“能算出一个数”种群并行搜索天然具备跳出局部最优的能力实现简单加约束方便功率上下界直接用粒子边界钳制就行。这也是近些年类似项目普遍采用PSO、遗传算法、差分进化这些群体的核心原因。1.3 我从标准PSO换成量子粒子群的原因最早我实现的是标准PSO测试下来发现两个问题一是参数太敏感惯性权重w、个体学习因子c1、群体学习因子c2三组参数在不同基站数量下表现差异很大想要好结果得反复调二是迭代后期粒子全部向全局最优靠拢速度越来越小种群多样性很快丢失一旦全局最优是个局部极值整个群体就彻底困住了。后来改用QPSO控制参数只剩一个收缩扩张系数beta从1.0线性递减到0.4左右就能跑出不错的结果省掉了大量调参工作。再进一步引入柯西分布以后粒子在后期还能保持一定的“跳跃能力”这才是这个项目的核心改进点。2. 算法原理拆解从PSO到QPSO再到柯西改造2.1 标准PSO为什么容易“死掉”标准PSO里每个粒子有两个属性位置X和速度V。每次迭代速度由三部分决定上一时刻速度、飞向自身历史最优pbest的倾向、飞向全局最优gbest的倾向。迭代次数多了以后所有粒子都被“拉”到当前全局最优附近速度逐渐趋近于零整个群体丧失探索新区域的能力。这就是所谓的搜索停滞算法表面上还在跑实际上所有粒子都在同一个点附近抖动。LTE覆盖这个目标函数局部极值非常多一旦gbest落在局部极值里标准PSO基本就交代了。2.2 QPSO的核心不需要速度的粒子QPSO的出发点很有意思它不再把粒子当成牛顿力学下的物体而是当成量子空间里有不确定性的微观粒子用薛定谔方程来描述粒子出现在某个位置的概率。量子粒子没有速度和位移的概念位置更新完全由波动方程决定。落到工程实现上QPSO其实只干了几件事维护每个粒子的个体历史最优pbest计算所有pbest的平均值得到mbest平均最优位置用一个随机混合点P连接pbest和gbest根据公式 X P ± beta * |mbest - X| * ln(1/u) 更新位置其中u是(0,1)内的均匀分布随机数beta就是收缩扩张系数。关键在mbest这个量它相当于整个群体的“平均记忆”。当某个粒子想飞得离群体太远时mbest会把它拉回来反过来当粒子聚成一团时随机项结合beta又能让部分粒子向外发散。beta大于1时粒子倾向于发散探索小于1时倾向于收敛到mbest附近。所以QPSO实际上通过一个参数就能调节勘探和开发的平衡相比标准PSO的三个参数好调得多。2.3 柯西分布的长尾为什么会起作用QPSO虽然比PSO稳健但后期依然可能被困在局部最优原因在于公式里ln(1/u)服从指数分布这个分布的尾巴衰减很快产生大幅度扰动的概率不高。我引入柯西分布的原因很简单它的尾巴比正态分布和指数分布都厚得多。用大白话说柯西分布是一个“平时待在中心但偶尔会抽风跳出去很远”的随机数生成器。如果用柯西分布的采样值替换QPSO位置更新里的一部分随机量粒子绝大多数时候还是正常更新但会以小概率迈出非常大的一步。这一步如果落在某个局部最优区域外面粒子就能逃出生天继续搜索新的更好区域。这个思路实施起来不复杂但效果立竿见影。我在代码里实际采用的是把柯西随机数叠加到QPSO位置更新项上作为补充扰动而不是完全替换原有的指数随机游走。这样既保留了QPSO框架的理论优势又额外增加了逃逸能力。2.4 我采用的柯西改进位置更新公式实际代码里QPSO中每个粒子的第j维位置更新为先随机产生P_local rand * pbest (1 - rand) * gbest再计算mbest 所有pbest的平均值最后位置X_new P_local ± beta * |mbest - X_old| * ln(1/u)增加柯西扰动项X_new X_new lambda * tan(pi * (rand - 0.5)) * (mbest - X_old)。其中tan(pi * (rand - 0.5))就是Matlab里生成标准柯西随机数的常用技巧lambda是扰动幅度系数。这一次改动会带来两个效果扰动幅度完全由mbest和当前粒子位置的差控制距离远时扰动大距离近时扰动小同时柯西分布的厚尾特性确保偶尔会出现大幅度跳跃而不是像高斯扰动那样“总在一个温和范围内活动”。3. Matlab代码实现从建模到出图一次跑通3.1 整体代码结构与运行流程我建议把工程拆分成四个文件职责清晰后期改起来方便run_main.m主脚本定义研究区域、基站坐标、栅格化参数、算法参数调用目标函数和优化算法输出结果图和统计表格calcCoverage.m覆盖率目标函数输入一组功率向量输出目标值覆盖率加惩罚项cqpso_optimize.m柯西量子粒子群优化主程序可以同时实现QPSO和CQPSO用开关参数控制是否启用柯西扰动plotResults.m可视化脚本画RSRP覆盖热力图、收敛曲线、基站位置以及优化前后的覆盖对比。主脚本调用顺序非常直观先参数初始化再循环调用目标函数进行适应度评估算法结束后把最优解传给可视化脚本。整个项目跑下来也就百来行核心代码但每一行都值得细看。3.2 覆盖率目标函数栅格、路径损耗和RSRP的计算计算覆盖率的第一步是栅格化。我的项目把研究区域设为3km x 3km栅格分辨率取50m每个栅格的中心点代表该区域的信号接收位置。3km x 3km / 50m就是60 x 60总共3600个栅格点。这个分辨率兼顾了计算速度和空间精度如果你的区域更大建议先粗跑再精调。RSRP的计算这里简化成发射功率减去路径损耗再扣除收发天线增益等固定余量实际工程还要考虑阴影衰落余量但作为算法验证模型确定性路径损耗足够了。路径损耗用COST231-Hata模型公式如下PL 46.3 33.9 * log10(f) - 13.82 * log10(hb) - a(hm) (44.9 - 6.55 * log10(hb)) * log10(d / 1000) Cm在这个公式里f是频率单位MHzLTE用2000MHzhb是基站天线高度单位米我取30mhm是终端高度单位米取1.5md是基站到栅格点的距离单位是米注意log10里面要转成km这是最容易踩坑的地方a(hm)是终端高度修正因子城区环境取3.2 * (log10(11.75 * hm))^2 - 4.97Cm是城市修正因子中等城市取0dB。计算RSRP时每个栅格点先对每个基站算一个接收功率然后取最大值作为该栅格的最强RSRP。覆盖率就是最强RSRP大于-110dBm的栅格数占总栅格数的比例。我这里给出目标函数的Matlab核心代码function [fitness, rsrpMat] calcCoverage(powerVec, gridXY, bsXY, params) % powerVec: 各基站发射功率(dBm) % gridXY: Nx2每个栅格中心的x,y坐标 % bsXY: Mx2基站坐标 M size(bsXY, 1); N size(gridXY, 1); rsrpMat -inf(N, M); % 每个栅格对每个基站的RSRP for i 1:M d sqrt((gridXY(:,1) - bsXY(i,1)).^2 (gridXY(:,2) - bsXY(i,2)).^2); d max(d, 30); % 防止距离过近导致路径损耗为负 pl 46.3 33.9*log10(params.freq) ... - 13.82*log10(params.hb) - params.aHm ... (44.9 - 6.55*log10(params.hb)) * log10(d/1000) ... params.Cm; rsrpMat(:, i) powerVec(i) - pl; end bestRsrp max(rsrpMat, [], 2); coverFlag bestRsrp params.rsrpThresh; coverage mean(coverFlag); % 基础覆盖率 % 重叠覆盖惩罚同一栅格如果被超过2个基站强覆盖说明重叠严重 strongCount sum(rsrpMat params.rsrpThresh, 2); overlapPenalty mean(strongCount 2); fitness coverage - params.lambdaOverlap * overlapPenalty; end注意我把目标函数设计成了“覆盖率减去重叠覆盖惩罚”否则粒子一定会把功率全部拉到上限来骗取高覆盖率。这个惩罚项非常重要后面避坑部分还会细说。3.3 QPSO和CQPSO主算法实现算法主体部分用矩阵化编程避免对每个粒子循环Matlab跑起来才够快。粒子编码为M维向量每一维就是对应基站的发射功率范围限定在30到46dBm之间。QPSO的位置更新核心代码如下function [bestX, bestFit, curve] cqpso_optimize(fun, dim, lb, ub, opts) ps opts.popSize; % 种群规模 maxIter opts.maxIter; % 最大迭代次数 betaMax 1.0; betaMin 0.4; useCauchy opts.useCauchy; cauchyLambda opts.cauchyLambda; X repmat(lb, ps, 1) rand(ps, dim) .* (repmat(ub - lb, ps, 1)); pbest X; fitness zeros(ps, 1); for i 1:ps fitness(i) fun(X(i,:)); end pbestFit fitness; [bestFit, idx] max(fitness); bestX X(idx, :); curve zeros(maxIter, 1); for t 1:maxIter beta betaMax - (betaMax - betaMin) * t / maxIter; mbest mean(pbest, 1); for i 1:ps phi rand(1, dim); P phi .* pbest(i,:) (1 - phi) .* bestX; u rand(1, dim); u(u 0) eps; if rand 0.5 X(i,:) P beta .* abs(mbest - X(i,:)) .* log(1 ./ u); else X(i,:) P - beta .* abs(mbest - X(i,:)) .* log(1 ./ u); end if useCauchy cauchyVar tan(pi * (rand(1, dim) - 0.5)); X(i,:) X(i,:) cauchyLambda .* cauchyVar .* (mbest - X(i,:)); end % 边界钳制 X(i,:) max(X(i,:), lb); X(i,:) min(X(i,:), ub); newFit fun(X(i,:)); if newFit pbestFit(i) pbestFit(i) newFit; pbest(i,:) X(i,:); end if newFit bestFit bestFit newFit; bestX X(i,:); end end curve(t) bestFit; end end这段代码里我做了几件关键的事粒子位置初始化用均匀随机铺满可行域避免初始就扎堆边界处理直接用钳制到上下界简单粗暴但有效柯西扰动项用的是(mbest - X)做幅度参考这样粒子离群体中心越远扰动反而越大帮助粒子探索更远区域。3.4 实验参数设置和公平对比方案我当时设计了标准PSO、QPSO、CQPSO三组对比实验参数我用表格整理出来算法种群规模迭代次数关键参数独立运行次数标准PSO40150w0.6c1c21.810QPSO40150beta从1.0线性降到0.410CQPSO40150beta同上lambda0.510三种算法在完全相同的问题模型、相同的初始覆盖条件、相同的迭代次数下运行每组独立跑10次记录最好值、平均值、最差值和标准差。为什么要跑10次因为群体智能算法带有随机性单次结果不能说明任何问题只有统计结果才能看出算法是否稳定。这个实验设计是论文和报告中体现说服力的关键千万别省。4. 实验结果和可视化分析4.1 三种算法的收敛过程对比跑完以后收敛曲线的差别很明显。标准PSO在前30代爬升很快但大约60代以后曲线基本就平了偶尔还能看到它卡在一个局部最优值附近上下抖动很难再获得质的提升。QPSO整体稳定性比PSO好前期略慢但后期还在稳步上升最终覆盖率比PSO高了不少。CQPSO是最有意思的前期它不一定是最快的因为柯西扰动有时候会产生大幅度跳跃导致适应度波动但迭代到中后期特别是100代往后其他算法都已经收敛停滞时CQPSO还能持续更新最优解。这说明柯西分布的长尾扰动在后期维持了种群多样性让粒子有机会跳出原来的局部极值找到更好的功率组合。从数值上看CQPSO的最终覆盖率通常能比QPSO高出几个百分点这个差距在覆盖工程里非常重要因为3%的覆盖率提升可能意味着少建一座基站。4.2 覆盖热力图怎么画更能说明问题只靠一组收敛曲线说服力不够覆盖热力图才是能直观说明“优化到底改了什么”的重要工具。我建议用pcolor或者imagesc来画自己写一个plotRaster函数输入RSRP矩阵和基站坐标输出带有覆盖门限色标的热力图。画图时有几个小技巧色标范围固定比如从-130dBm到-70dBm这样优化前后的图才可以视觉对比在最优RSRP矩阵里叠加一个半透明的判断层RSRP小于-110dBm的区域用明显颜色标出来基站位置用三角形或圆形标出来方便对照“哪个站覆盖了哪片区域”。优化前后的对比图非常直观初始状态往往边缘栅格一片蓝紫色表示RSRP低于门限属于弱覆盖区域优化后这些区域明显缩小同时中心区域也没有出现过度的红色高亮说明功率分配更均衡没有造成严重的重叠覆盖。4.3 统计结果表和物理可解释性最后我把10次运行数据整理成统计表格算法最好覆盖率平均覆盖率最差覆盖率标准差PSO91.2%89.8%87.4%1.13%QPSO93.5%92.6%91.0%0.65%CQPSO95.8%95.1%94.2%0.47%CQPSO不仅平均覆盖率最高标准差还最小说明算法不是靠运气获得好结果而是真正稳定地逼近全局最优。更重要的是要解释优化结果在物理上是否合理。我观察优化后的功率向量后发现算法会自动把边缘基站的功率调高把中心基站的功率适当压低。这完全符合LTE网络规划的工程直觉中心基站功率太高会制造大量重叠覆盖边缘基站功率不足则会产生覆盖空洞算法找到的功率组合恰好平衡了这两个矛盾。这种“可解释性”很加分写论文时一定要讲清楚。5. 常见问题与避坑指南实测记录5.1 柯西扰动太大导致粒子反复飞出边界柯西分布的长尾是双刃剑偶尔的大跳跃能帮粒子逃出局部最优但跳跃幅度太大也会让粒子频繁撞到边界。如果lambda设置得过大粒子会反复在上下界之间横跳浪费大量迭代次数。我实测下来lambda取0.5左右比较合适同时必须做边界钳制避免粒子长期停留在可行域外。如果遇到粒子飞出边界后适应度反而变好的情况说明你的目标函数在边界处有异常值建议在所有粒子更新后都做边界校验并打印几个飞出的例子检查是不是路径损耗计算有问题。5.2 覆盖率怪异地接近100%或0%先查路径损耗单位这个坑我印象最深。COST231-Hata公式里距离d的单位是km而我一开始疏忽把栅格中心的距离算成了米导致路径损耗整整虚高了100多dBRSRP全部低于门限覆盖率直接变成0。反过来如果忘了减去衰落余量或者单位搞反RSRP又会虚高覆盖率接近100%看着很漂亮实际上完全没意义。检查方法很简单随机取一个栅格点手算一次路径损耗和代码输出对比如果偏差特别大第一反应就是查单位转换。这也提醒我们任何公式移植到代码里都要先单点验证再跑整体循环。5.3 代码运行太慢矩阵化、分阶段粗调精调Matlab最怕的就是大循环套小循环。如果每个粒子、每个栅格、每个基站之间都用for循环一次目标函数调用可能就要花几十毫秒150次迭代乘40个粒子就是6000次函数调用算起来非常吃紧。优化思路有四个所有距离计算直接使用向量化运算不要写成双循环先用100m粗栅格跑粗调找到大致最优功率范围后再用50m甚至25m的细栅格精调调试阶段固定随机种子避免重新跑又变化严重影响排查效率如果机器支持并行计算可以把种群适应度评估放进parfor里对目标函数是纯函数的项目提升非常明显。5.4 目标函数里忘了惩罚重叠覆盖结果虚高我在实验初期只用覆盖率作为目标函数结果发现算法学坏了它把每个站的功率都调到最高覆盖率确实很高但RSRP热力图上几乎全是深红色说明每个栅格都被好几个基站强覆盖。这种方案在实际网络里肯定不行干扰会让终端体验大幅下降。解决办法是在目标函数里加入重叠覆盖惩罚项。我这里用的是统计每个栅格被多少个基站超过门限强覆盖如果超过2个就计为一次无效贡献把所有无效栅格比例乘惩罚系数加到覆盖率上。引入惩罚后最终优化的功率组合立刻变合理了中心基站不再盲目拉高功率覆盖率和实际可部署性都更可靠。5.5 多次实验结果忽高忽低怎么控制方差群体智能算法有随机性不同随机种子得到的结果会有差异这很正常。但如果10次独立运行的标准差超过2%就要检查几件事算法收敛是否充分、种群规模是否太小、目标函数是否包含强烈不连续跳变。另一个常见问题是PSO和QPSO的初始化随机种子不同导致初始覆盖条件不同对比不公平。我给的建议是每次独立实验前都记录随机种子的取值同组算法使用相同的初始种群生成方式至少保证对比条件一致。如果想进一步降低方差可以适当增大种群规模QPSO从40增加到60后CQPSO的标准差通常可以从0.5%压到0.3%以下。最后分享一个调试阶段特别好用的小技巧在迭代过程中把每个粒子的当前适应度和位置实时画出来用散点图配上覆盖率热力图能够非常直观地看到粒子如何从模糊区域逐步移动到功率组合较优的区域。这个方法帮我发现了好几处代码逻辑错误比只看收敛曲线高效得多。你可以把绘图频率设为每10代刷新一次跑完以后再把所有帧合成一个动态过程图放在论文或答辩PPT里也相当加分。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门