粒子群优化算法(Particle Swarm Optimization, PSO)代码template (matlab)

% set the target function
objectiveFunction = @yourtargetfunction;

options.NumParticles            = yourparticlenum;
options.MinNeighborhoodFraction = 0.4;
options.seed                    = 11222;
options.inertia_range           = [0.1 0.4];
options.cSelf                   = 1;
options.cSocial                 = 1;
options.StallIterLimit          = 5;
options.MaxFunEvals             = 3000;
options.MaxIter                 = 25;
options.ObjectiveLimit          = 0.0001;
options.TolFun                  = 1.0E-4;

inertia_range = options.inertia_range;
cSelf         = options.cSelf;
cSocial       = options.cSocial;
min_inertia   = min(inertia_range);
max_inertia   = max(inertia_range);
maxInertia    = max_inertia;
minInertia    = min_inertia;

numParticles  = options.NumParticles;
seed          = options.seed;

minNeighborhoodSize = max(2,floor(numParticles*0.4));
rng(seed);

% initiate the parameter vector
paras_init = your initial parameter vector; 
numVariables = length(paras_init);

% set upper bound and lower bound
for i = 1:numVariables
    lb(i) = use your knowledge to determine it;
    ub(i) = use your knowledge to determine it;
end

lb_mat        = repmat(reshape(lb,1,numVariables),numParticles,1);
ub_mat        = repmat(reshape(ub,1,numVariables),numParticles,1);

% The initial position, which will be used as the P position later
p_position = rand(numParticles,numVariables);
p_position = p_position.*lb_mat + (1-p_position).*ub_mat;

% Enforce the bounds
p_position = max(lb_mat,p_position);
p_position = min(ub_mat,p_position);

values      = zeros(numParticles,1);

for i = 1:numParticles
    fprintf(1,'-----------------------\n');
    fprintf('Particle %d is Initiating Started\n', i);
    fprintf(1,'%-30s\n', 'The Position is')
    p_position(i,:)
    values(i) = objectiveFunction(p_position(i,:));
    fprintf(1,'------------------------\n');
end
    
% --------------------------------------------------
% The initial state;
% --------------------------------------------------
state.Fvals       = values;
state.Positions   = p_position;

state.IndividualBestFvals     = state.Fvals;
state.IndividualBestPositions = state.Positions;
state.FunEval                 = numParticles;

[bestFvals,bestPos]  = min(state.Fvals);
fprintf(1,'%-30s:%-10g\n','Best Fvals',bestFvals);
bestFvalsWindow = nan(options.StallIterLimit, 1);

vmax = ub - lb;

v    = repmat(-vmax,numParticles,1) + ...
       repmat(2*vmax,numParticles,1) .* rand(numParticles,numVariables);
   
state.Velocities = v;

inertia = max(inertia_range);

adaptiveInertiaCounter = 0;

if all(inertia_range >= 0)
    adaptiveInertia = max_inertia;
elseif all(inertia_range <= 0)
    adaptiveInertia = min_inertia;
end

adaptiveNeighborhoodSize = minNeighborhoodSize;
state.Iteration = 0;

exitFlag = [];
while isempty(exitFlag)
    
    fprintf(1,'--------------------------------------------------\n');
    fprintf('Iteration %d Started\n', state.Iteration);
    state.Iteration = state.Iteration + 1;
    
    neighborIndex = zeros(numParticles, adaptiveNeighborhoodSize);
    neighborIndex(:, 1) = 1:numParticles; % First neighbor is self
    
    for i = 1:numParticles
        % Determine random neighbors that exclude the particle itself,
        % which is (numParticles-1) particles
        neighbors = randperm(numParticles-1, adaptiveNeighborhoodSize-1);
        % Add 1 to indicies that are >= current particle index
        iShift = neighbors >= i;
        neighbors(iShift) = neighbors(iShift) + 1;
        neighborIndex(i,2:end) = neighbors;
    end
    % Identify the best neighbor
    [~, bestRowIndex] = min(state.IndividualBestFvals(neighborIndex), [], 2);
    bestLinearIndex = (bestRowIndex.'-1).*numParticles + (1:numParticles);
    bestNeighborIndex = neighborIndex(bestLinearIndex);
    
    % Randomness in velocities
    randSelf = rand(numParticles, numVariables);
    randSocial = rand(numParticles, numVariables);
    
    newVelocities = adaptiveInertia*state.Velocities + ...
    cSelf*randSelf.*(state.IndividualBestPositions-state.Positions) + ...
    cSocial*randSocial.*(state.IndividualBestPositions(bestNeighborIndex, :)-state.Positions);
    tfValid = all(isfinite(newVelocities), 2);
    
    % Check for illegal values
    state.Velocities(tfValid,:) = newVelocities(tfValid,:);
    
    % Update the positions
    newPopulation = state.Positions + state.Velocities;
    tfInvalid = ~isfinite(newPopulation);
    newPopulation(tfInvalid) = state.Positions(tfInvalid);
    
    % Enforce bounds, setting the corresponding velocity component to
    % zero if a particle encounters a lower/upper bound
    tfInvalid = newPopulation < lb_mat;
    if any(tfInvalid(:))
        newPopulation(tfInvalid) = lb_mat(tfInvalid);
        state.Velocities(tfInvalid) = 0;
    end
    tfInvalid = newPopulation > ub_mat;
    if any(tfInvalid(:))
        newPopulation(tfInvalid) = ub_mat(tfInvalid);
        state.Velocities(tfInvalid) = 0;
    end
    state.Positions = newPopulation;
    
    values      = zeros(numParticles,1);
    tic;
    for i = 1:numParticles
        fprintf(1,'%-30s:%-10d;%-30s:%-10d\n','Current Iteration:',state.Iteration,'Current Particle',i);
        values(i) = objectiveFunction(p_position(i,:));
    end
    time = toc;
    fprintf(1,'%-30s:%-30g\n','Time for eval',time);
    state.FunEval = state.FunEval  + numParticles;

    state.Fvals = values;
    % Remember the best fvals and positions
    tfImproved = state.Fvals < state.IndividualBestFvals;
    state.IndividualBestFvals(tfImproved) = state.Fvals(tfImproved);
    state.IndividualBestPositions(tfImproved, :) = state.Positions(tfImproved, :);
    bestFvalsWindow(1+mod(state.Iteration-1,options.StallIterLimit)) = min(state.IndividualBestFvals);
    
    % Keep track of improvement in bestFvals and update the adaptive
    % parameters according to the approach described in S. Iadevaia et
    % al. Cancer Res 2010;70:6704-6714 and M. Liu, D. Shin, and H. I.
    % Kang. International Conference on Information, Communications and
    % Signal Processing 2009:1-5.
    newBest = min(state.IndividualBestFvals);
    if isfinite(newBest) && newBest < bestFvals
        bestFvals = newBest;
        state.LastImprovement = state.Iteration;
        adaptiveInertiaCounter = max(0, adaptiveInertiaCounter-1);
        adaptiveNeighborhoodSize = minNeighborhoodSize;
    else
        adaptiveInertiaCounter = adaptiveInertiaCounter+1;
        adaptiveNeighborhoodSize = min(numParticles, adaptiveNeighborhoodSize+minNeighborhoodSize);
    end
    
    % Update the inertia coefficient, enforcing limits (Since inertia
    % can be negative, enforcing both upper *and* lower bounds after
    % multiplying.)
    if adaptiveInertiaCounter < 2
        adaptiveInertia = max(minInertia, min(maxInertia, 2*adaptiveInertia));
    elseif adaptiveInertiaCounter > 5
        adaptiveInertia = max(minInertia, min(maxInertia, 0.5*adaptiveInertia));
    end
    fprintf(1,'%-30s:%-10g\n','Best Fvals',bestFvals);
    [exitFlag,reasonToStop] = stopPso(options,state,bestFvalsWindow);
    fprintf(1,'--------------------------------------------------\n');
end

if exitFlag == 1 || exitFlag == -1 
        % Find and return the best solution
        [fval,bestFvals] = min(state.IndividualBestFvals);
        x = state.IndividualBestPositions(bestFvals,:);

        % Update output structure
        output  = state;
        
        positionBest = state.IndividualBestPositions;
        fvalBest = state.IndividualBestFvals;
        
end

function [exitFlag,reasonToStop] = stopPso(options,state,bestFvalsWindow)
    iteration = state.Iteration;

    iterationIndex = 1+mod(iteration-1,options.StallIterLimit);
    bestFval = bestFvalsWindow(iterationIndex);

    % Compute change in fval and individuals in last 'Window' iterations
    Window = options.StallIterLimit;
    if iteration > Window
        % The smallest fval in the window should be bestFval.
        % The largest fval in the window should be the oldest one in the
        % window. This value is at iterationIndex+1 (or 1).
        if iterationIndex == Window
            % The window runs from index 1:iterationIndex
            maxBestFvalsWindow = bestFvalsWindow(1);
        else
            % The window runs from [iterationIndex+1:end, 1:iterationIndex]
            maxBestFvalsWindow = bestFvalsWindow(iterationIndex+1);
        end
        funChange = abs(maxBestFvalsWindow-bestFval)/max(1,abs(bestFval));
    else
        funChange = Inf;
    end

    reasonToStop = '';
    exitFlag = [];

    if state.FunEval >= options.MaxFunEvals
        reasonToStop = sprintf('Optimization ended: maximum number of function evaluations exceeded.');
        exitFlag = -2;
    elseif state.Iteration >= options.MaxIter
        reasonToStop = sprintf('Optimization ended: maximum number of iterations exceeded.');
        exitFlag = -1;
    elseif bestFval <= options.ObjectiveLimit
        reasonToStop = sprintf('Optimization ended: minimum objective function limit reached.');
        exitFlag = 1;
    elseif funChange <= options.TolFun
        reasonToStop = sprintf('Optimization ended: change in the objective value less than options.TolFun.');
        exitFlag = 1;
    end

    if ~isempty(exitFlag)
        fprintf('%s\n',reasonToStop);
    end
end
    

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
粒子群优化算法 (particle swarm optimization, PSO) 是一种基于群体智能的优化算法,其算法原理可以概括为以下几个步骤: 1. 初始化一群粒子的位置和速度,并随机分配其初始位置和速度。 2. 计算每个粒子的适应度值,并根据适应度值更新每个粒子的最佳位置和全局最佳位置。 3. 根据每个粒子的最佳位置和全局最佳位置,更新粒子的速度和位置。 4. 判断是否满足停止条件,若满足则输出结果,否则回到第 2 步。 具体来说,PSO 算法的每个粒子都有一个位置向量和一个速度向量。在算法的每一轮迭代中,粒子的速度和位置会根据以下公式进行更新: $v_{i}(t+1)=wv_{i}(t)+c_{1}r_{1}(p_{i}-x_{i}(t))+c_{2}r_{2}(p_{g}-x_{i}(t))$ $x_{i}(t+1)=x_{i}(t)+v_{i}(t+1)$ 其中,$v_{i}(t)$ 表示粒子 $i$ 在时间 $t$ 的速度向量,$x_{i}(t)$ 表示粒子 $i$ 在时间 $t$ 的位置向量,$p_{i}$ 表示粒子 $i$ 的历史最佳位置,$p_{g}$ 表示全局最佳位置,$w$、$c_{1}$ 和 $c_{2}$ 是常数,$r_{1}$ 和 $r_{2}$ 是 $[0,1]$ 之间的随机数。 在算法的每轮迭代中,粒子的速度和位置会不断地更新,直到满足停止条件为止。通常,停止条件可以是达到最大迭代次数、适应度值达到一定阈值等。 PSO 算法通过模拟鸟群、鱼群等群体的行为,将一群粒子看作是搜索空间中的一个个潜在解,通过不断更新粒子的位置和速度,最终找到全局最优解或近似最优解。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值