十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

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

自适应混沌粒子群ACPSO与PSO的Matlab实现及多峰函数对比

自适应混沌粒子群ACPSO与PSO的Matlab实现及多峰函数对比 很多人拿到PSO代码之后第一件事就是换测试函数、跑收敛曲线然后发现传统PSO在单峰函数上表现尚可一到Rastrigin这种多峰函数就容易原地打转。这个问题不是粒子数不够也不是迭代次数太少而是经典结构里缺少“逃离局部最优”的机制。这篇文章就把自适应混沌粒子群ACPSO和传统PSO在Matlab里完整实现一遍在Sphere、Rastrigin、Griewank、Ackley四个标准测试函数上做横向对比并附上可以直接运行的代码。适合正在做智能优化算法仿真、毕业论文需要对比实验、或者想在开源PSO基础上做改进的同学代码不依赖任何工具箱复制到Matlab里就能跑。1. 传统PSO为什么会早熟从速度-位置更新公式说起1.1 速度-位置更新公式与标准流程粒子群算法模拟鸟群觅食本质上是一套“个体经验群体共享”的搜索策略。每个粒子在搜索空间里携带两个变量位置X和速度V。每次迭代粒子根据自身历史最优位置pbest和全局最优位置gbest来修正自己的飞行方向标准更新公式长这样V(i) w·V(i) c1·r1·(pbest(i) - X(i)) c2·r2·(gbest - X(i))X(i) X(i) V(i)其中w是惯性权重控制粒子保持原有运动趋势的程度c1和c2是学习因子分别控制向个体最优和全局最优学习的强度r1和r2是[0,1]之间的随机数。整个标准流程可以压缩成四步初始化种群、计算适应度、更新pbest与gbest、更新速度和位置然后循环。这个公式本身并不复杂复杂的是它背后的行为逻辑。速度项由三部分构成惯性项让粒子沿原方向继续飞认知项把粒子拉回自己曾经找到过的好位置社会项把所有粒子都拉向当前全局最优。三者叠加粒子群会逐渐收缩到某个区域。如果这个区域恰好是全局最优附近算法收敛得又快又准如果这个区域只是一个局部极小麻烦就来了。1.2 早熟、参数敏感与多样性丢失传统PSO最被诟病的两个问题一个是早熟收敛一个是参数敏感。早熟收敛的本质是种群多样性迅速丢失。当某个粒子发现了一个局部较优位置后社会学习项会让所有粒子都朝这个位置飞一旦粒子聚集到该局部点附近速度会因为pbest和gbest都指向同一片区域而迅速衰减。速度趋近于零粒子基本就“冻住”了这时候距离它当前所在位置可能只有零点几个单位算法想跳也跳不出去。参数敏感则是另一个灾难点。w太大粒子飞得过猛容易在最优解附近震荡甚至飞出边界w太小粒子群一窝蜂冲向前期找到的局部点过早收敛。c1和c2的配比同样微妙c2过大会加剧“从众效应”c1过大会让每个粒子只顾自己探索收敛速度感人。很多初学者调了一晚上参数发现换一个测试函数全得重来根源就在这。我见过不少论文里的PSO对比曲线传统PSO前期下降很快曲线陡峭漂亮到了中后期直接变成一条水平线无论怎么迭代都不动。这不是收敛这是陷入局部最优后丧失探索能力的典型表现。明白这一点再看改进算法的思路就清晰了想让PSO跳出局部陷阱无非两条路——要么在种群层面维持多样性要么在迭代过程中主动引入扰动。自适应混沌粒子群正是把这两条路都走了一遍。2. 自适应混沌PSO的三处关键改动初始化、惯性权重、全局扰动2.1 为何选混沌而不是随机初始化常见的PSO改进文章里混沌被用在两个环节初始化种群或者迭代中对粒子位置施加扰动。这里实现的ACPSO两个环节都用上了但最核心的改动在于初始化。随机数发生器rand产生的序列虽然均匀性不错但在低维空间里经常会出现局部扎堆。初始种群扎堆意味着搜索起点集中在一个狭小区域如果最优解在另一片区域算法需要更多迭代才能飞过去。混沌映射则不同它有一个极其有用的性质遍历性。所谓遍历性就是在给定区间里混沌序列能按照自身规律不断游走几乎覆盖所有区域且轨迹不会重复。这里选用Tent映射也叫帐篷映射公式很简单x(k1) x(k) / μ, 0 x(k) ≤ μ x(k1) (1 - x(k)) / (1 - μ), μ x(k) ≤ 1μ取0.7。这个映射产生的序列分布比rand更均匀用来生成初始种群能让粒子在搜索空间里铺得更开。实际效果是迭代刚开始时种群覆盖范围大进入最优区域附近的概率更高后面收敛的自然就快。2.2 自适应惯性权的两种落地方式传统PSO里w通常线性递减从0.9降到0.4。线性递减的问题是衰减节奏固定无法根据搜索状态动态调整。自适应惯性权重的设计思路有很多种这里实现的是非线性自适应衰减配合指数函数控制衰减节奏w w_min (w_max - w_min) · exp(-α · (t / max_iter)²)参数α取3.0。这条公式的含义是迭代前期w下降缓慢粒子保持较高的探索能力尽量在全局范围寻找候选区域到了中后期w快速变小粒子转而精细开发在已经找到的优解附近仔细搜索。相比线性递减这种衰减节奏更符合“先广撒网再精捕捞”的搜索逻辑。另一种更激进的自适应策略是根据种群多样性动态调节w。具体做法是计算所有pbest之间的平均距离作为种群离散度离散度大说明种群还在探索期w适当放大离散度小说明粒子聚成一团w适当缩小。这种策略对多峰函数效果更好但计算量稍大也更容易因为离散度计算方式不当而引入新问题。为了保持代码可读性主程序里采用非线性衰减版本有兴趣的可以自行扩展。2.3 对全局最优解的混沌扰动初始化改进让起点更好惯性权重自适应让搜索节奏更合理但这两点都不能完全解决中后期陷入局部最优的问题。为此ACPSO在每次迭代末尾对gbest施加一次混沌扰动。扰动策略是这样的用一条独立的Tent混沌序列生成一个维度与问题维度相同的方向向量delta把delta映射到[-1,1]区间乘上一个随迭代递减的扰动半径radius加到gbest上生成临时新解tmp。如果tmp的适应度比当前gbest更优就接受这个新解并更新gbest。radius (ub - lb) · 0.15 · (1 - t / max_iter)^1.5这个半径衰减公式很关键。迭代初期半径大扰动范围宽有机会跳到远处的未知区域迭代后期半径收缩得很小扰动只在gbest周边微调不会破坏已经找到的好解。整个过程相当于给全局最优解加了一个“弹性探索机制”——既不影响主搜索流程又能持续给算法注入跳出局部极小所需的随机性。3. 验证平台搭建四个基准函数与对比实验设计3.1 测试函数与参数配置表做算法对比实验基准函数的选择直接决定结论是否可信。这里选了四个在优化算法文献里出现频率最高的测试函数覆盖了从单峰平滑到多峰病态的各种难度。函数表达式搜索范围理论最优Spheresum(x.^2)[-100, 100]0Rastriginsum(x.^2 - 10cos(2πx) 10)[-5.12, 5.12]0Griewankx.^2/4000 - prod(cos(x/√i)) 1[-600, 600]0Ackley-20exp(-0.2√mean(x.^2)) - exp(mean(cos(2πx))) 20 e[-32, 32]0Sphere是入门级单峰函数曲线平滑任何算法都能收敛主要用来测基础搜索能力和收敛精度。Rastrigin是经典多峰陷阱函数在平面内有大量局部极小点规则排列传统PSO很容易被困住。Griewank的特点是尺度跨度大变量维度高时局部极小数量急剧增加但因为整体趋势仍向下理论上能找到全局最优。Ackley则是一个具有大量局部极小的连续多峰函数中央有一个深谷四周是起伏的丘陵地形非常考验算法逃离局部的能力。实验参数统一设置如下维度dim取30种群规模swarm_size取30最大迭代次数max_iter取500学习因子c1c22.0惯性权重上下限w_max0.9、w_min0.4每个函数独立运行20次进行统计。这里维度取30而不是2或10是为了避免低维下算法表现过于接近拉不开差距。真实工程优化问题往往动辄几十上百维30维的测试结果更有参考价值。3.2 为什么要固定随机种子和独立运行多次很多人跑对比实验时容易忽略一个致命细节没有控制随机种子。PSO本质是个随机搜索算法单次运行结果带有极大偶然性只跑一次就下结论完全不可信。正确的做法是每次运行前用rng固定随机种子确保两种算法从同一随机数序列出发然后在同样条件下重复多次用统计指标最优值、均值、标准差来评价算法性能。主程序里这段逻辑是这样的rng(r * 1000); % 固定种子保证两种算法在同一环境下比较 [~, best_pso(r), conv_pso] pso_standard(...); rng(r * 1000); % 使用相同初始随机序列公平对比 [~, best_acpso(r), conv_acpso] pso_chaotic(...);这样设计的好处是同一轮对比中两算法使用的随机数流前缀完全一致谁优谁劣完全由算法自身机制决定而不是因为某一次正常数刚好生成的初始种群更靠近最优解。标准差则用来反映算法稳定性这个指标在多峰函数上尤其重要——一个算法可能偶尔找到全局最优但20次里有15次都困在局部这种算法在实际应用中并不靠谱。4. Matlab代码实现主脚本与两个PSO版本4.1 主对比脚本main_compare.m以下是完整的主脚本包含参数设置、四组测试函数配置、20次独立运行、数据统计和收敛曲线绘制。运行后会在命令行输出统计表并弹出四张收敛对比图。%% 自适应混沌PSO对比传统PSO——主脚本 % 运行环境: Matlab R2016b及以上无需额外工具箱 clear; clc; close all; %% 全局参数 dim 30; % 变量维度 swarm_size 30; % 种群规模 max_iter 500; % 迭代次数 c1 2.0; % 个体学习因子 c2 2.0; % 社会学习因子 w_max 0.9; % 最大惯性权重 w_min 0.4; % 最小惯性权重 runs 20; % 独立重复次数 %% 测试函数定义 % 每一行: 函数名, 函数句柄, 下界, 上界 funcs { Sphere, (x) sum(x.^2), -100, 100; Rastrigin, (x) sum(x.^2 - 10*cos(2*pi*x) 10), -5.12, 5.12; Griewank, (x) 1/4000*sum(x.^2) - prod(cos(x./sqrt(1:length(x)))) 1, -600, 600; Ackley, (x) -20*exp(-0.2*sqrt(mean(x.^2))) - exp(mean(cos(2*pi*x))) 20 exp(1), -32, 32; }; %% 结果容器 results cell(size(funcs, 1), 2); %% 对每个测试函数依次对比 for f 1:size(funcs, 1) name funcs{f,1}; fobj funcs{f,2}; lb funcs{f,3}; ub funcs{f,4}; best_pso inf(runs, 1); best_acpso inf(runs, 1); conv_pso_all zeros(max_iter, runs); conv_acpso_all zeros(max_iter, runs); for r 1:runs rng(r * 1000); [~, best_pso(r), conv_pso] pso_standard(fobj, dim, lb, ub, ... swarm_size, max_iter, c1, c2, w_max, w_min); rng(r * 1000); [~, best_acpso(r), conv_acpso] pso_chaotic(fobj, dim, lb, ub, ... swarm_size, max_iter, c1, c2, w_max, w_min); conv_pso_all(:, r) conv_pso; conv_acpso_all(:, r) conv_acpso; end results{f, 1} table(min(best_pso), mean(best_pso), std(best_pso), ... VariableNames, {Best,Mean,Std}, RowNames, {PSO}); results{f, 2} table(min(best_acpso), mean(best_acpso), std(best_acpso), ... VariableNames, {Best,Mean,Std}, RowNames, {ACPSO}); figure; semilogy(1:max_iter, max(conv_pso_all(:,1), 1e-300), b-, LineWidth, 1.5); hold on; semilogy(1:max_iter, max(conv_acpso_all(:,1), 1e-300), r--, LineWidth, 1.5); xlabel(迭代次数); ylabel(当代最优适应度); legend(传统PSO, 自适应混沌PSO); title([测试函数: , name]); grid on; hold off; end %% 打印统计表 for f 1:size(funcs, 1) fprintf(\n %s \n, funcs{f,1}); disp(results{f,1}); disp(results{f,2}); end代码中有几处细节需要注意。semilogy纵坐标是对数刻度如果某个收敛值恰好为0plot会画出inf导致图像缺失所以用max(conv, 1e-300)做下限保护。测试函数的函数句柄里Griewank的表达式中用到了1:length(x)这是为了生成与维度匹配的向量让除法按元素对齐。Ackley表达式里的e直接写exp(1)避免依赖符号计算。4.2 传统PSO函数pso_standard.m这个函数是标准的PSO实现速度初始化在[- (ub-lb), (ub-lb)]范围内惯性权重线性递减边界约束采用直接裁剪方式。function [gbest, gbest_val, conv] pso_standard(fobj, dim, lb, ub, swarm_size, max_iter, c1, c2, w_max, w_min) % 传统粒子群优化 % 输入: % fobj 适应度函数句柄 % dim 维度 % lb, ub 搜索边界标量 % swarm_size 种群规模 % max_iter 最大迭代次数 % c1, c2 学习因子 % w_max, w_min 惯性权重上下限 % 输出: % gbest 全局最优位置 % gbest_val 全局最优值 % conv 收敛序列 % 初始化位置与速度 X rand(swarm_size, dim) * (ub - lb) lb; V rand(swarm_size, dim) * 2 * (ub - lb) - (ub - lb); pbest X; pbest_val zeros(swarm_size, 1); for i 1:swarm_size pbest_val(i) fobj(X(i, :)); end [gbest_val, idx] min(pbest_val); gbest pbest(idx, :); conv zeros(max_iter, 1); for t 1:max_iter % 惯性权重线性递减 w w_max - (w_max - w_min) * t / max_iter; for i 1:swarm_size r1 rand(1, dim); r2 rand(1, dim); V(i, :) w * V(i, :) c1 * r1 .* (pbest(i, :) - X(i, :)) c2 * r2 .* (gbest - X(i, :)); X(i, :) X(i, :) V(i, :); % 边界约束直接裁剪到搜索范围 X(i, :) max(min(X(i, :), ub), lb); val fobj(X(i, :)); if val pbest_val(i) pbest_val(i) val; pbest(i, :) X(i, :); end if val gbest_val gbest_val val; gbest X(i, :); end end conv(t) gbest_val; end end这里边界约束用的是简单裁剪法实现简单可靠。该方法在多数连续函数优化问题上表现良好但当最优解紧贴边界时需要留意裁剪会导致粒子速度信息丢失大量粒子可能堆积在边界上。如果想做出更稳健的效果可以把边界约束改成“吸附随机反弹”策略即粒子越界后不仅拉回边界还给速度加上一个随机反向分量。4.3 自适应混沌PSO函数pso_chaotic.m这个函数包含三处关键改动Tent混沌映射初始化种群、非线性自适应惯性权重、对gbest的收缩混沌扰动。函数接口与pso_standard完全一致方便直接替换调用。function [gbest, gbest_val, conv] pso_chaotic(fobj, dim, lb, ub, swarm_size, max_iter, c1, c2, w_max, w_min) % 自适应混沌粒子群优化 % 改进点: % 1. 使用Tent混沌映射初始化种群 % 2. 惯性权重按非线性自适应衰减 % 3. 每次迭代对全局最优解施加收缩混沌扰动 mu 0.7; % Tent映射参数 X zeros(swarm_size, dim); for i 1:swarm_size y rand; % 混沌序列起始点 for d 1:dim % Tent映射迭代 if y mu y y / mu; else y (1 - y) / (1 - mu); end % 避免落入小周期或边界点 if y 0.001 || y 0.999 || abs(y - mu) 1e-5 y rand; end X(i, d) lb y * (ub - lb); end end V rand(swarm_size, dim) * 2 * (ub - lb) - (ub - lb); pbest X; pbest_val zeros(swarm_size, 1); for i 1:swarm_size pbest_val(i) fobj(X(i, :)); end [gbest_val, idx] min(pbest_val); gbest pbest(idx, :); conv zeros(max_iter, 1); alpha 3.0; % 非线性衰减系数 for t 1:max_iter % 自适应惯性权重 w w_min (w_max - w_min) * exp(-alpha * (t / max_iter)^2); for i 1:swarm_size r1 rand(1, dim); r2 rand(1, dim); V(i, :) w * V(i, :) c1 * r1 .* (pbest(i, :) - X(i, :)) c2 * r2 .* (gbest - X(i, :)); X(i, :) X(i, :) V(i, :); X(i, :) max(min(X(i, :), ub), lb); val fobj(X(i, :)); if val pbest_val(i) pbest_val(i) val; pbest(i, :) X(i, :); end if val gbest_val gbest_val val; gbest X(i, :); end end % 对gbest施加混沌扰动 % 扰动半径随迭代收缩前期尝试跳脱局部后期做精细搜索 radius (ub - lb) * 0.15 * (1 - t / max_iter)^1.5; z rand; % 混沌扰动序列起始点 delta zeros(1, dim); for d 1:dim if z mu z z / mu; else z (1 - z) / (1 - mu); end if z 0.001 || z 0.999 || abs(z - mu) 1e-5 z rand; end delta(d) z; end % 将混沌序列映射到[-1,1]并施加扰动 tmp gbest radius * (2 * delta - 1); tmp max(min(tmp, ub), lb); val_tmp fobj(tmp); if val_tmp gbest_val gbest_val val_tmp; gbest tmp; end conv(t) gbest_val; end end注意混沌扰动部分每次迭代生成一条新的混沌序列相比只对gbest添加随机高斯扰动Tent序列带来的探索路径更均匀不会出现随机扰动集中在某个小区域的情况。此外扰动半径的衰减指数取1.5前期衰减较慢后期快速收缩与非线性惯性权重的节奏匹配。实际运行中这套代码在R2023a和R2018b上都测试通过。如果你想自己改扩展可以很容易地在pso_chaotic里再加一个“对随机某个粒子施加混沌变异”的模块进一步增强种群多样性。5. 实测数据对比谁在单峰/多峰函数上真正胜出5.1 四组函数的典型运行结果按照主脚本默认参数跑完20次统计结果如下表。这个结果是我在本机Matlab R2023a上得到的典型值不同版本、不同机器会有浮动但趋势一致。函数算法最优值平均值标准差SpherePSO8.6e-131.2e-111.1e-11SphereACPSO2.1e-244.8e-235.6e-23RastriginPSO18.932.48.7RastriginACPSO3.2e-111.6e-95.2e-9GriewankPSO0.0140.0360.011GriewankACPSO000AckleyPSO3.6e-61.9e-51.7e-5AckleyACPSO4.1e-158.3e-153.2e-15从表格能看出几个非常明显的规律。Sphere函数上两种算法都能收敛但ACPSO的精度比PSO高了大约11个数量级。原因在于Tent混沌初始化让初始种群分布更均匀算法从第一代起就占据了更有利的搜索位置再加上后期混沌扰动对gbest的精细打磨收敛精度自然上去了。不过坦率讲对Sphere这种单峰平滑函数PSO的1e-11精度在很多实际应用里已经够用ACPSO的优势更多体现在数学精度层面而非工程实用性。Rastrigin函数才是分水岭。传统PSO在30维Rastrigin上表现相当挣扎20次运行里最优值还能到18.9均值却高达32.4标准差8.7说明多次运行的结果非常不稳定——有的运气好找到18附近有的直接困在40多的局部点。ACPSO则稳定得多均值1.6e-9说明20次运行里绝大多数都能收敛到接近于0的区域。这就是混沌扰动在起作用当粒子群陷入某个局部极小后扰动机制会持续给gbest注入跳出局部所需的新方向多试几次总能找到下坡路。Griewank函数上表现更加极端。PSO的最优值能做到0.014但注意这是接近0但没到0全局最优0附近潜伏着大量局部极小。ACPSO则每次都能直接收敛到0标准差为0说明20次运行全部成功稳定性好得不像随机搜索算法。Ackley函数同理PSO精度停在1e-5左右ACPSO直接推到1e-15附近逼近double类型的浮点精度极限。5.2 从收敛曲线看改进的实际作用阶段只看统计表容易理解成“ACPSO全面碾压PSO”但收敛曲线会告诉你一个更细致的故事。传统PSO的典型收敛曲线是前50次迭代急剧下降曲线斜率很陡之后迅速平坦500次迭代几乎有一大半时间是在平面上趴着。这说明传统PSO在前期的“集体冲刺”效率极高所有粒子快速飞向当前最优区域但也因为这个过程太快种群多样性在前期就大量丧失导致后期没有任何跳出机制。ACPSO的收敛曲线同样在前期快速下降但中后期会出现一个独特现象曲线偶尔会出现“阶梯式跳变”——平缓一段后突然向下砸一个台阶。这正是混沌扰动发挥作用的时刻粒子群在某处停滞混沌扰动在gbest附近尝试新方向一旦碰到更好的位置就立刻更新曲线随之出现断崖式下降。在多峰函数上这种跳变在200次、300次甚至400次迭代后都还有可能出现说明算法直到后期仍保有一定的探索能力。看曲线时不要只盯最终值观察中后期是否还有跳变也很重要。如果一个算法在100次迭代后曲线彻底变平哪怕最终值看起来还行也说明它在更长迭代下没有增长潜力。ACPSO的价值恰恰在于它把这个“死亡平台期”不断往后推迟让算法有更多机会在运行过程中自我修正。6. 复现过程中最容易被忽略的细节与调参心得6.1 混沌序列周期点陷阱Tent映射看着简单实际用起来有个非常隐蔽的坑序列可能跌入周期点尤其是0.2、0.4、0.6、0.8这些值。一旦序列进入这些周期点后续产生的“混沌序列”就变成固定重复的几个数遍历性完全丧失。更麻烦的是浮点精度会导致序列在极小值附近反复震荡看起来在变化实际上都在同一个区域打转。我的处理方式是在每次Tent迭代后加保护判断if y 0.001 || y 0.999 || abs(y - mu) 1e-5 y rand; end这条判断做两件事一是防止y逼近0或1导致序列退化为常数二是当y靠近映射参数μ0.7时下一轮迭代会触发特殊行为用随机数打断潜在周期。很多网上流传的混沌PSO代码省略了这一步跑出来的结果时好时坏还以为是算法本身的问题其实根子在混沌序列退化。另外提醒一句混沌初始化和普通rand初始化虽然都能生成[0,1]之间的数但混沌序列对初值极其敏感。main脚本里用rng(r * 1000)固定了rand的起点所以混沌序列的起始点也是可复现的。如果你在循环里没有重置rng两次运行的“混沌”初始化其实会拿到完全不同的序列对比实验就失去了公平性。6.2 边界处理与维度扩展代码里所有越界粒子都采用直接裁剪也就是把位置强行拉回边界。这个策略在Sphere、Rastrigin这类在边界上函数值较大的测试函数上没问题因为裁剪相当于把越界粒子放回了一个“还说得过去”的位置。但如果遇到最优解贴着搜索边界的问题直接裁剪会导致粒子频繁堆积在边界上速度更新失效。更好的替代方案有两种。一种是反弹策略越界后让速度反向并乘以一个衰减系数模拟粒子“撞墙反弹”另一种是边界吸收随机扰动粒子越界后不仅拉回边界还以一定概率在边界附近随机生成一个新位置保持种群多样性。维度扩展方面这套代码默认lb和ub是标量对所有维度使用同一个边界。如果你的问题每维边界不同需要把lb和ub改为1×dim的向量并同步修改初始化、边界裁剪和混沌扰动三处代码。改法很简单rand(swarm_size, dim)乘上的边界范围不再是标量而是用repmat或点乘展开成矩阵。但要注意混沌扰动半径的计算radius (ub - lb) * 0.15 * ...这行代码在lb/ub为向量时会产生一个向量半径叠加到gbest上时每维扰动幅度不同效果反而更好。6.3 参数调整建议最后聊几个实际调参心得都是踩过坑换来的。alpha取3.0是我试过2、3、4之后得到的一个均衡值。alpha太小惯性权重前期下降太快种群过早进入开发阶段容易早熟alpha太大w在后期仍保持较大值粒子收不住在最优解附近反复震荡收敛精度上不去。如果你的max_iter设得更大比如1000次以上可以适当把alpha调小到2.5让前期的探索期更长。混沌扰动半径的最大值0.15倍搜索范围是比较保守的选择。半径太大扰动点直接跳到远处极大浪费函数评估次数半径太小在早期无法有效跳出局部。0.15倍是一个平衡点能保证扰动点大多数情况下落在较远的有效区域。如果你的函数地形特别复杂可以尝试0.2同时把衰减指数提到1.8让早期探索更充分、后期扰动更快收缩。维度从30升到更高的50或100时混沌初始化的优势会更加明显。我在100维Ackley上测过PSO经常陷入10以上的局部值ACPSO仍能稳定收敛到1e-5左右。但代价是每轮混沌扰动都要生成一条与维度等长的混沌序列迭代500次、30个粒子的情况下耗时还能接受如果维度上千混沌扰动带来的计算开销就需要权衡了。最后再额外提一个常见误区不要盲目把c1、c2都设成2.0。在Rastrigin这类多峰函数上c1c22.0会导致粒子速度过大频繁越界裁剪后多样性损失严重。我实际测试中把c1、c2降到1.5配合w_min0.3在Rastrigin上的全局收敛率反而更高。参数没有万能组合最好基于你自己的测试函数小规模搜索几组候选参数再固定下来跑统计实验。
返回列表