function xmin=wcmaes % CMA-ES: Evolution Strategy with Covariance Matrix Adaptation % and weighted recombination for nonlinear function minimization. % To be used under the terms of the GNU General Public License, % see http://www.gnu.org/copyleft/gpl.html . % Author: Nikolaus Hansen, 2001. % e-mail: hansen@bionik.tu-berlin.de % URL:http://www.bionik.tu-berlin.de/user/niko % Last change: February,7,2003 % Set dimension, fitness fct, start values, stop criteria N=10; strfitnessfct = 'elli'; % 'rosen'; 'cigar'; 'sphere'; 'tablet'; 'sharpR'; maxeval = 300*(N+3)^2; stopfitness = 1e-10; % stop criteria xmeanw = 0.099*ones(N, 1); % object parameter start point sigma = 0.25e-0; minsigma = 1e-15; % initial step size, minimal step size flginiphase = 1; % Initial phase % Parameter setting: selection, lambda = 4+floor(3*log(N)); mu = floor(lambda/2); arweights = log((lambda+1)/2)-log(1:mu)'; % muXone array for weighted recomb. % lambda=10; mu=2; arweights = ones(mu,1); % uncomment for (2_I,10)-ES % parameter setting: adaptation cc = 4/(N+4); ccov = 2/(N+2^0.5)^2; cs = 4/(N+4); damp = (1-min(0.7,N*lambda/maxeval)) / cs + 1; % Initialize dynamic strategy parameters and constants B = eye(N); D = eye(N); BD = B*D; C = BD*transpose(BD); pc = zeros(N,1); ps = zeros(N,1); cw=sum(arweights)/norm(arweights); chiN=N^0.5*(1-1/(4*N)+1/(21*N^2)); % Initialize fitness for output and output arfitness(1)=feval(strfitnessfct, xmeanw); arx(:,1)=xmeanw; arindex=1:mu; outt0=clock; outetime=0.5; outx=[];outy1=[];outy2=[];outy3=[];outy4=[]; % Generation loop disp([' (' num2str(mu) ',' num2str(lambda) ')-CMA-ES (w=[' num2str(arweights','%5.2f') '])' ]); counteval = 0; flgstop = 0; while 1 % if flgstop break; % Set stop flag if arfitness(1) <= stopfitness flgstop = 1; elseif counteval >= maxeval flgstop = 1; end %%% Generate output if 1 & (mod(counteval/lambda, 1) < 1 | flgstop) outx = [outx counteval]; outy1=[outy1; [arfitness(1) sigma cond(D)]]; outy2=[outy2;(arx(:,arindex(1)))']; outy3=[outy3; sigma*sqrt(diag(C))']; outy4=[outy4;sort(diag(D))']; if etime(clock,outt0) > 10*outetime | flgstop | ... etime(clock, outt0) <= 0 % bug fix for etime outt0 = clock; if 1 % graphic output outplot(outx,outy1,outy2,outy3,outy4); % outplot defined below elseif 1 % save data for later graphic output with outplot if ~exist('sfile', 'var') spath = ''; sfile = [spath 'cmaN' num2str(N, '%02d') 'on' strfitnessfct '.mat']; if exist(sfile, 'file') error(['File ' sfile ' already exists.']); end end save(sfile,'counteval','arfitness','arx','outx','outy1', ... 'outy2','outy3','outy4'); end outetime = etime(clock, outt0); end end % output if flgstop break; end % Generate and evaluate lambda offspring arz = randn(N,lambda); arx = xmeanw*ones(1, lambda) + sigma * (BD * arz); % You may handle constraints here and now. % You may either resample columns of arz and/or multiply % them with a factor < 1 (the latter will result in a % decreased overall step size) and recalculate arx % accordingly. Do not change arx or arz in any other % way. You may also use an altered arx only for the % evaluation of the fitness function, if you leave % arx and arz unchanged for the algorithm. for k=1:lambda arfitness(k) = feval(strfitnessfct, arx(:,k)); % Eq. (13) counteval = counteval+1; end % Sort by fitness and compute weighted mean in xmeanw [arfitness, arindex] = sort(arfitness); % minimization xold = xmeanw; % for speed up of Eq. (14) xmeanw = arx(:,arindex(1:mu))*arweights/sum(arweights); zmeanw = arz(:,arindex(1:mu))*arweights/sum(arweights); % Adapt covariance matrix pc = (1-cc)*pc + (sqrt(cc*(2-cc))*cw/sigma) * (xmeanw-xold); % Eq. (14) if ~flginiphase % do not adapt in the initial phase C = (1-ccov)*C + ccov*pc*transpose(pc); % Eq. (15) end % adapt sigma ps = (1-cs)*ps + (sqrt(cs*(2-cs))*cw) * (B*zmeanw); % Eq. (16) sigma = sigma * exp((norm(ps)-chiN)/chiN/damp); % Eq. (17) % Update B and D from C if mod(counteval/lambda, 1/ccov/N/5) < 1 C=triu(C)+transpose(triu(C,1)); % enforce symmetry [B,D] = eig(C); % limit condition of C to 1e14 + 1 if max(diag(D)) > 1e14*min(diag(D)) tmp = max(diag(D))/1e14 - min(diag(D)); C = C + tmp*eye(N); D = D + tmp*eye(N); end D = diag(sqrt(diag(D))); % D contains standard deviations now BD = B*D; % for speed up only end % if mod % Adjust minimal step size if sigma*min(diag(D)) < minsigma ... | arfitness(1) == arfitness(min(mu+1,lambda)) ... | xmeanw == xmeanw ... + 0.2*sigma*BD(:,1+floor(mod(counteval/lambda,N))) sigma = 1.4*sigma; warning(['minimal axis sigma increased to ' num2str(sigma*min(diag(D))) ... ' due to an assumed problem' ]); % flgstop=1; end % Test for end of initial phase if flginiphase & counteval/lambda > 2/cs if (norm(ps)-chiN)/chiN < 0.05 % step size is not much too small flginiphase = 0; end end end % while, end generation loop disp([num2str(counteval) ': ' num2str(arfitness(1))]); if exist('sfile', 'var') disp(['Results saved in ' sfile]); end xmin = arx(:, arindex(1)); % return best point of last generation % --------------------------------------------------------------- function outplot(outx, outy1, outy2, outy3, outy4); figure(324); subplot(2,2,1);semilogy(outx,abs(outy1(:,1))+1e-99,'.-b');hold on; subplot(2,2,1);semilogy(outx,(outy1(:,2)),'-g'); hold on; subplot(2,2,1);semilogy(outx,(outy1(:,3)),'-r'); hold off; title('abs(Function Value), Sigma (gr.), Axis Ratio (red)');grid on;zoom on; subplot(2,2,2); plot(outx,outy2,'-'); title('Object Parameters');grid on;zoom on; subplot(2,2,3); semilogy(outx, outy3, '-'); title('Standard Deviations in All Coordinates');grid on;zoom on; subplot(2,2,4); semilogy(outx, outy4, '-'); title('Scaling (All Main Axes)');grid on;zoom on; drawnow; % --------------------------------------------------------------- function f=sphere(x) f=sum(x.^2); function f=schwefel(x) f = 0; for i = 1:size(x,1) f = f+sum(x(1:i))^2; end function f=cigar(x) f = x(1)^2 + 1e6*sum(x(2:end).^2); function f=tablet(x) f = 1e6*x(1)^2 + sum(x(2:end).^2); function f=elli(x) N = size(x,1); if N < 2 error('dimension must be greater one'); end f=1e6.^((0:N-1)/(N-1)) * x.^2; function f=parabR(x) f = -x(1) + 100*sum(x(2:end).^2); function f=sharpR(x) f = -x(1) + 100*norm(x(2:end)); function f=rosen(x) if size(x,1) < 2 error('dimension must be greater one'); end f = 100*sum((x(1:end-1).^2 - x(2:end)).^2) + sum((x(1:end-1)-1).^2); function f=diffpow(x) N = size(x,1); if N < 2 error('dimension must be greater one'); end f=sum(abs(x).^(2+10*(0:N-1)'/(N-1))); function f=rastrigin10(x) N = size(x,1); if N < 2 error('dimension must be greater one'); end scale=10.^((0:N-1)'/(N-1)); q = 10*size(x,1) + sum((scale.*x).^2 - 10*cos(2*pi*(scale.*x))); function f=fct_rand(x) f=rand;