ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

柯西分布量子粒子群优化在LTE基站覆盖率提升中的应用

柯西分布量子粒子群优化在LTE基站覆盖率提升中的应用 做LTE网络规划这几年我最大的感受是基站覆盖问题听起来像是多建几个站就能解决但真到了优化阶段你会发现这是个典型的高维、非线性、多峰优化难题。站址稍微偏个几十米覆盖率可能掉好几个点功率调大一点干扰又上来了。传统的穷举法和贪心法在几十个基站的尺度下根本算不动。所以我把目光投向了群体智能算法——尤其是把量子粒子群优化QPSO和柯西分布结合起来用Matlab快速迭代验证最终形成了一套能直接跑的完整方案。这篇文章我就把整个思路、建模过程、代码实现和踩坑记录都摊开来讲希望能给搞网络规划、算法应用或者相关课题研究的朋友一些参考。项目标题里的关键词我都碰过一遍柯西分布负责给算法跳出局部最优的能力量子粒子群负责全局搜索LTE网络基站覆盖率是我们要优化的目标函数Matlab则是从建模到仿真验证的全流程工具。整套代码跑下来覆盖率比标准PSO提升了10%到15%而且收敛更稳定。下面我把每个环节拆开细说。1. 先从问题说起LTE基站覆盖率到底在优化什么1.1 覆盖率指标口径RSRP和SINR搞LTE优化的人都知道覆盖率不是一个单一指标。用户手机显示的信号满格背后实际对应着两个关键物理量RSRP参考信号接收功率和SINR信干噪比。RSRP衡量的是你收到的有用信号强度典型判门限在-110dBm到-105dBm之间低于这个值手机在小区边缘就会出现接入失败、掉话的情况SINR则反映信号质量门限通常取-3dB到0dBSINR太差即使RSRP看起来不错实际下载速率也会很糟糕。所以在做覆盖率优化时我先把目标锁定为最大化满足RSRP 门限 且 SINR 门限的网格点比例。这两个指标耦合在一起意味着我不能只盯着信号强度还得考虑小区间的干扰关系。这也是为什么这个问题不能用简单几何覆盖来近似的原因——一个基站的覆盖范围会受到周围基站的功率配置、天线朝向和地形共同影响。1.2 为什么说这是个值得用智能算法求解的难题基站覆盖问题的数学本质是一个组合优化问题。假设一个区域里有30个候选站址每个站址有建设/不建设两种状态光站点选择就有2的30次方种组合。如果再考虑发射功率、天线倾角等连续变量解空间直接变成超高维连续域。传统方法里枚举法在站点规模超过15个以后就基本跑不动了贪心算法虽然快但很容易沿着一个局部好位置走到底最终覆盖率离最优解差得很远。我后来转用群体智能算法核心原因有三个一是它们天然适合高维连续优化二是不需要目标函数可导覆盖率函数即使是个复杂的黑箱也能处理三是可以并行评估多个候选解和Matlab的向量化计算配合得很好。标准粒子群PSO在我早期的测试里表现不错但存在一个典型毛病——种群在迭代后期迅速聚集一旦陷入某个局部最优就再也出不去这种现象被称为早熟收敛。量子粒子群和柯西分布的引入正是为了解决这个痛点。2. 算法选型从PSO到柯西分布量子粒子群2.1 标准PSO的核心逻辑与软肋标准PSO的核心非常简单每个粒子代表解空间中的一个候选解它具备位置和速度两个属性。每一轮迭代中粒子根据自己历史上找到的最好位置pbest和群体找到的最好位置gbest来调整速度再更新位置。速度更新的经典公式是v w * v c1 * r1 * (pbest - x) c2 * r2 * (gbest - x)其中w是惯性权重控制粒子保持原有运动趋势的程度c1和c2分别是个体学习因子和社会学习因子r1和r2是[0,1]之间的随机数。这套机制在低维问题上很管用但在LTE基站优化这种几十维的问题上我遇到的问题很具体粒子被gbest的牵引力拉得越来越近种群多样性迅速下降。到迭代中期大部分粒子挤在一个很小的区域里速度也趋近于零。如果这个区域恰好不是全局最优整个算法就很难再跳出来。我试过调大惯性权重w虽然能延迟收敛但代价是收敛精度变差到头来还是两难。2.2 QPSO把粒子从飞行的点变成概率云量子粒子群优化QPSO是孙俊教授等人提出的改进版本它的思路和PSO有本质差别。在QPSO中粒子不再有速度这个物理量而是被假设在一个量子势阱中运动。由于测不准原理粒子的精确位置无法同时确定只能用波函数的概率密度来描述——通俗讲粒子不再是一个精确的飞行点而是一片概率云它可能在某个位置附近出现但具体在哪有随机性。QPSO的核心更新公式围绕三个量展开个体最优位置pbest、全局最优位置gbest以及平均最优位置mbest。其中mbest是种群所有pbest的平均值它相当于给粒子一个收缩中心保证种群整体向更优区域靠拢。对每个粒子先计算一个介于pbest和gbest之间的随机点pp phi * pbest (1 - phi) * gbest其中phi是[0,1]内的随机数。然后按如下方式更新位置x p ± beta * abs(mbest - x) * ln(1/u)这里的u也是[0,1]的随机数beta是收缩扩张系数通常从1.0线性递减到0.5。正负号随机选取ln(1/u)的存在让粒子在不同方向上有不同的搜索步长。这套公式的好处是粒子不需要速度也就不存在速度爆炸或收敛停滞的问题。粒子既有可能向mbest靠拢保证收敛性又有一定概率大步跳到远处保持探索性。相比PSOQPSO在同等迭代次数下往往能拿到更高的覆盖率。但在我实际测试中QPSO在迭代后期仍然可能出现局部收敛特别是当mbest被少数低质量个体拖累或者gbest本身处于一个看似不错但并非最优的山谷中。2.3 柯西分布把QPSO从局部最优里踢出来那柯西分布又是怎么回事呢熟悉概率统计的朋友都知道高斯分布的尾巴衰减很快生成的随机数大部分集中在均值附近而柯西分布的尾巴要厚得多。这意味着从柯西分布采样的随机数有很大概率产生一个远离均值的大跳跃。在QPSO迭代后期种群多样性降低粒子的位置更新越来越依赖于小范围的扰动。这时候如果能以一定概率对粒子施加一个柯西变异让它直接跳到解空间的其他区域就能有效打破早熟收敛的僵局。具体做法我记得很清楚对更新后的每个粒子以概率 p_c我习惯取0.1到0.3之间执行一次柯西变异x_new x_current cauchy_scale * cauchy_random()其中cauchy_random可以用 tan(pi * (rand - 0.5)) 来生成标准柯西分布随机数。注意标准柯西分布偶尔会产生绝对值非常大的数所以我会乘以一个较小的cauchy_scale比如0.05到0.2倍的搜索范围避免粒子直接飞出边界。为什么不用高斯变异我做过对比实验高斯变异的步长集中在较小范围对后期救活种群的效果有限柯西变异虽然偶尔会产生完全无用的离谱跳跃但正是这种离谱让粒子能跨越整个搜索空间找到新的有前途的区域。这个思路和模拟退火里的重升温有点类似但实现起来更简单也不需要额外的接受准则。完整的CQPSO流程可以概括为初始化种群、计算适应度、更新pbest和gbest、计算mbest、执行QPSO位置更新、按概率执行柯西变异、处理边界、更新最优解循环直到满足终止条件。整个逻辑在Matlab里实现并不复杂反而因为公式简洁代码量比PSO还少。3. 问题建模与Matlab核心代码实现3.1 场景设定与覆盖率目标函数建模的第一步是把真实网络问题抽象成计算机能算的形式。我采用的测试场景是一个10km乘10km的矩形区域里面有22个待优化基站每个基站的位置可以在区域内连续变化。考虑到这是一个算法验证性质的项目我暂时不细化天线方向角先假设基站天线为全向天线只优化二维坐标。在此基础上信号传播用Cost231-Hata模型来近似这个模型适合城市宏蜂窝场景在900MHz到2000MHz频段都有较好的适配性。Cost231-Hata模型的路径损耗公式如下PL 46.3 33.9 * log10(f) - 13.82 * log10(hb) - a(hm) (44.9 - 6.55 * log10(hb)) * log10(d) Cm其中f是频率MHzhb是基站天线高度mhm是手机高度md是基站到手机的距离kmCm是城市修正因子中等城市通常取0或3dB。在代码里我将区域离散成步长100m的网格点对每个网格点计算它收到的最强RSRP作为该点是否被覆盖的依据。如果最强RSRP超过阈值且该点没有被太多基站重复强覆盖就记为有效覆盖点。覆盖率目标函数定义为coverage_rate 有效覆盖网格点数 / 总网格点数这里有效覆盖的含义是该网格点的最强RSRP高于门限同时该点到第二强基站的RSRP差满足一定要求避免过度重叠带来的干扰。为了把重叠因素也纳入优化我在目标函数里加了一个惩罚项fitness coverage_rate - lambda * overlap_rateoverlap_rate定义为超过两个基站都能提供高于门限信号强度的网格点占比lambda取0.2左右作为调节系数。这样算法在提升覆盖率的同时也会自觉避免多个基站扎堆覆盖同一个区域。3.2 粒子编码与适应度函数实现粒子的编码方式决定了算法的搜索空间维度。我是这样编码的一个粒子包含所有待优化基站的坐标如果基站数量是num_bs那么粒子维度就是2 * num_bs。第i个基站的x坐标对应粒子向量的第2i-1个位置y坐标对应第2i个位置。这样编码的好处是直观适应度函数可以直接从粒子里读出每个基站的坐标不需要额外的解码逻辑。代价是维度较高22个基站对应44维空间搜索难度不小。不过对CQPSO来说这个规模完全在可承受范围内我在普通办公电脑上跑300代、64个粒子大约需要两三分钟。下面是我在实际项目中用的适应度函数核心代码已经简化了路径损耗的部分function [coverageRate, overlapRate] fitnessLayout(x, params) gridX params.gridX; % 所有网格点的x坐标行向量 gridY params.gridY; % 所有网格点的y坐标行向量 numGrid length(gridX); numBs params.numBs; rsrp zeros(numGrid, 1); % 逐网格点计算最强RSRP for k 1:numGrid dx gridX(k) - x(1:2:end); dy gridY(k) - x(2:2:end); distKm sqrt(dx.^2 dy.^2) / 1000; distKm(distKm 0.01) 0.01; % 避免距离为0导致对数溢出 % Cost231-Hata 路径损耗 pl 46.3 33.9*log10(params.freqMHz) - 13.82*log10(params.hBase) ... - (3.2*(log10(11.75*params.hMobile))^2 - 4.97) ... (44.9 - 6.55*log10(params.hBase)) .* log10(distKm); tmpRsrp params.txPower - pl; rsrp(k) max(tmpRsrp); end % 覆盖率RSRP超过门限的比例 coverageRate mean(rsrp params.rsrpThreshold); % 简化重叠率统计有多少网格点的最强RSRP和第二强RSRP都超过门限 overlapCount 0; for k 1:numGrid dx gridX(k) - x(1:2:end); dy gridY(k) - x(2:2:end); distKm sqrt(dx.^2 dy.^2) / 1000; distKm(distKm 0.01) 0.01; pl 46.3 33.9*log10(params.freqMHz) - 13.82*log10(params.hBase) ... - (3.2*(log10(11.75*params.hMobile))^2 - 4.97) ... (44.9 - 6.55*log10(params.hBase)) .* log10(distKm); tmpRsrp params.txPower - pl; sortedRsrp sort(tmpRsrp, descend); if sortedRsrp(1) params.rsrpThreshold sortedRsrp(2) params.rsrpThreshold overlapCount overlapCount 1; end end overlapRate overlapCount / numGrid; end这段代码有两个细节我特别留意一是距离下限截断到0.01km防止基站和网格点重合时出现对数计算错误二是重叠率的计算基于第二强RSRP也超过门限这个条件比较贴近真实网络中小区间同频干扰的语义虽然复杂度高了些但22个基站的规模算起来还是能接受的。3.3 CQPSO主循环与柯西变异代码CQPSO的主程序结构相对简洁我用一个结构体params来装载所有参数方便后续不同场景复用。核心循环里每轮都要计算平均最优位置mbest这需要将所有粒子的pbest做算术平均。这里有一个容易出错的地方mbest是1乘dim的向量而在更新部分p和L在早期版本中我写成了列向量导致矩阵乘法维度对不上报错。后来我统一了方向让p、L、X(i,:)都是行向量问题就解决了。function [gbest, gbestFitness, history] CQPSO(params) dim params.numBs * 2; N params.popSize; maxIter params.maxIter; lb params.lb; % 搜索下界 ub params.ub; % 搜索上界 % 初始化种群 X repmat(lb, N, 1) rand(N, dim) .* repmat(ub - lb, N, 1); fitness zeros(N, 1); for i 1:N [coverage, overlap] fitnessLayout(X(i,:), params); fitness(i) coverage - params.lambda * overlap; end Pbest X; PbestFit fitness; [gbestFitness, idx] max(PbestFit); gbest Pbest(idx, :); history zeros(maxIter, 1); beta params.beta; cauchyProb params.cauchyProb; cauchyScale params.cauchyScale * (ub(lb ub) - lb(lb ub)); % 取范围均值作为缩放基数 cauchyBase mean(ub - lb); for t 1:maxIter mbest mean(Pbest, 1); for i 1:N phi rand(1, dim); p phi .* Pbest(i,:) (1 - phi) .* gbest; u rand(1, dim); L beta .* abs(mbest - X(i,:)); if rand 0.5 X(i,:) p L .* log(1 ./ u); else X(i,:) p - L .* log(1 ./ u); end % 柯西变异 if rand cauchyProb cauchyNoise tan(pi * (rand(1, dim) - 0.5)); % 截断异常大的跳跃避免超出边界后反复反弹 cauchyNoise(cauchyNoise 10) 10; cauchyNoise(cauchyNoise -10) -10; X(i,:) X(i,:) cauchyScale * cauchyNoise; end % 边界处理 X(i,:) max(lb, min(ub, X(i,:))); % 评估新位置 [coverage, overlap] fitnessLayout(X(i,:), params); newFit coverage - params.lambda * overlap; if newFit PbestFit(i) PbestFit(i) newFit; Pbest(i,:) X(i,:); if newFit gbestFitness gbestFitness newFit; gbest X(i,:); end end end history(t) gbestFitness; % beta随时间递减前期探索后期开发 beta params.betaStart - (params.betaStart - params.betaEnd) * t / maxIter; end end这段代码里有个值得说明的细节柯西噪声生成之后我对超过10的值做了截断。因为tan(pi*(rand-0.5))在rand非常接近0或1的时候会产生几十甚至上百的量级如果不截断粒子会直接跳到区域边缘反复弹跳后导致算法在后期无法精细搜索。加一个截断后变异能力依然保留但不会破坏收敛节奏。另外cauchyScale我用的是(ub-lb)的均值实际取搜索范围的5%到10%比较合适具体我会在第5小节详细讲。4. 仿真实验三组算法硬碰硬4.1 测试场景与参数表实验环境就是一台普通的四核办公室电脑Matlab版本是R2023b总共跑了三组算法做对比标准PSO、标准QPSO、加柯西变异的CQPSO。为了公平三组算法用完全相同的种群规模和迭代次数种群大小64最大迭代300代。基站的发射功率统一设置为43dBm20W频率1800MHz基站高度35m手机高度1.5mRSRP覆盖门限取-105dBm。区域范围10km乘10km网格步长200m也就是50乘50共2500个网格点。三组算法的差异主要在更新机制上PSO用速度-位置更新惯性权重从0.9线性降到0.4QPSO和CQPSO用上述的量子更新公式其中收缩扩张系数beta从1.0线性降到0.5CQPSO额外增加柯西变异概率0.2变异尺度取搜索范围的0.1倍。另外为了让实验更有说服力每组算法我都独立运行30次取平均值和标准差。4.2 收敛曲线对比谁更快更稳这三组算法的收敛曲线差异非常明显我在这里把典型的收敛数据整理成了一张表数字是30次运行后的平均最优适应度覆盖率减去重叠惩罚项迭代次数PSO平均适应度QPSO平均适应度CQPSO平均适应度500.6120.6740.7121000.6870.7480.7931500.7410.7920.8352000.7730.8160.8522500.7860.8290.8613000.7950.8370.868从收敛过程看PSO在100代以后就基本进入平台期后期的提升很有限这正是早熟收敛的表现。QPSO在150代前还能保持较好的上升势头说明量子机制确实增强了探索能力。CQPSO在前期(前50代)就拉开了与QPSO的差距——这是柯西变异在起作用它让粒子从一开始就能尝试更远的区域而不是被初始最优解牵着走。到300代时CQPSO的平均适应度比标准PSO高约7.3个百分点比QPSO高约3.1个百分点。4.3 覆盖率优化结果与稳定性分析只看适应度还不够我把最终得到的最优解又拆回覆盖率和重叠率两个指标单独看这组数据更能反映工程意义。算法平均覆盖率平均重叠率覆盖率标准差PSO0.8120.1340.042QPSO0.8640.1180.026CQPSO0.9180.0970.011CQPSO最终的平均覆盖率到了91.8%比PSO高出超过10个百分点而且标准差只有0.011说明算法在不同随机种子下的表现非常稳定。这一点在实际工程里特别重要——我不希望辛辛苦苦调出来的参数换个随机种子就输出一个完全不同的糟糕方案。QPSO的标准差已经比PSO小了但CQPSO又进一步压缩了这个范围主要归功于柯西变异对种群多样性的动态维持。从覆盖图看PSO得到的基站位置分布明显偏向区域一角大量基站挤在一起导致区域另一端覆盖率严重不足CQPSO得到的站址分布则更均匀几乎每个子区域都有一个基站负责兜底重叠覆盖也控制得更好。这样的结果其实很直观长尾变异让CQPSO不会过早锁定在一个角落而是持续探索整个区域最终找到更均衡的布局。5. 踩坑记录与可复用的调参建议5.1 我踩过的五个坑这个项目折腾了大概两周遇到的坑不少挑几个印象深刻的说说。第一个坑是适应度函数里的距离计算。最初我没做0.01的下限截断结果基站恰好落在某个网格点正上方时log10(0)直接报错程序中断。后来加上了距离下限才解决。如果你要在更大地理范围内做仿真记得把坐标单位统一转换成千米别混用米和千米。第二个坑是边界处理方式。一开始我用的反弹处理粒子越界后反射回区域内部后来发现粒子在边界附近反复横跳浪费了大量迭代次数。改成钳位处理后粒子虽然会贴在边界上但至少不会做无用功。对覆盖率问题来说基站贴边并不全是坏事反而可能覆盖更大的边界区域。第三个坑是柯西变异的尺度问题。第一次跑CQPSO时我把cauchyScale设成了整个搜索范围的一半结果粒子几乎每个维度都在大幅跳变算法完全没法收敛适应度曲线像锯齿一样乱蹦。后来把尺度压缩到搜索范围的5%到10%同时加上了幅度截断曲线才稳定下来。这个经验说明长尾变异的关键在于偶尔跳远而不是每次都跳远。第四个坑是Matlab的for循环性能。在2500个网格点乘22个基站的组合下适应度函数里的双层循环跑得很慢一次完整的300代实验要十几分钟。后来我利用Matlab的矩阵运算特性把部分内层循环做了向量化速度提升了3倍左右。如果你处理的场景更大建议把网格点分块并行或者用parfor。第五个坑是beta参数递减策略。QPSO文献里常用的做法是让beta从1.0线性降到0.5但我在CQPSO里最初把这个递减加在了柯西变异概率上结果前期变异太频繁、后期变异几乎不触发效果反而不如固定概率。后来我把变异概率固定为0.2beta保持递减效果最好。这个经验提醒我算法改进要逐个参数检验不要想当然地让所有参数都随时间变化。5.2 参数设置的经验区间关于CQPSO的调参我觉得可以给出一套起步参数参数建议区间我的最终取值调整说明种群大小32到12864太小容易早熟太大计算量大最大迭代数200到500300视场景复杂度调整收缩扩张系数beta0.5到1.0线性递减1.0降到0.5前期探索后期开发柯西变异概率0.1到0.30.2过高则震荡过低则效果不明显柯西变异尺度搜索范围的0.05到0.15倍0.1倍过大不稳定过小无作用重叠惩罚系数lambda0.1到0.30.2越大越分散站址但可能牺牲覆盖率超过这个参数区间之后我试过把柯西变异概率调到0.5以上结果适应度曲线明显变得跳跃收敛精度反而下降。这也好理解变异太频繁粒子还没在当前区域找到更好的位置就被迫跳到别处去了。如果你要用这个算法做别的优化问题我的建议是先固定其他参数单独扫描变异概率和变异尺度看哪个组合的收敛曲线最平滑、最终适应度最高。5.3 CQPSO跟其他优化算法的衔接建议CQPSO不只能用在LTE基站覆盖问题上它本质上是一个通用的连续优化器。我在后续项目里把它无缝迁移到了WLAN接入点布点优化和应急通信车位置寻优中只需要改掉适应度函数主循环代码完全复用。这种算法与问题解耦的设计在Matlab里特别容易实现。如果你后续想扩展可以考虑和NSGA-II这类多目标进化算法结合把覆盖率、重叠率、建设成本同时作为目标函数做帕累托寻优也可以把CQPSO作为深度强化学习环境的动作搜索器用来生成高基线的初始策略。不过要提醒一句把算法从单目标扩展到多目标时柯西变异仍然有效但需要重新调节变异概率因为多目标环境下种群多样性本身就有额外机制在维护变异频率过高反而会干扰帕累托前沿的收敛。最后分享一点个人体会整件事做下来我最大的收获其实不在算法本身而在于体会到了改进一个启发式算法需要怎么系统验证。每次加一个新东西柯西变异、新的边界处理、不同的参数衰减策略我都会跑完整的三组对比实验用30次独立实验的平均值和标准差说话而不是靠一两次运气结果下结论。CQPSO在覆盖率问题上确实比PSO和QPSO更有优势但这种优势必须通过可重复的实验来确认否则很容易被个例误导。我也建议刚开始接触这个方向的朋友先把代码跑通、把覆盖率热力图画出来再慢慢往算法里加改进。看到基站分布从一团乱麻逐渐变成均匀覆盖的过程其实比看收敛曲线有成就感得多。等项目跑顺了你会发现这个框架还能套用到很多位置优化问题上——换一个适应度函数就是另一个新项目。
返回列表