基于牛顿引力和运动定律的引力搜索算法

引力搜索算法(Gravitational Search Algorithm, GSA)是一种基于牛顿万有引力定律和运动定律的群体智能优化算法。

算法原理

GSA模拟了物理世界中的万有引力现象:

  1. 每个粒子(解决方案)被视为一个有质量的物体
  2. 质量越大表示解决方案越好
  3. 粒子之间通过引力相互作用,导致运动
  4. 随着时间的推移,质量大的粒子会吸引质量小的粒子

代码

function [bestSolution, bestFitness, convergenceCurve] = GSA(objFunc, dim, lb, ub, maxIter, popSize)
    % 引力搜索算法(GSA)
    % 输入:
    %   objFunc: 目标函数
    %   dim: 问题维度
    %   lb: 决策变量下界
    %   ub: 决策变量上界
    %   maxIter: 最大迭代次数
    %   popSize: 种群大小
    % 输出:
    %   bestSolution: 最优解
    %   bestFitness: 最优适应度值
    %   convergenceCurve: 收敛曲线
    
    % 初始化参数
    G0 = 100;    % 初始引力常数
    alpha = 20;  % 衰减系数
    epsilon = 0.1; % 小常数,防止除零
    
    % 初始化种群
    positions = initialization(popSize, dim, ub, lb);
    velocity = zeros(popSize, dim);
    
    % 评估初始种群
    fitness = zeros(popSize, 1);
    for i = 1:popSize
        fitness(i) = objFunc(positions(i, :));
    end
    
    % 记录最佳解
    [bestFitness, bestIndex] = min(fitness);
    bestSolution = positions(bestIndex, :);
    
    % 初始化收敛曲线
    convergenceCurve = zeros(maxIter, 1);
    convergenceCurve(1) = bestFitness;
    
    % 迭代过程
    for iter = 2:maxIter
        % 计算当前引力常数
        G = G0 * exp(-alpha * iter / maxIter);
        
        % 计算每个粒子的质量
        [mass, M] = calculateMass(fitness, popSize);
        
        % 计算每个粒子受到的合力
        acceleration = calculateAcceleration(positions, mass, G, epsilon, iter, maxIter, popSize, dim);
        
        % 更新速度和位置
        velocity = rand(popSize, dim) .* velocity + acceleration;
        positions = positions + velocity;
        
        % 边界处理
        positions = max(positions, lb);
        positions = min(positions, ub);
        
        % 评估新位置
        for i = 1:popSize
            fitness(i) = objFunc(positions(i, :));
        end
        
        % 更新最佳解
        [currentBestFitness, currentBestIndex] = min(fitness);
        if currentBestFitness < bestFitness
            bestFitness = currentBestFitness;
            bestSolution = positions(currentBestIndex, :);
        end
        
        % 记录收敛曲线
        convergenceCurve(iter) = bestFitness;
        
        % 显示迭代信息
        if mod(iter, 100) == 0
            fprintf('迭代次数: %d, 最佳适应度: %f\n', iter, bestFitness);
        end
    end
end

function positions = initialization(popSize, dim, ub, lb)
    % 初始化种群位置
    positions = zeros(popSize, dim);
    for i = 1:popSize
        positions(i, :) = lb + (ub - lb) .* rand(1, dim);
    end
end

function [mass, M] = calculateMass(fitness, popSize)
    % 计算每个粒子的质量
    
    % 找到最差和最佳适应度值
    worst = max(fitness);
    best = min(fitness);
    
    % 处理所有适应度值相同的情况
    if worst == best
        mass = ones(popSize, 1);
        M = mass / sum(mass);
        return;
    end
    
    % 计算质量
    mass = (fitness - worst) ./ (best - worst);
    
    % 归一化质量
    M = mass ./ sum(mass);
end

function acceleration = calculateAcceleration(positions, mass, G, epsilon, iter, maxIter, popSize, dim)
    % 计算每个粒子受到的加速度
    
    % 确定Kbest(随着迭代逐渐减少)
    Kbest = popSize * (1 - 0.9 * iter / maxIter);
    Kbest = max(2, round(Kbest)); % 确保至少有两个粒子
    
    % 按质量排序,选择最好的Kbest个粒子
    [~, sortedIndices] = sort(mass, 'descend');
    activeAgents = sortedIndices(1:Kbest);
    
    % 初始化加速度矩阵
    acceleration = zeros(popSize, dim);
    
    % 计算每个粒子受到的合力
    for i = 1:popSize
        for j = 1:Kbest
            if i ~= activeAgents(j)
                % 计算粒子间的欧氏距离
                R = norm(positions(i, :) - positions(activeAgents(j), :), 2);
                
                % 计算引力
                for k = 1:dim
                    % 引力公式: F = G * (M_i * M_j) / (R + epsilon) * (x_j - x_i)
                    force = G * (mass(i) * mass(activeAgents(j))) / (R + epsilon) * ...
                            (positions(activeAgents(j), k) - positions(i, k));
                    
                    % 随机化引力方向
                    acceleration(i, k) = acceleration(i, k) + rand * force;
                end
            end
        end
        
        % 根据牛顿第二定律计算加速度: a = F / M
        if mass(i) > 0
            acceleration(i, :) = acceleration(i, :) / mass(i);
        end
    end
end

测试

使用GSA解决标准测试函数

% 定义测试函数 (Sphere函数)
sphereFunc = @(x) sum(x.^2);

% 设置参数
dim = 30;           % 问题维度
lb = -100;          % 下界
ub = 100;           % 上界
maxIter = 1000;     % 最大迭代次数
popSize = 50;       % 种群大小

% 运行GSA算法
[bestSolution, bestFitness, convergenceCurve] = GSA(sphereFunc, dim, lb, ub, maxIter, popSize);

% 显示结果
fprintf('最优解: %s\n', mat2str(bestSolution, 4));
fprintf('最优适应度: %f\n', bestFitness);

% 绘制收敛曲线
figure;
plot(convergenceCurve, 'LineWidth', 2);
title('GSA收敛曲线');
xlabel('迭代次数');
ylabel('最佳适应度值');
grid on;

扩展功能:多种测试函数

% 多种测试函数定义
testFunctions = {
    @(x) sum(x.^2),                                    % Sphere函数
    @(x) sum(abs(x)) + prod(abs(x)),                   % Schwefel 2.22函数
    @(x) sum([1:length(x)] .* (x.^4)) + rand,          % Quartic函数
    @(x) sum(100*(x(2:end)-x(1:end-1).^2).^2 + (x(1:end-1)-1).^2) % Rosenbrock函数
};

functionNames = {'Sphere', 'Schwefel 2.22', 'Quartic', 'Rosenbrock'};

% 为每个测试函数运行GSA
results = cell(length(testFunctions), 1);
for i = 1:length(testFunctions)
    fprintf('正在测试函数: %s\n', functionNames{i});
    
    [bestSolution, bestFitness, convergenceCurve] = GSA(...
        testFunctions{i}, dim, lb, ub, maxIter, popSize);
    
    results{i}.bestSolution = bestSolution;
    results{i}.bestFitness = bestFitness;
    results{i}.convergenceCurve = convergenceCurve;
    
    fprintf('%s函数的最优适应度: %f\n\n', functionNames{i}, bestFitness);
end

% 绘制所有测试函数的收敛曲线
figure;
hold on;
colors = ['r', 'g', 'b', 'm'];
for i = 1:length(testFunctions)
    plot(results{i}.convergenceCurve, 'Color', colors(i), 'LineWidth', 1.5, ...
        'DisplayName', functionNames{i});
end
hold off;
title('不同测试函数的GSA收敛曲线');
xlabel('迭代次数');
ylabel('最佳适应度值');
legend('show');
grid on;

参考代码 基于牛顿引力和运动定律的引力搜索算法 www.youwenfan.com/contentcng/99352.html

参数调优建议

  1. 种群大小(popSize): 通常设置在20-100之间,复杂问题需要更大的种群
  2. 最大迭代次数(maxIter): 取决于问题复杂度,一般500-5000次
  3. 初始引力常数(G0): 通常设置为100
  4. 衰减系数(alpha): 控制引力衰减速度,通常设置为20
  5. epsilon: 防止除零的小常数,通常设置为0.1

算法特点

  1. 无梯度优化: GSA不需要目标函数的梯度信息
  2. 全局搜索: 通过引力机制实现有效的全局搜索
  3. 自适应调整: 引力常数随时间衰减,平衡探索与开发
  4. 简单有效: 概念简单,实现容易,在许多问题上表现良好

应用领域

GSA已被成功应用于:

  • 工程优化问题
  • 机器学习参数优化
  • 神经网络训练
  • 图像处理
  • 经济调度问题

这个实现提供了GSA的基本框架,您可以根据具体问题调整参数和算法细节以获得更好的性能。

posted @ 2025-09-09 16:31  风一直那个吹  阅读(7)  评论(0)    收藏  举报