⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pso.m

📁 改进的pso算法(3个m文件和一个说明文件): 本算法实现Clerc and Kennedy 2002年对pso算法的重要改进
💻 M
字号:
function [X,FVAL,EXITFLAG,OUTPUT] = PSO(FUN,X0,LB,UB,OPTIONS,varargin)%PSO finds a minimum of a function of several variables using the particle swarm % optimization (PSO) algorithm originally introduced in 1995 by Kennedy and % Eberhart. This algorithm was extended by Shi and Eberhart in 1998 through the% introduction of inertia factors to dampen the velocities of the particles.% In 2002, Clerc and Kennedy introduced a constriction factor in PSO, which was% later on shown to be superior to the inertia factors. Therefore, the algorithm% using a constriction factor was implemented here.%%   PSO attempts to solve problems of the form:%       min F(X) subject to: LB <= X <= UB%        X%%   X=PSO(FUN,X0) start at X0 and finds a minimum X to the function FUN. %   FUN accepts input X and returns a scalar function value F evaluated at X.%   X0 may be a scalar, vector, or matrix.%   %   X=PSO(FUN,X0,LB,UB) defines a set of lower and upper bounds on the %   design variables, X, so that a solution is found in the range %   LB <= X <= UB. Use empty matrices for LB and UB if no bounds exist. %   Set LB(i) = -Inf if X(i) is unbounded below; set UB(i) = Inf if X(i) is %   unbounded above.%   %   X=PSO(FUN,X0,LB,UB,OPTIONS) minimizes with the default optimization%   parameters replaced by values in the structure OPTIONS, an argument %   created with the PSOSET function. See PSOSET for details. %   Used options are SWARM_SIZE, COGNITIVE_ACC, SOCIAL_ACC, MAX_ITER,%   MAX_TIME, MAX_FUN_EVALS, TOLX, TOLFUN, DISPLAY and OUTPUT_FCN.%   Use OPTIONS = [] as a place holder if no options are set.%   %   X=PSO(FUN,X0,LB,UB,OPTIONS,varargin) is used to supply a variable %   number of input arguments to the objective function FUN.%   %   [X,FVAL]=PSO(FUN,X0,...) returns the value of the objective %   function FUN at the solution X.%   %   [X,FVAL,EXITFLAG]=PSO(FUN,X0,...) returns an EXITFLAG that describes the %   exit condition of PSO. Possible values of EXITFLAG and the corresponding %   exit conditions are:%   %     1  Change in the objective function value less than the specified tolerance.%     2  Change in X less than the specified tolerance.%     0  Maximum number of function evaluations or iterations reached.%    -1  Maximum time exceeded.%   %   [X,FVAL,EXITFLAG,OUTPUT]=PSO(FUN,X0,...) returns a structure OUTPUT with %   the number of iterations taken in OUTPUT.nITERATIONS, the number of function%   evaluations in OUTPUT.nFUN_EVALS, the coordinates of the different particles in %   the swarm in OUTPUT.SWARM, the corresponding fitness values in OUTPUT.FITNESS, %   the particle's best position and its corresponding fitness in OUTPUT.PBEST and%   OUTPUT.PBEST_FITNESS, the best position ever achieved by the swarm in %   OUTPUT.GBEST and its corresponding fitness in OUTPUT.GBEST_FITNESS, the amount%   of time needed in OUTPUT.TIME and the options used in OUTPUT.OPTIONS.% %   See also PSOSET, PSOGET% Copyright (C) 2006 Brecht Donckels, BIOMATH, brecht.donckels@ugent.be% % This program is free software; you can redistribute it and/or% modify it under the terms of the GNU General Public License% as published by the Free Software Foundation; either version 2% of the License, or (at your option) any later version.% % This program is distributed in the hope that it will be useful,% but WITHOUT ANY WARRANTY; without even the implied warranty of% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the% GNU General Public License for more details. % % You should have received a copy of the GNU General Public License% along with this program; if not, write to the Free Software% Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,% USA.% handle variable input argumentsif nargin < 5,    OPTIONS = [];    if nargin < 4,        UB = 1e5;        if nargin < 3,            LB = -1e5;        end    endend% check input argumentsif ~ischar(FUN),    error('''FUN'' incorrectly specified in ''PSO''');endif ~isfloat(X0),    error('''X0'' incorrectly specified in ''PSO''');endif ~isfloat(LB),    error('''LB'' incorrectly specified in ''PSO''');endif ~isfloat(UB),    error('''UB'' incorrectly specified in ''PSO''');endif length(X0) ~= length(LB),    error('''LB'' and ''X0'' have incompatible dimensions in ''PSO''');endif length(X0) ~= length(UB),    error('''UB'' and ''X0'' have incompatible dimensions in ''PSO''');end% declaration of global variablesglobal NDIM nFUN_EVALS% set EXITFLAG to default valueEXITFLAG = -2;% determine number of variables to be optimizedNDIM = length(X0);% seed the random number generatorrand('state',sum(100*clock));% set default optionsDEFAULT_OPTIONS = PSOSET('SWARM_SIZE',25,... % number of particles in swarm for each variable to be optimized             'COGNITIVE_ACC',2.8,...         % cognitive acceleration coefficient (value as recommended in Schutte and Groenwold, 2006)             'SOCIAL_ACC',1.3,...            % social acceleration coefficient (value as recommended in Schutte and Groenwold, 2006)             'MAX_ITER',2500,...             % maximum number of iterations             'MAX_TIME',2500,...             % maximum duration of optimization             'MAX_FUN_EVALS',2500,...        % maximum number of function evaluations             'TOLX',1e-6,...                 % maximum difference between best and worst function evaluation in simplex             'TOLFUN',1e-3,...               % maximum difference between the coordinates of the vertices             'DISPLAY','none',...            % 'iter' or 'none' indicating whether user wants feedback             'OUTPUT_FCN',[]);               % string with output function name% update default options with supplied optionsOPTIONS = PSOSET(DEFAULT_OPTIONS,OPTIONS);% store OPTIONS in OUTPUTOUTPUT.OPTIONS = OPTIONS;% initialize swarm (each row of swarm corresponds to one particle)SWARM = zeros(OPTIONS.SWARM_SIZE,NDIM,OPTIONS.MAX_ITER);for i = 1:OPTIONS.SWARM_SIZE,    if i == 1,        SWARM(1,:,1) = X0(:)';    else        SWARM(i,:,1) = LB(:)' + rand(1,NDIM).*(UB(:)'-LB(:)');    endend% initialize VELOCITIESVELOCITIES = zeros(OPTIONS.SWARM_SIZE,NDIM,OPTIONS.MAX_ITER);% initialize FITNESS, PBEST_FITNESS, GBEST_FITNESS, INDEX_PBEST, index_gbest_particle and INDEX_GBEST_ITERATIONFITNESS = nan(OPTIONS.SWARM_SIZE,OPTIONS.MAX_ITER);PBEST = nan(OPTIONS.SWARM_SIZE,NDIM,OPTIONS.MAX_ITER);GBEST = nan(OPTIONS.MAX_ITER,NDIM);PBEST_FITNESS = nan(OPTIONS.SWARM_SIZE,OPTIONS.MAX_ITER);GBEST_FITNESS = nan(OPTIONS.SWARM_SIZE,1);INDEX_PBEST = nan(OPTIONS.SWARM_SIZE,OPTIONS.MAX_ITER);INDEX_GBEST_PARTICLE = nan(OPTIONS.MAX_ITER,1);INDEX_GBEST_ITERATION = nan(OPTIONS.MAX_ITER,1);% calculate constriction factor from acceleration coefficientsif OPTIONS.COGNITIVE_ACC+OPTIONS.SOCIAL_ACC <= 4,    % display message    disp('Sum of Cognitive Acceleration Coefficient and Social Acceleration Coefficient is less then or equal to 4.')    disp('Their values were adjusted automatically to satisfy this condition.');    disp(' ')    % the values are adjusted so that the sum is equal to 4.1, keeping the ratio COGNITIVE_ACC/SOCIAL_ACC constant    OPTIONS.COGNITIVE_ACC = OPTIONS.COGNITIVE_ACC*4.1/(OPTIONS.COGNITIVE_ACC+OPTIONS.SOCIAL_ACC);    OPTIONS.SOCIAL_ACC = OPTIONS.SOCIAL_ACC*4.1/(OPTIONS.COGNITIVE_ACC+OPTIONS.SOCIAL_ACC);    % calculate constriction factor    k = 1; % k can take values between 0 and 1, but is usually set to one (Montes de Oca et al., 2006)    OPTIONS.ConstrictionFactor = 2*k/(abs(2-(OPTIONS.COGNITIVE_ACC+OPTIONS.SOCIAL_ACC)-sqrt((OPTIONS.COGNITIVE_ACC+OPTIONS.SOCIAL_ACC)^2-4*(OPTIONS.COGNITIVE_ACC+OPTIONS.SOCIAL_ACC))));else    % calculate constriction factor    k = 1; % k can take values between 0 and 1, but is usually set to one (Montes de Oca et al., 2006)    OPTIONS.ConstrictionFactor = 2*k/(abs(2-(OPTIONS.COGNITIVE_ACC+OPTIONS.SOCIAL_ACC)-sqrt((OPTIONS.COGNITIVE_ACC+OPTIONS.SOCIAL_ACC)^2-4*(OPTIONS.COGNITIVE_ACC+OPTIONS.SOCIAL_ACC))));end% initialize countersnITERATIONS = 0;nFUN_EVALS = 0;% initialize timertic% for each iteration....for i = 1:OPTIONS.MAX_ITER,        % if a termination criterium was met, the value of EXITFLAG should have changed    % from its default value of -2 to -1, 0, 1 or 2        if EXITFLAG ~= -2,        break    end        % calculate FITNESS values for all particles in SWARM     % (each row of FITNESS corresponds to the FITNESS value of one particle)    % (each column of FITNESS corresponds to the FITNESS values of the particles in one iteration)        for j = 1:OPTIONS.SWARM_SIZE,        FITNESS(j,i) = CALCULATE_COST(FUN,SWARM(j,:,i),LB,UB,varargin{:});    end        % identify particle's location at which the best FITNESS has been achieved (PBEST)        for j = 1:OPTIONS.SWARM_SIZE,        [PBEST_FITNESS(j,i),INDEX_PBEST(j,i)] = min(FITNESS(j,:));        PBEST(j,:,i) = SWARM(j,:,INDEX_PBEST(j,i));    end        % identify the particle from the SWARM at which the best FITNESS has been achieved so far (GBEST)            [GBEST_FITNESS(i),index_gbest] = min(reshape(FITNESS,numel(FITNESS),1));    [INDEX_GBEST_PARTICLE(i),INDEX_GBEST_ITERATION(i)] = ind2sub(size(FITNESS),index_gbest);    GBEST(i,:) = SWARM(INDEX_GBEST_PARTICLE(i),:,INDEX_GBEST_ITERATION(i));            % update the VELOCITIES        VELOCITIES(:,:,i+1) = OPTIONS.ConstrictionFactor.*(VELOCITIES(:,:,i) + OPTIONS.COGNITIVE_ACC.*rand(OPTIONS.SWARM_SIZE,NDIM).*(PBEST(:,:,i)-SWARM(:,:,i)) + OPTIONS.SOCIAL_ACC.*rand(OPTIONS.SWARM_SIZE,NDIM).*(repmat(GBEST(i,:),[OPTIONS.SWARM_SIZE 1 1],1)-SWARM(:,:,i)));        % update particle positions        SWARM(:,:,i+1) = SWARM(:,:,i)+VELOCITIES(:,:,i+1);        % to make sure that particles stay within specified bounds...    %   (suppose that the particle's new position is outside the boundaries,    %    then the particle's position is adjusted by assuming that the boundary    %    acts like a wall or mirror) (selfmade solution)        for j = 1:OPTIONS.SWARM_SIZE,        for k = 1:NDIM,            % check upper boundary            if length(UB) == 1,                if SWARM(j,k,i+1) > UB,                    SWARM(j,k,i+1) = UB-rand*(SWARM(j,k,i+1)-UB);                    VELOCITIES(j,k,i+1) = SWARM(j,k,i+1)-SWARM(j,k,i);                end            else                if SWARM(j,k,i+1) > UB(k),                    SWARM(j,k,i+1) = UB(k)-rand*(SWARM(j,k,i+1)-UB(k));                    VELOCITIES(j,k,i+1) = SWARM(j,k,i+1)-SWARM(j,k,i);                end            end            % check lower boundary            if length(UB) == 1,                if SWARM(j,k,i+1) < LB,                    SWARM(j,k,i+1) = LB+rand*(LB-SWARM(j,k,i+1));                    VELOCITIES(j,k,i+1) = SWARM(j,k,i+1)-SWARM(j,k,i);                end            else                if SWARM(j,k,i+1) < LB(k),                    SWARM(j,k,i+1) = LB(k)+rand*(LB(k)-SWARM(j,k,i+1));                    VELOCITIES(j,k,i+1) = SWARM(j,k,i+1)-SWARM(j,k,i);                end            end        end    end                % update counters        nITERATIONS = nITERATIONS+1;        % give user feedback on screen if requested        if strcmp(OPTIONS.DISPLAY,'iter'),        if nITERATIONS == 1,            disp(' Nr Iter  Nr Fun Eval    Current best function    Current worst function       Best function');            disp(sprintf(' %5.0f     %5.0f             %12.6g              %12.6g           %15.6g',nITERATIONS,nFUN_EVALS,min(FITNESS(:,i)),max(FITNESS(:,i)),GBEST_FITNESS(i)));        else            disp(sprintf(' %5.0f     %5.0f             %12.6g              %12.6g           %15.6g',nITERATIONS,nFUN_EVALS,min(FITNESS(:,i)),max(FITNESS(:,i)),GBEST_FITNESS(i)));        end    end        % end the optimization if one of the stopping criteria is met    %% 1. difference between best and worst function evaluation in simplex is smaller than TOLFUN     %% 2. maximum difference between the coordinates of the vertices in simplex is less than TOLX    %% 3. no convergence,but maximum number of iterations has been reached    %% 4. no convergence,but maximum time has been reached        if abs(max(FITNESS(:,i))-min(FITNESS(:,i))) < OPTIONS.TOLFUN,        if strcmp(OPTIONS.DISPLAY,'iter'),            disp('Change in the objective function value less than the specified tolerance (TOLFUN).')        end        EXITFLAG = 1;        break;    end        if max(max(abs(diff(SWARM(:,:,i),1,1)))) < OPTIONS.TOLX,        if strcmp(OPTIONS.DISPLAY,'iter'),            disp('Change in X less than the specified tolerance (TOLX).')        end        EXITFLAG = 2;        break;    end        if (i >= OPTIONS.MAX_ITER*NDIM) || (i*OPTIONS.SWARM_SIZE >= OPTIONS.MAX_FUN_EVALS*NDIM*(NDIM+1)),        if strcmp(OPTIONS.DISPLAY,'iter'),            disp('Maximum number of function evaluations or iterations reached.');        end        EXITFLAG = 0;        break;    end        if toc/60 > OPTIONS.MAX_TIME,        if strcmp(OPTIONS.DISPLAY,'iter'),            disp('Exceeded maximum time.');        end        EXITFLAG = -1;        break;    endend% return solutionX = GBEST(i,:);FVAL = GBEST_FITNESS(i);% store number of function evaluationsOUTPUT.nFUN_EVALS = nFUN_EVALS;% store number of iterationsOUTPUT.nITERATIONS = nITERATIONS;% trim OUTPUT data structureOUTPUT.SWARM = SWARM(:,:,1:nITERATIONS);OUTPUT.PBEST = PBEST(:,:,1:nITERATIONS);OUTPUT.GBEST = GBEST(1:nITERATIONS,:);OUTPUT.FITNESS = FITNESS(:,1:nITERATIONS);OUTPUT.PBEST_FITNESS = PBEST_FITNESS(:,1:nITERATIONS);OUTPUT.GBEST_FITNESS = GBEST_FITNESS(1:nITERATIONS,1);% store the amount of time needed in OUTPUT data structureOUTPUT.TIME = toc;return% ==============================================================================% COST FUNCTION EVALUATION% ------------------------function [YTRY] = CALCULATE_COST(FUN,PTRY,LB,UB,varargin)global NDIM nFUN_EVALS% add one to number of function evaluationsnFUN_EVALS = nFUN_EVALS + 1;for i = 1:NDIM,    % check lower bounds    if PTRY(i) < LB(i),        YTRY = 1e12+(LB(i)-PTRY(i))*1e6;        return    end    % check upper bounds    if PTRY(i) > UB(i),        YTRY = 1e12+(PTRY(i)-UB(i))*1e6;        return    endend% calculate cost associated with PTRYYTRY = feval(FUN,PTRY,varargin{:});return

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -