這是一個標準的粒子群優化算法 (PSO) 實現,用於求解無約束優化問題。完整流程:初始化 → 迭代尋優 → 結果繪圖。
%% 清空環境
clear; clc; tic; % 清除變量、命令窗、啟動計時器
%% 參數初始化
% 粒子群核心參數
c1 = 1.49445; % 認知學習因子 (個體經驗權重)
c2 = 1.49445; % 社會學習因子 (群體經驗權重)
maxgen = 200; % 最大迭代次數
sizepop = 20; % 種群規模 (粒子數量)
Vmax = 1; Vmin = -1; % 速度邊界限制
popmax = 5; popmin = -5; % 位置邊界限制
for i = 1:sizepop
pop(i,:) = 5 * rand(1,2); % 在 [-5,5]² 區域隨機初始化位置
V(i,:) = rand(1,2); % 隨機初始化速度
fitness(i) = fun(pop(i,:)); % 計算適應度 (目標函數值)
end
% 找出初始全局最優與個體最優
[bestfitness, bestindex] = min(fitness); % 假設最小化問題
zbest = pop(bestindex, :); % 全局最佳位置
gbest = pop; % 每個粒子的個體最佳位置
fitnessgbest = fitness; % 個體最佳適應度
fitnesszbest = bestfitness; % 全局最佳適應度
💡 注意:原代碼 `rands` 應為 `rand`,`rands` 不是 MATLAB 內建函數。
for i = 1:maxgen
for j = 1:sizepop
% ---- 速度更新 (核心公式) ----
V(j,:) = V(j,:) ...
+ c1 * rand * (gbest(j,:) - pop(j,:)) ... % 認知分量
+ c2 * rand * (zbest - pop(j,:)); % 社會分量
% 速度邊界處理
V(j, V(j,:) > Vmax) = Vmax;
V(j, V(j,:) < Vmin) = Vmin;
% ---- 位置更新 ----
pop(j,:) = pop(j,:) + 0.5 * V(j,:); % 0.5 為慣性權重簡化
% 位置邊界處理 (吸收式邊界)
pop(j, pop(j,:) > popmax) = popmax;
pop(j, pop(j,:) < popmin) = popmin;
% ---- 自適應變異 (增強探索) ----
if rand > 0.8
k = ceil(2 * rand); % 隨機選擇第 1 或 2 維
pop(j,k) = rand * (popmax - popmin) + popmin; % 隨機重置
end
% 計算新適應度
fitness(j) = fun(pop(j,:));
end
% ---- 個體最優更新 ----
for j = 1:sizepop
if fitness(j) < fitnessgbest(j)
gbest(j,:) = pop(j,:);
fitnessgbest(j) = fitness(j);
end
end
% ---- 全局最優更新 ----
[minFit, minIdx] = min(fitness);
if minFit < fitnesszbest
zbest = pop(minIdx, :);
fitnesszbest = minFit;
end
yy(i) = fitnesszbest; % 記錄每代全局最優值
end
toc; % 停止計時
plot(yy, 'b-', 'LineWidth', 1.5);
title(['適應度收斂曲線 終止代數=' num2str(maxgen)]);
xlabel('迭代代數'); ylabel('適應度值');
grid on; % 添加網格便於觀察
| 問題 | 建議 |
|---|---|
| `rands` 未定義 | 改為 `rand` |
| 慣性權重固定 0.5 | 採用線性遞減:`w = 0.9 - 0.5 * i/maxgen` |
| 邊界處理為吸收式 | 改為反射式或隨機重置,避免粒子粘壁 |
| 無收斂判斷 | 加入「連續 N 代無改善則提前終止」 |
| 目標函數 `fun` 未給出 | 需根據具體問題實現,如 `fun = @(x) x(1)^2 + x(2)^2` |
此代碼實現了基礎 PSO 流程,適合作為學習入門模板。實際工程應用建議使用 MATLAB Global Optimization Toolbox 內建 `particleswarm` 或成熟第三方庫(如 matlab-pso),功能更完善、參數調優更靈活。