遗传算法和粒子群算法求解非线性函数最大值问题
遗传算法(GA)和粒子群优化算法(PSO)实现,用于求解非线性函数最大值问题,并详细比较两种算法性能。
1. 问题定义与测试函数
%% 主程序:GA和PSO求解非线性函数最大值问题
clear; close all; clc;
warning('off', 'all');
%% 1. 定义测试函数
fprintf('=== GA和PSO求解非线性函数最大值 ===\n');
% 选择测试函数
test_function = 5; % 1-6
% 获取函数信息
[func, func_name, bounds, dim, global_max, global_max_pos] = ...
get_test_function(test_function);
% 显示函数信息
fprintf('测试函数: %s\n', func_name);
fprintf('维度: %d\n', dim);
fprintf('搜索范围: ');
for i = 1:dim
fprintf('[%.2f, %.2f] ', bounds(i,1), bounds(i,2));
end
fprintf('\n');
fprintf('理论最大值: %.6f\n', global_max);
fprintf('理论最大值位置: [');
fprintf('%.2f ', global_max_pos);
fprintf(']\n\n');
%% 2. 算法参数设置
% 2.1 通用参数
params = struct();
params.maxIter = 100; % 最大迭代次数
params.popSize = 50; % 种群大小
params.dim = dim; % 问题维度
params.bounds = bounds; % 搜索边界
params.verbose = true; % 显示详细信息
params.parallel = false; % 是否使用并行计算
% 2.2 遗传算法参数
paramsGA = params;
paramsGA.crossoverProb = 0.8; % 交叉概率
paramsGA.mutationProb = 0.1; % 变异概率
paramsGA.selectionMethod = 'tournament'; % 选择方法: 'roulette', 'tournament'
paramsGA.crossoverMethod = 'blend'; % 交叉方法: 'single', 'two', 'blend'
paramsGA.mutationMethod = 'gaussian'; % 变异方法: 'uniform', 'gaussian'
paramsGA.elitismCount = 2; % 精英保留数量
% 2.3 粒子群算法参数
paramsPSO = params;
paramsPSO.wMax = 0.9; % 最大惯性权重
paramsPSO.wMin = 0.4; % 最小惯性权重
paramsPSO.c1 = 2.0; % 个体学习因子
paramsPSO.c2 = 2.0; % 社会学习因子
paramsPSO.vMax = 0.2; % 最大速度限制(相对于搜索范围的比例)
paramsPSO.vMin = -0.2; % 最小速度限制
%% 3. 运行算法
fprintf('运行遗传算法...\n');
tic;
[bestPosGA, bestFitGA, historyGA] = GeneticAlgorithm(func, paramsGA);
timeGA = toc;
fprintf('遗传算法完成!耗时: %.3f秒\n', timeGA);
fprintf('\n运行粒子群算法...\n');
tic;
[bestPosPSO, bestFitPSO, historyPSO] = ParticleSwarmOptimization(func, paramsPSO);
timePSO = toc;
fprintf('粒子群算法完成!耗时: %.3f秒\n', timePSO);
%% 4. 结果显示
fprintf('\n=== 结果比较 ===\n');
fprintf('%-20s %-20s %-20s\n', '算法', '找到最大值', '误差(%)');
fprintf('%s\n', repmat('-', 60, 1));
errorGA = abs((global_max - bestFitGA) / global_max) * 100;
errorPSO = abs((global_max - bestFitPSO) / global_max) * 100;
fprintf('%-20s %.10f %.2f%%\n', '遗传算法', bestFitGA, errorGA);
fprintf('%-20s %.10f %.2f%%\n', '粒子群算法', bestFitPSO, errorPSO);
fprintf('%-20s %.10f 0.00%%\n', '理论最大值', global_max);
fprintf('\n%-20s %-30s\n', '算法', '最优解位置');
fprintf('%s\n', repmat('-', 60, 1));
fprintf('遗传算法: [');
for i = 1:min(5, dim)
fprintf('%.6f ', bestPosGA(i));
end
if dim > 5
fprintf('... ');
end
fprintf(']\n');
fprintf('粒子群算法: [');
for i = 1:min(5, dim)
fprintf('%.6f ', bestPosPSO(i));
end
if dim > 5
fprintf('... ');
end
fprintf(']\n');
fprintf('理论最优: [');
for i = 1:min(5, dim)
fprintf('%.6f ', global_max_pos(i));
end
if dim > 5
fprintf('... ');
end
fprintf(']\n');
%% 5. 可视化比较
% 5.1 收敛曲线比较
figure('Position', [100, 100, 1400, 800]);
% 收敛曲线
subplot(2, 3, 1);
plot(1:length(historyGA.bestFitness), historyGA.bestFitness, 'b-', 'LineWidth', 2);
hold on;
plot(1:length(historyPSO.bestFitness), historyPSO.bestFitness, 'r-', 'LineWidth', 2);
yline(global_max, 'k--', 'LineWidth', 1.5, 'DisplayName', '理论最大值');
xlabel('迭代次数');
ylabel('函数值');
title('收敛曲线比较');
legend('遗传算法', '粒子群算法', '理论最大值', 'Location', 'best');
grid on;
% 平均适应度
subplot(2, 3, 2);
plot(1:length(historyGA.avgFitness), historyGA.avgFitness, 'b-', 'LineWidth', 2);
hold on;
plot(1:length(historyPSO.avgFitness), historyPSO.avgFitness, 'r-', 'LineWidth', 2);
xlabel('迭代次数');
ylabel('平均函数值');
title('种群平均适应度变化');
legend('遗传算法', '粒子群算法', 'Location', 'best');
grid on;
% 标准差变化
subplot(2, 3, 3);
plot(1:length(historyGA.stdFitness), historyGA.stdFitness, 'b-', 'LineWidth', 2);
hold on;
plot(1:length(historyPSO.stdFitness), historyPSO.stdFitness, 'r-', 'LineWidth', 2);
xlabel('迭代次数');
ylabel('适应度标准差');
title('种群多样性变化');
legend('遗传算法', '粒子群算法', 'Location', 'best');
grid on;
% 5.2 函数曲面可视化(仅适用于2维函数)
if dim == 2
% 创建网格
x1 = linspace(bounds(1,1), bounds(1,2), 100);
x2 = linspace(bounds(2,1), bounds(2,2), 100);
[X1, X2] = meshgrid(x1, x2);
% 计算函数值
Z = zeros(size(X1));
for i = 1:size(X1,1)
for j = 1:size(X1,2)
Z(i,j) = func([X1(i,j), X2(i,j)]);
end
end
% 等高线图
subplot(2, 3, 4);
contourf(X1, X2, Z, 30);
hold on;
plot(bestPosGA(1), bestPosGA(2), 'bo', 'MarkerSize', 10, 'LineWidth', 2, ...
'DisplayName', 'GA最优解');
plot(bestPosPSO(1), bestPosPSO(2), 'rs', 'MarkerSize', 10, 'LineWidth', 2, ...
'DisplayName', 'PSO最优解');
plot(global_max_pos(1), global_max_pos(2), 'k*', 'MarkerSize', 15, 'LineWidth', 2, ...
'DisplayName', '理论最优');
xlabel('x_1');
ylabel('x_2');
title('函数等高线图及最优解位置');
legend('Location', 'best');
colorbar;
grid on;
% 3D曲面图
subplot(2, 3, 5);
surf(X1, X2, Z, 'EdgeColor', 'none', 'FaceAlpha', 0.8);
hold on;
plot3(bestPosGA(1), bestPosGA(2), bestFitGA, 'bo', 'MarkerSize', 10, ...
'LineWidth', 2, 'DisplayName', 'GA最优解');
plot3(bestPosPSO(1), bestPosPSO(2), bestFitPSO, 'rs', 'MarkerSize', 10, ...
'LineWidth', 2, 'DisplayName', 'PSO最优解');
plot3(global_max_pos(1), global_max_pos(2), global_max, 'k*', 'MarkerSize', 15, ...
'LineWidth', 2, 'DisplayName', '理论最优');
xlabel('x_1');
ylabel('x_2');
zlabel('f(x)');
title('函数3D曲面图');
legend('Location', 'best');
grid on;
view(45, 30);
end
% 5.3 算法性能统计
subplot(2, 3, 6);
algorithms = {'遗传算法', '粒子群算法'};
best_values = [bestFitGA, bestFitPSO];
times = [timeGA, timePSO];
iterations = [length(historyGA.bestFitness), length(historyPSO.bestFitness)];
yyaxis left;
bar(best_values);
ylabel('找到的最大值');
ylim([min(best_values)*0.99, global_max*1.01]);
yyaxis right;
plot(times, 's-', 'LineWidth', 2, 'MarkerSize', 10);
ylabel('计算时间(秒)');
set(gca, 'XTickLabel', algorithms);
title('算法性能比较');
grid on;
%% 6. 多次运行统计比较
fprintf('\n=== 统计比较(运行%d次) ===\n', 10);
statsGA = run_multiple_trials(@GeneticAlgorithm, func, paramsGA, 10);
statsPSO = run_multiple_trials(@ParticleSwarmOptimization, func, paramsPSO, 10);
fprintf('\n%-15s %-10s %-10s %-10s %-10s\n', ...
'算法', '均值', '标准差', '最好值', '最差值');
fprintf('%s\n', repmat('-', 55, 1));
fprintf('%-15s %.6f %.6f %.6f %.6f\n', ...
'遗传算法', statsGA.mean, statsGA.std, statsGA.best, statsGA.worst);
fprintf('%-15s %.6f %.6f %.6f %.6f\n', ...
'粒子群算法', statsPSO.mean, statsPSO.std, statsPSO.best, statsPSO.worst);
fprintf('理论最大值: %.6f\n', global_max);
%% 7. 保存结果
results = struct();
results.GA = struct('position', bestPosGA, 'fitness', bestFitGA, 'history', historyGA);
results.PSO = struct('position', bestPosPSO, 'fitness', bestFitPSO, 'history', historyPSO);
results.function = struct('name', func_name, 'dim', dim, 'bounds', bounds, ...
'global_max', global_max, 'global_max_pos', global_max_pos);
results.stats = struct('GA', statsGA, 'PSO', statsPSO);
save('GA_PSO_Comparison.mat', 'results');
fprintf('\n结果已保存到 GA_PSO_Comparison.mat\n');
2. 测试函数定义
function [func, func_name, bounds, dim, global_max, global_max_pos] = ...
get_test_function(choice)
% 获取测试函数
switch choice
case 1 % Sphere函数(单峰)
func = @(x) -sum(x.^2); % 转换为求最大值问题
func_name = 'Sphere Function';
dim = 10;
bounds = repmat([-5, 5], dim, 1);
global_max_pos = zeros(1, dim);
global_max = 0;
case 2 % Rastrigin函数(多峰)
func = @(x) -(10*dim + sum(x.^2 - 10*cos(2*pi*x)));
func_name = 'Rastrigin Function';
dim = 10;
bounds = repmat([-5.12, 5.12], dim, 1);
global_max_pos = zeros(1, dim);
global_max = 0;
case 3 % Ackley函数(多峰)
func = @(x) -(-20*exp(-0.2*sqrt(mean(x.^2))) - ...
exp(mean(cos(2*pi*x))) + 20 + exp(1));
func_name = 'Ackley Function';
dim = 10;
bounds = repmat([-32, 32], dim, 1);
global_max_pos = zeros(1, dim);
global_max = 0;
case 4 % Rosenbrock函数(病态)
func = @(x) -sum(100*(x(2:end) - x(1:end-1).^2).^2 + (1 - x(1:end-1)).^2);
func_name = 'Rosenbrock Function';
dim = 10;
bounds = repmat([-2, 2], dim, 1);
global_max_pos = ones(1, dim);
global_max = 0;
case 5 % Griewank函数(多峰,高维)
func = @(x) -(1 + sum(x.^2)/4000 - prod(cos(x./sqrt(1:dim))));
func_name = 'Griewank Function';
dim = 10;
bounds = repmat([-600, 600], dim, 1);
global_max_pos = zeros(1, dim);
global_max = 0;
case 6 % Schwefel函数(多峰,欺骗性)
func = @(x) -418.9829*dim + sum(x.*sin(sqrt(abs(x))));
func_name = 'Schwefel Function';
dim = 10;
bounds = repmat([-500, 500], dim, 1);
global_max_pos = repmat(420.9687, 1, dim);
global_max = 0;
case 7 % 自定义函数:复杂多峰函数
func = @(x) -(abs(sum(sin(x))) + 1) ./ (0.1 + sqrt(sum(x.^2)));
func_name = 'Custom Complex Function';
dim = 5;
bounds = repmat([-10, 10], dim, 1);
global_max_pos = zeros(1, dim);
global_max = 10; % 近似值
otherwise
error('未知的测试函数选择');
end
end
3. 遗传算法实现
function [bestPosition, bestFitness, history] = GeneticAlgorithm(func, params)
% 遗传算法实现
% 初始化参数
popSize = params.popSize;
maxIter = params.maxIter;
dim = params.dim;
bounds = params.bounds;
verbose = params.verbose;
crossoverProb = params.crossoverProb;
mutationProb = params.mutationProb;
selectionMethod = params.selectionMethod;
crossoverMethod = params.crossoverMethod;
mutationMethod = params.mutationMethod;
elitismCount = params.elitismCount;
% 初始化历史记录
history.bestFitness = zeros(maxIter, 1);
history.avgFitness = zeros(maxIter, 1);
history.stdFitness = zeros(maxIter, 1);
history.bestPosition = zeros(maxIter, dim);
% 1. 初始化种群
population = initializePopulation(popSize, dim, bounds);
fitness = evaluatePopulation(population, func);
% 2. 记录初始状态
[bestFitness, bestIdx] = max(fitness);
bestPosition = population(bestIdx, :);
history.bestFitness(1) = bestFitness;
history.avgFitness(1) = mean(fitness);
history.stdFitness(1) = std(fitness);
history.bestPosition(1, :) = bestPosition;
% 3. 主迭代循环
for iter = 1:maxIter
if verbose && mod(iter, 10) == 0
fprintf('迭代 %3d: 最佳适应度 = %.10f\n', iter, bestFitness);
end
% 3.1 选择
parents = selection(population, fitness, selectionMethod);
% 3.2 交叉
offspring = crossover(parents, crossoverProb, crossoverMethod, bounds);
% 3.3 变异
offspring = mutation(offspring, mutationProb, mutationMethod, bounds, iter, maxIter);
% 3.4 精英保留
[offspring, offspringFitness] = elitism(...
population, fitness, offspring, elitismCount, func);
% 3.5 更新种群
population = offspring;
fitness = offspringFitness;
% 3.6 更新最优解
[currentBestFitness, currentBestIdx] = max(fitness);
currentBestPosition = population(currentBestIdx, :);
if currentBestFitness > bestFitness
bestFitness = currentBestFitness;
bestPosition = currentBestPosition;
end
% 3.7 记录历史
history.bestFitness(iter) = bestFitness;
history.avgFitness(iter) = mean(fitness);
history.stdFitness(iter) = std(fitness);
history.bestPosition(iter, :) = bestPosition;
% 3.8 早停检查(可选)
if iter > 50 && std(history.bestFitness(iter-49:iter)) < 1e-10
if verbose
fprintf('早停在迭代 %d\n', iter);
end
break;
end
end
% 截断历史记录
history.bestFitness = history.bestFitness(1:iter);
history.avgFitness = history.avgFitness(1:iter);
history.stdFitness = history.stdFitness(1:iter);
history.bestPosition = history.bestPosition(1:iter, :);
end
function population = initializePopulation(popSize, dim, bounds)
% 初始化种群
population = zeros(popSize, dim);
for i = 1:popSize
for j = 1:dim
population(i, j) = bounds(j,1) + rand() * (bounds(j,2) - bounds(j,1));
end
end
end
function fitness = evaluatePopulation(population, func)
% 评估种群适应度
popSize = size(population, 1);
fitness = zeros(popSize, 1);
for i = 1:popSize
fitness(i) = func(population(i, :));
end
end
function parents = selection(population, fitness, method)
% 选择操作
popSize = size(population, 1);
parents = zeros(popSize, size(population, 2));
switch method
case 'roulette'
% 轮盘赌选择
fitness_pos = fitness - min(fitness) + eps; % 确保非负
prob = fitness_pos / sum(fitness_pos);
cumProb = cumsum(prob);
for i = 1:popSize
r = rand();
idx = find(cumProb >= r, 1);
parents(i, :) = population(idx, :);
end
case 'tournament'
% 锦标赛选择
tournamentSize = 3;
for i = 1:popSize
% 随机选择k个个体
tournamentIdx = randperm(popSize, tournamentSize);
tournamentFitness = fitness(tournamentIdx);
% 选择最好的一个
[~, bestIdx] = max(tournamentFitness);
parents(i, :) = population(tournamentIdx(bestIdx), :);
end
case 'rank'
% 排序选择
[~, sortedIdx] = sort(fitness, 'descend');
ranks = 1:popSize;
prob = 2*(popSize - ranks + 1) / (popSize*(popSize+1));
cumProb = cumsum(prob);
for i = 1:popSize
r = rand();
idx = find(cumProb >= r, 1);
parents(i, :) = population(sortedIdx(idx), :);
end
end
end
function offspring = crossover(parents, prob, method, bounds)
% 交叉操作
popSize = size(parents, 1);
dim = size(parents, 2);
offspring = parents; % 默认直接复制
for i = 1:2:popSize-1
if rand() < prob
switch method
case 'single'
% 单点交叉
point = randi(dim-1);
offspring(i, point+1:end) = parents(i+1, point+1:end);
offspring(i+1, point+1:end) = parents(i, point+1:end);
case 'two'
% 两点交叉
points = sort(randperm(dim, 2));
offspring(i, points(1):points(2)) = parents(i+1, points(1):points(2));
offspring(i+1, points(1):points(2)) = parents(i, points(1):points(2));
case 'blend'
% 模拟二进制交叉
beta = rand(1, dim);
for j = 1:dim
if rand() < 0.5
beta(j) = (2*rand())^(1/3);
else
beta(j) = (1/(2*(1-rand())))^(1/3);
end
end
offspring(i, :) = 0.5*((1+beta).*parents(i,:) + (1-beta).*parents(i+1,:));
offspring(i+1, :) = 0.5*((1-beta).*parents(i,:) + (1+beta).*parents(i+1,:));
case 'arithmetic'
% 算术交叉
alpha = rand();
offspring(i, :) = alpha*parents(i,:) + (1-alpha)*parents(i+1,:);
offspring(i+1, :) = alpha*parents(i+1,:) + (1-alpha)*parents(i,:);
end
% 边界检查
offspring(i, :) = min(max(offspring(i, :), bounds(:,1)'), bounds(:,2)');
offspring(i+1, :) = min(max(offspring(i+1, :), bounds(:,1)'), bounds(:,2)');
end
end
end
function offspring = mutation(offspring, prob, method, bounds, iter, maxIter)
% 变异操作
popSize = size(offspring, 1);
dim = size(offspring, 2);
for i = 1:popSize
if rand() < prob
switch method
case 'uniform'
% 均匀变异
for j = 1:dim
if rand() < 1/dim
offspring(i, j) = bounds(j,1) + rand()*(bounds(j,2) - bounds(j,1));
end
end
case 'gaussian'
% 高斯变异
for j = 1:dim
if rand() < 1/dim
sigma = (bounds(j,2) - bounds(j,1)) * (1 - iter/maxIter);
mutation = sigma * randn();
offspring(i, j) = offspring(i, j) + mutation;
end
end
case 'nonUniform'
% 非均匀变异
for j = 1:dim
if rand() < 1/dim
r = rand();
tau = (bounds(j,2) - bounds(j,1)) * (1 - iter/maxIter)^2;
if r < 0.5
delta = tau * ((2*r)^(1/(1+iter/maxIter)) - 1);
else
delta = tau * (1 - (2*(1-r))^(1/(1+iter/maxIter)));
end
offspring(i, j) = offspring(i, j) + delta;
end
end
end
% 边界检查
offspring(i, :) = min(max(offspring(i, :), bounds(:,1)'), bounds(:,2)');
end
end
end
function [newPopulation, newFitness] = elitism(...
oldPopulation, oldFitness, newPopulation, elitismCount, func)
% 精英保留策略
[sortedFitness, sortedIdx] = sort(oldFitness, 'descend');
% 保留精英个体
for i = 1:min(elitismCount, length(sortedIdx))
newPopulation(i, :) = oldPopulation(sortedIdx(i), :);
end
% 重新评估适应度
popSize = size(newPopulation, 1);
newFitness = zeros(popSize, 1);
for i = 1:popSize
newFitness(i) = func(newPopulation(i, :));
end
end
4. 粒子群算法实现
function [bestPosition, bestFitness, history] = ParticleSwarmOptimization(func, params)
% 粒子群优化算法实现
% 初始化参数
popSize = params.popSize;
maxIter = params.maxIter;
dim = params.dim;
bounds = params.bounds;
verbose = params.verbose;
wMax = params.wMax;
wMin = params.wMin;
c1 = params.c1;
c2 = params.c2;
vMax = params.vMax;
vMin = params.vMin;
% 计算速度限制
range = bounds(:,2) - bounds(:,1);
vMaxLimit = vMax * range';
vMinLimit = vMin * range';
% 初始化历史记录
history.bestFitness = zeros(maxIter, 1);
history.avgFitness = zeros(maxIter, 1);
history.stdFitness = zeros(maxIter, 1);
history.w = zeros(maxIter, 1);
history.bestPosition = zeros(maxIter, dim);
% 1. 初始化粒子群
[positions, velocities, personalBestPositions, personalBestFitness] = ...
initializePSO(popSize, dim, bounds, func);
% 2. 初始化全局最优
[globalBestFitness, globalBestIdx] = max(personalBestFitness);
globalBestPosition = personalBestPositions(globalBestIdx, :);
history.bestFitness(1) = globalBestFitness;
history.avgFitness(1) = mean(personalBestFitness);
history.stdFitness(1) = std(personalBestFitness);
history.w(1) = wMax;
history.bestPosition(1, :) = globalBestPosition;
% 3. 主迭代循环
for iter = 1:maxIter
% 3.1 自适应调整参数
w = wMax - (wMax - wMin) * iter / maxIter; % 线性递减惯性权重
history.w(iter) = w;
% 3.2 更新每个粒子
for i = 1:popSize
% 更新速度
r1 = rand(1, dim);
r2 = rand(1, dim);
velocities(i, :) = w * velocities(i, :) + ...
c1 * r1 .* (personalBestPositions(i, :) - positions(i, :)) + ...
c2 * r2 .* (globalBestPosition - positions(i, :));
% 速度限制
velocities(i, :) = max(min(velocities(i, :), vMaxLimit), vMinLimit);
% 更新位置
positions(i, :) = positions(i, :) + velocities(i, :);
% 边界处理
for j = 1:dim
if positions(i, j) < bounds(j,1)
positions(i, j) = bounds(j,1);
velocities(i, j) = -0.5 * velocities(i, j); % 反弹
elseif positions(i, j) > bounds(j,2)
positions(i, j) = bounds(j,2);
velocities(i, j) = -0.5 * velocities(i, j); % 反弹
end
end
% 计算当前适应度
currentFitness = func(positions(i, :));
% 更新个体最优
if currentFitness > personalBestFitness(i)
personalBestFitness(i) = currentFitness;
personalBestPositions(i, :) = positions(i, :);
% 更新全局最优
if currentFitness > globalBestFitness
globalBestFitness = currentFitness;
globalBestPosition = positions(i, :);
end
end
end
% 3.3 记录历史信息
history.bestFitness(iter) = globalBestFitness;
history.avgFitness(iter) = mean(personalBestFitness);
history.stdFitness(iter) = std(personalBestFitness);
history.bestPosition(iter, :) = globalBestPosition;
% 3.4 显示进度
if verbose && mod(iter, 10) == 0
fprintf('迭代 %3d: 最佳适应度 = %.10f\n', iter, globalBestFitness);
end
% 3.5 早停检查
if iter > 50 && std(history.bestFitness(iter-49:iter)) < 1e-10
if verbose
fprintf('早停在迭代 %d\n', iter);
end
break;
end
end
% 4. 返回结果
bestPosition = globalBestPosition;
bestFitness = globalBestFitness;
% 截断历史记录
history.bestFitness = history.bestFitness(1:iter);
history.avgFitness = history.avgFitness(1:iter);
history.stdFitness = history.stdFitness(1:iter);
history.w = history.w(1:iter);
history.bestPosition = history.bestPosition(1:iter, :);
end
function [positions, velocities, personalBestPositions, personalBestFitness] = ...
initializePSO(popSize, dim, bounds, func)
% 初始化粒子群
% 初始化位置
positions = zeros(popSize, dim);
for i = 1:popSize
for j = 1:dim
positions(i, j) = bounds(j,1) + rand() * (bounds(j,2) - bounds(j,1));
end
end
% 初始化速度
range = bounds(:,2) - bounds(:,1);
velocities = zeros(popSize, dim);
for i = 1:popSize
for j = 1:dim
velocities(i, j) = -0.1 * range(j) + 0.2 * range(j) * rand();
end
end
% 初始化个体最优
personalBestPositions = positions;
personalBestFitness = zeros(popSize, 1);
for i = 1:popSize
personalBestFitness(i) = func(positions(i, :));
end
end
5. 辅助函数和性能评估
%% 辅助函数
function stats = run_multiple_trials(algorithm_func, func, params, nTrials)
% 多次运行算法进行统计
bestValues = zeros(nTrials, 1);
times = zeros(nTrials, 1);
for trial = 1:nTrials
fprintf('运行 %d/%d...\n', trial, nTrials);
% 运行算法
params.verbose = false; % 关闭详细输出
tic;
[~, bestFit, ~] = algorithm_func(func, params);
elapsedTime = toc;
bestValues(trial) = bestFit;
times(trial) = elapsedTime;
end
% 计算统计量
stats = struct();
stats.mean = mean(bestValues);
stats.std = std(bestValues);
stats.best = max(bestValues);
stats.worst = min(bestValues);
stats.times = times;
stats.values = bestValues;
end
%% 算法性能分析函数
function analyze_algorithm_performance()
% 分析算法在不同维度下的性能
% 测试不同维度的Sphere函数
dims = [2, 5, 10, 20, 30, 50];
nRuns = 10;
resultsGA = cell(length(dims), 1);
resultsPSO = cell(length(dims), 1);
fprintf('\n=== 不同维度下的算法性能分析 ===\n');
fprintf('%-6s %-15s %-15s %-15s %-15s\n', ...
'维度', '算法', '平均适应度', '标准差', '平均时间(秒)');
fprintf('%s\n', repmat('-', 70, 1));
for i = 1:length(dims)
dim = dims(i);
% 定义Sphere函数
func = @(x) -sum(x.^2);
bounds = repmat([-5, 5], dim, 1);
% 遗传算法参数
paramsGA = struct();
paramsGA.popSize = 50;
paramsGA.maxIter = 100;
paramsGA.dim = dim;
paramsGA.bounds = bounds;
paramsGA.verbose = false;
paramsGA.crossoverProb = 0.8;
paramsGA.mutationProb = 0.1;
paramsGA.selectionMethod = 'tournament';
paramsGA.crossoverMethod = 'blend';
paramsGA.mutationMethod = 'gaussian';
paramsGA.elitismCount = 2;
% 粒子群算法参数
paramsPSO = struct();
paramsPSO.popSize = 50;
paramsPSO.maxIter = 100;
paramsPSO.dim = dim;
paramsPSO.bounds = bounds;
paramsPSO.verbose = false;
paramsPSO.wMax = 0.9;
paramsPSO.wMin = 0.4;
paramsPSO.c1 = 2.0;
paramsPSO.c2 = 2.0;
paramsPSO.vMax = 0.2;
paramsPSO.vMin = -0.2;
% 运行多次
statsGA = run_multiple_trials(@GeneticAlgorithm, func, paramsGA, nRuns);
statsPSO = run_multiple_trials(@ParticleSwarmOptimization, func, paramsPSO, nRuns);
% 保存结果
resultsGA{i} = statsGA;
resultsPSO{i} = statsPSO;
% 显示结果
fprintf('%-6d %-15s %-15.6f %-15.6f %-15.3f\n', ...
dim, '遗传算法', statsGA.mean, statsGA.std, mean(statsGA.times));
fprintf('%-6d %-15s %-15.6f %-15.6f %-15.3f\n', ...
dim, '粒子群算法', statsPSO.mean, statsPSO.std, mean(statsPSO.times));
fprintf('\n');
end
% 可视化
figure('Position', [100, 100, 1200, 500]);
% 适应度随维度变化
subplot(1, 3, 1);
ga_means = cellfun(@(x) -x.mean, resultsGA); % 转换为正值
pso_means = cellfun(@(x) -x.mean, resultsPSO);
plot(dims, ga_means, 'bo-', 'LineWidth', 2, 'MarkerSize', 8);
hold on;
plot(dims, pso_means, 'rs-', 'LineWidth', 2, 'MarkerSize', 8);
plot(dims, zeros(size(dims)), 'k--', 'LineWidth', 1.5);
xlabel('维度');
ylabel('平均适应度(正值)');
title('适应度随维度变化');
legend('遗传算法', '粒子群算法', '理论最优', 'Location', 'best');
grid on;
% 计算时间随维度变化
subplot(1, 3, 2);
ga_times = cellfun(@(x) mean(x.times), resultsGA);
pso_times = cellfun(@(x) mean(x.times), resultsPSO);
plot(dims, ga_times, 'bo-', 'LineWidth', 2, 'MarkerSize', 8);
hold on;
plot(dims, pso_times, 'rs-', 'LineWidth', 2, 'MarkerSize', 8);
xlabel('维度');
ylabel('平均计算时间(秒)');
title('计算时间随维度变化');
legend('遗传算法', '粒子群算法', 'Location', 'best');
grid on;
% 成功率(达到理论最优99%)
subplot(1, 3, 3);
ga_success = zeros(length(dims), 1);
pso_success = zeros(length(dims), 1);
for i = 1:length(dims)
ga_success(i) = sum(resultsGA{i}.values > -0.01) / nRuns * 100;
pso_success(i) = sum(resultsPSO{i}.values > -0.01) / nRuns * 100;
end
bar([ga_success, pso_success]);
xlabel('维度索引');
ylabel('成功率(%)');
title('成功率比较');
legend('遗传算法', '粒子群算法', 'Location', 'best');
grid on;
set(gca, 'XTickLabel', dims);
end
%% 混合算法(GA-PSO)
function [bestPosition, bestFitness, history] = GA_PSO_Hybrid(func, params)
% 遗传算法-粒子群混合算法
% 参数
popSize = params.popSize;
maxIter = params.maxIter;
dim = params.dim;
bounds = params.bounds;
verbose = params.verbose;
% 分割种群
nGA = floor(popSize * 0.5);
nPSO = popSize - nGA;
% 初始化历史记录
history.bestFitness = zeros(maxIter, 1);
history.avgFitness = zeros(maxIter, 1);
% 1. 初始化两个子种群
% GA种群
populationGA = initializePopulation(nGA, dim, bounds);
fitnessGA = evaluatePopulation(populationGA, func);
% PSO种群
[positionsPSO, velocitiesPSO, personalBestPositions, personalBestFitness] = ...
initializePSO(nPSO, dim, bounds, func);
% 2. 初始全局最优
[bestFitnessGA, bestIdxGA] = max(fitnessGA);
[bestFitnessPSO, bestIdxPSO] = max(personalBestFitness);
if bestFitnessGA > bestFitnessPSO
globalBestFitness = bestFitnessGA;
globalBestPosition = populationGA(bestIdxGA, :);
else
globalBestFitness = bestFitnessPSO;
globalBestPosition = personalBestPositions(bestIdxPSO, :);
end
% 3. 主迭代循环
for iter = 1:maxIter
% 3.1 运行GA迭代
% 选择
parentsGA = selection(populationGA, fitnessGA, 'tournament');
% 交叉
offspringGA = crossover(parentsGA, 0.8, 'blend', bounds);
% 变异
offspringGA = mutation(offspringGA, 0.1, 'gaussian', bounds, iter, maxIter);
% 评估
fitnessGA = evaluatePopulation(offspringGA, func);
populationGA = offspringGA;
% 3.2 运行PSO迭代
w = 0.9 - (0.9 - 0.4) * iter / maxIter;
for i = 1:nPSO
% 更新速度
r1 = rand(1, dim);
r2 = rand(1, dim);
velocitiesPSO(i, :) = w * velocitiesPSO(i, :) + ...
2.0 * r1 .* (personalBestPositions(i, :) - positionsPSO(i, :)) + ...
2.0 * r2 .* (globalBestPosition - positionsPSO(i, :));
% 更新位置
positionsPSO(i, :) = positionsPSO(i, :) + velocitiesPSO(i, :);
% 边界处理
positionsPSO(i, :) = min(max(positionsPSO(i, :), bounds(:,1)'), bounds(:,2)');
% 计算适应度
currentFitness = func(positionsPSO(i, :));
% 更新个体最优
if currentFitness > personalBestFitness(i)
personalBestFitness(i) = currentFitness;
personalBestPositions(i, :) = positionsPSO(i, :);
end
end
% 3.3 信息交换(迁移)
if mod(iter, 10) == 0
% 选择GA中最好的个体替换PSO中最差的个体
[~, gaBestIdx] = max(fitnessGA);
[~, psoWorstIdx] = min(personalBestFitness);
positionsPSO(psoWorstIdx, :) = populationGA(gaBestIdx, :);
personalBestPositions(psoWorstIdx, :) = populationGA(gaBestIdx, :);
personalBestFitness(psoWorstIdx) = fitnessGA(gaBestIdx);
% 选择PSO中最好的个体替换GA中最差的个体
[~, psoBestIdx] = max(personalBestFitness);
[~, gaWorstIdx] = min(fitnessGA);
populationGA(gaWorstIdx, :) = personalBestPositions(psoBestIdx, :);
fitnessGA(gaWorstIdx) = personalBestFitness(psoBestIdx);
end
% 3.4 更新全局最优
[currentBestFitnessGA, currentBestIdxGA] = max(fitnessGA);
[currentBestFitnessPSO, currentBestIdxPSO] = max(personalBestFitness);
if currentBestFitnessGA > currentBestFitnessPSO
currentBestFitness = currentBestFitnessGA;
currentBestPosition = populationGA(currentBestIdxGA, :);
else
currentBestFitness = currentBestFitnessPSO;
currentBestPosition = personalBestPositions(currentBestIdxPSO, :);
end
if currentBestFitness > globalBestFitness
globalBestFitness = currentBestFitness;
globalBestPosition = currentBestPosition;
end
% 3.5 记录历史
history.bestFitness(iter) = globalBestFitness;
history.avgFitness(iter) = (mean(fitnessGA) * nGA + ...
mean(personalBestFitness) * nPSO) / popSize;
% 3.6 显示进度
if verbose && mod(iter, 10) == 0
fprintf('迭代 %3d: 最佳适应度 = %.10f\n', iter, globalBestFitness);
end
end
% 4. 返回结果
bestPosition = globalBestPosition;
bestFitness = globalBestFitness;
end
参考代码 遗传算法和粒子群算法求解非线性函数最大值问题 www.3dddown.com/cna/97949.html
6. 算法比较总结
遗传算法特点:
-
优点:
- 全局搜索能力强,适合多峰函数
- 对初始值不敏感
- 并行性好,适合大规模优化
- 可以处理离散和连续变量
-
缺点:
- 收敛速度较慢
- 参数调节复杂
- 局部搜索能力较弱
粒子群算法特点:
-
优点:
- 收敛速度快
- 参数少,易于实现
- 局部搜索能力强
- 适合连续优化问题
-
缺点:
- 容易陷入局部最优
- 对初始值敏感
- 处理离散问题较困难
使用建议:
-
选择GA的情况:
- 问题高度多峰
- 需要全局最优解
- 有充足的计算时间
- 问题包含离散变量
-
选择PSO的情况:
- 问题相对简单
- 需要快速收敛
- 连续优化问题
- 计算资源有限
-
混合策略:
- 前期使用GA进行全局探索
- 后期使用PSO进行局部开发
- 结合两者优点,提高整体性能
浙公网安备 33010602011771号