├── Classical functions ├── Step.m ├── Sphere.m ├── Schwefel2_22.m ├── Quartic.m ├── SumSquares.m ├── Schaffer2.m ├── ThreeHumpCamel.m ├── Schwefel1_2.m ├── Rastrigin.m ├── Rosenbrock.m ├── Booth.m ├── Matyas.m ├── Schaffer6.m ├── DropWave.m ├── HolderTable.m ├── Schaffer4.m ├── Bohachevsky3.m ├── Beale.m ├── Bohachevsky2.m ├── SixHumpCamelBack.m ├── Bohachevsky1.m ├── Easom.m ├── Michalewicz.m ├── Zakharov.m ├── DixonPrice.m ├── Griewank.m ├── Shubert.m ├── Colville.m ├── Ackley.m └── Michalewicz_minimum.m ├── Data ├── DATA.mat ├── data1.mat ├── data2.mat ├── DATA_CEC.mat └── dataCEC.mat ├── input_data.zip ├── Algorithms ├── MothSearch.m ├── LSHADE_SPACMA.m ├── LSHADE_cnEpSin.m ├── ElephantHerdingOptimization.m ├── GeneticAlgorithm.m ├── DifferentialEvolution.m ├── ButterflyOptimizationAlgorithm.m ├── BatAlgorithm.m ├── WhaleOptimizationAlgorithm.m ├── ParticleSwarmOptimization.m ├── GreyWolfOptimizer.m ├── MothFlameOptimization.m ├── CuckooSearch.m ├── HarrisHawksOptimization.m ├── LSHADE.m ├── WingsuitFlyingSearch.m ├── MonarchButterflyOptimization.m ├── UMOEA.m └── EBOwithCMAR.m ├── CEC2020 functions ├── cec20_func.cpp ├── CEC2020_functions.m └── cec20_func.mexw64 ├── ReadMe.txt ├── README.md ├── SetParametres.m └── CompareAlgorithms.m /Classical functions/Step.m: -------------------------------------------------------------------------------- 1 | function y = Step(x) 2 | y = sum((x+0.5).^2); 3 | end -------------------------------------------------------------------------------- /Classical functions/Sphere.m: -------------------------------------------------------------------------------- 1 | function y = Sphere(x) 2 | y = sum(x.^2); 3 | end 4 | -------------------------------------------------------------------------------- /Classical functions/Schwefel2_22.m: -------------------------------------------------------------------------------- 1 | function y = Schwefel2_22(x) 2 | y = sum(abs(x)) + prod(abs(x)); 3 | end -------------------------------------------------------------------------------- /Data/DATA.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncovic1/Global-Optimization-Heuristic-Algorithms/HEAD/Data/DATA.mat -------------------------------------------------------------------------------- /Data/data1.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncovic1/Global-Optimization-Heuristic-Algorithms/HEAD/Data/data1.mat -------------------------------------------------------------------------------- /Data/data2.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncovic1/Global-Optimization-Heuristic-Algorithms/HEAD/Data/data2.mat -------------------------------------------------------------------------------- /input_data.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncovic1/Global-Optimization-Heuristic-Algorithms/HEAD/input_data.zip -------------------------------------------------------------------------------- /Classical functions/Quartic.m: -------------------------------------------------------------------------------- 1 | function y = Quartic(x) 2 | j = 1:length(x); 3 | y = sum(j.*x.^4); 4 | end -------------------------------------------------------------------------------- /Data/DATA_CEC.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncovic1/Global-Optimization-Heuristic-Algorithms/HEAD/Data/DATA_CEC.mat -------------------------------------------------------------------------------- /Data/dataCEC.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncovic1/Global-Optimization-Heuristic-Algorithms/HEAD/Data/dataCEC.mat -------------------------------------------------------------------------------- /Classical functions/SumSquares.m: -------------------------------------------------------------------------------- 1 | function y = SumSquares(x) 2 | j = 1:length(x); 3 | y = sum(j.*x.^2); 4 | end -------------------------------------------------------------------------------- /Algorithms/MothSearch.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncovic1/Global-Optimization-Heuristic-Algorithms/HEAD/Algorithms/MothSearch.m -------------------------------------------------------------------------------- /Algorithms/LSHADE_SPACMA.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncovic1/Global-Optimization-Heuristic-Algorithms/HEAD/Algorithms/LSHADE_SPACMA.m -------------------------------------------------------------------------------- /Algorithms/LSHADE_cnEpSin.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncovic1/Global-Optimization-Heuristic-Algorithms/HEAD/Algorithms/LSHADE_cnEpSin.m -------------------------------------------------------------------------------- /CEC2020 functions/cec20_func.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncovic1/Global-Optimization-Heuristic-Algorithms/HEAD/CEC2020 functions/cec20_func.cpp -------------------------------------------------------------------------------- /Classical functions/Schaffer2.m: -------------------------------------------------------------------------------- 1 | function z = Schaffer2(x) 2 | z = 0.5 + ((sin(x(1)^2-x(2)^2))^2-0.5)/(1+0.001*(x(1)^2+x(2)^2))^2; 3 | end 4 | -------------------------------------------------------------------------------- /CEC2020 functions/CEC2020_functions.m: -------------------------------------------------------------------------------- 1 | function y = CEC2020_functions(x) 2 | global fun_num; 3 | y = feval(@cec20_func, x', fun_num); 4 | end -------------------------------------------------------------------------------- /Classical functions/ThreeHumpCamel.m: -------------------------------------------------------------------------------- 1 | function z = ThreeHumpCamel(x) 2 | z = 2*x(1)^2 - 1.05*x(1)^4 + x(1)^6/6 + x(1)*x(2) + x(2)^2; 3 | end 4 | -------------------------------------------------------------------------------- /CEC2020 functions/cec20_func.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncovic1/Global-Optimization-Heuristic-Algorithms/HEAD/CEC2020 functions/cec20_func.mexw64 -------------------------------------------------------------------------------- /Algorithms/ElephantHerdingOptimization.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncovic1/Global-Optimization-Heuristic-Algorithms/HEAD/Algorithms/ElephantHerdingOptimization.m -------------------------------------------------------------------------------- /Classical functions/Schwefel1_2.m: -------------------------------------------------------------------------------- 1 | function y = Schwefel1_2(x) 2 | for i = 1:length(x) 3 | y(i) = sum(x(1:i))^2; 4 | end 5 | y = sum(y); 6 | end -------------------------------------------------------------------------------- /Classical functions/Rastrigin.m: -------------------------------------------------------------------------------- 1 | function z = Rastrigin(x) 2 | z = 10*length(x); 3 | for i=1:length(x) 4 | z = z + (x(i)^2-10*cos(2*pi*x(i))); 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /Classical functions/Rosenbrock.m: -------------------------------------------------------------------------------- 1 | function z = Rosenbrock(x) 2 | z = 0; 3 | for i=1:length(x)-1 4 | z = z + (100*(x(i+1) - x(i)^2)^2 + (1-x(i))^2); 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /Classical functions/Booth.m: -------------------------------------------------------------------------------- 1 | function [y] = Booth(x) 2 | 3 | x1 = x(1); 4 | x2 = x(2); 5 | 6 | term1 = (x1 + 2*x2 - 7)^2; 7 | term2 = (2*x1 + x2 - 5)^2; 8 | 9 | y = term1 + term2; 10 | 11 | end 12 | -------------------------------------------------------------------------------- /Classical functions/Matyas.m: -------------------------------------------------------------------------------- 1 | function [y] = Matyas(x) 2 | 3 | x1 = x(1); 4 | x2 = x(2); 5 | 6 | term1 = 0.26 * (x1^2 + x2^2); 7 | term2 = -0.48*x1*x2; 8 | 9 | y = term1 + term2; 10 | 11 | end 12 | -------------------------------------------------------------------------------- /Classical functions/Schaffer6.m: -------------------------------------------------------------------------------- 1 | function y = Schaffer6(x) 2 | y = 0; 3 | for i = 1:length(x)-1 4 | y = y + 0.5 + ((sin(sqrt(x(i)^2+x(i+1)^2)))^2-0.5)/((1+0.001*(x(i)^2+x(i+1)^2))^2); 5 | end 6 | end -------------------------------------------------------------------------------- /Classical functions/DropWave.m: -------------------------------------------------------------------------------- 1 | function [y] = DropWave(x) 2 | 3 | x1 = x(1); 4 | x2 = x(2); 5 | 6 | 7 | frac1 = 1 + cos(12*sqrt(x1^2+x2^2)); 8 | frac2 = 0.5*(x1^2+x2^2) + 2; 9 | 10 | y = -frac1/frac2; 11 | 12 | end 13 | -------------------------------------------------------------------------------- /Classical functions/HolderTable.m: -------------------------------------------------------------------------------- 1 | function [y] = HolderTable(x) 2 | 3 | x1 = x(1); 4 | x2 = x(2); 5 | 6 | fact1 = sin(x1)*cos(x2); 7 | fact2 = exp(abs(1 - sqrt(x1^2+x2^2)/pi)); 8 | 9 | y = -abs(fact1*fact2); 10 | 11 | end 12 | -------------------------------------------------------------------------------- /Classical functions/Schaffer4.m: -------------------------------------------------------------------------------- 1 | function [y] = Schaffer4(x) 2 | 3 | x1 = x(1); 4 | x2 = x(2); 5 | 6 | fact1 = (cos(sin(abs(x1^2-x2^2))))^2 - 0.5; 7 | fact2 = (1 + 0.001*(x1^2+x2^2))^2; 8 | 9 | y = 0.5 + fact1/fact2; 10 | 11 | end 12 | -------------------------------------------------------------------------------- /Classical functions/Bohachevsky3.m: -------------------------------------------------------------------------------- 1 | function [y] = Bohachevsky3(x) 2 | 3 | x1 = x(1); 4 | x2 = x(2); 5 | 6 | term1 = x1^2; 7 | term2 = 2*x2^2; 8 | term3 = -0.3 * cos(3*pi*x1 + 4*pi*x2); 9 | 10 | y = term1 + term2 + term3 + 0.3; 11 | 12 | end 13 | -------------------------------------------------------------------------------- /Classical functions/Beale.m: -------------------------------------------------------------------------------- 1 | function [y] = Beale(x) 2 | 3 | x1 = x(1); 4 | x2 = x(2); 5 | 6 | term1 = (1.5 - x1 + x1*x2)^2; 7 | term2 = (2.25 - x1 + x1*x2^2)^2; 8 | term3 = (2.625 - x1 + x1*x2^3)^2; 9 | 10 | y = term1 + term2 + term3; 11 | 12 | end 13 | -------------------------------------------------------------------------------- /Classical functions/Bohachevsky2.m: -------------------------------------------------------------------------------- 1 | function [y] = Bohachevsky2(x) 2 | 3 | x1 = x(1); 4 | x2 = x(2); 5 | 6 | term1 = x1^2; 7 | term2 = 2*x2^2; 8 | term3 = -0.3 * cos(3*pi*x1) * cos(4*pi*x2); 9 | 10 | y = term1 + term2 + term3 + 0.3; 11 | 12 | end 13 | -------------------------------------------------------------------------------- /Classical functions/SixHumpCamelBack.m: -------------------------------------------------------------------------------- 1 | function [y] = SixHumpCamelBack(x) 2 | 3 | x1 = x(1); 4 | x2 = x(2); 5 | 6 | term1 = (4-2.1*x1^2+(x1^4)/3) * x1^2; 7 | term2 = x1*x2; 8 | term3 = (-4+4*x2^2) * x2^2; 9 | 10 | y = term1 + term2 + term3; 11 | 12 | end 13 | -------------------------------------------------------------------------------- /Classical functions/Bohachevsky1.m: -------------------------------------------------------------------------------- 1 | function [y] = Bohachevsky1(x) 2 | 3 | x1 = x(1); 4 | x2 = x(2); 5 | 6 | term1 = x1^2; 7 | term2 = 2*x2^2; 8 | term3 = -0.3 * cos(3*pi*x1); 9 | term4 = -0.4 * cos(4*pi*x2); 10 | 11 | y = term1 + term2 + term3 + term4 + 0.7; 12 | 13 | end 14 | -------------------------------------------------------------------------------- /Classical functions/Easom.m: -------------------------------------------------------------------------------- 1 | function z = Easom(x) 2 | d = length(x); 3 | z1 = 0; 4 | for i = 1:d 5 | z1 = z1 + (x(i)-pi)^2; 6 | end 7 | z = 1; 8 | for i = 1:d 9 | z = z*cos(x(i))*exp(-z1); 10 | end 11 | z = z*(-1)^(d+1); 12 | end 13 | -------------------------------------------------------------------------------- /Classical functions/Michalewicz.m: -------------------------------------------------------------------------------- 1 | function [y] = Michalewicz(x) 2 | 3 | m = 10; 4 | 5 | d = length(x); 6 | sum = 0; 7 | 8 | for ii = 1:d 9 | xi = x(ii); 10 | new = sin(xi) * (sin(ii*xi^2/pi))^(2*m); 11 | sum = sum + new; 12 | end 13 | 14 | y = -sum; 15 | 16 | end 17 | -------------------------------------------------------------------------------- /Classical functions/Zakharov.m: -------------------------------------------------------------------------------- 1 | function [y] = Zakharov(x) 2 | 3 | 4 | d = length(x); 5 | sum1 = 0; 6 | sum2 = 0; 7 | 8 | for ii = 1:d 9 | xi = x(ii); 10 | sum1 = sum1 + xi^2; 11 | sum2 = sum2 + 0.5*ii*xi; 12 | end 13 | 14 | y = sum1 + sum2^2 + sum2^4; 15 | 16 | end 17 | -------------------------------------------------------------------------------- /ReadMe.txt: -------------------------------------------------------------------------------- 1 | - First, add folders 'Algorithms', 'CEC2014 functions' and 'Classical functions' to the path. 2 | - To compare WFS with similar algorithms just run the file 'CompareAlgorithms.m'. All settings may be adjust there. 3 | - Complete implementation of WFS algorithm is located in Algorithms -> 'WingsuitFlyingSearch.m'. 4 | -------------------------------------------------------------------------------- /Classical functions/DixonPrice.m: -------------------------------------------------------------------------------- 1 | function [y] = DixonPrice(x) 2 | 3 | x1 = x(1); 4 | d = length(x); 5 | term1 = (x1-1)^2; 6 | 7 | sum = 0; 8 | for ii = 2:d 9 | xi = x(ii); 10 | xold = x(ii-1); 11 | new = ii * (2*xi^2 - xold)^2; 12 | sum = sum + new; 13 | end 14 | 15 | y = term1 + sum; 16 | 17 | end 18 | -------------------------------------------------------------------------------- /Classical functions/Griewank.m: -------------------------------------------------------------------------------- 1 | function [y] = Griewank(x) 2 | d = length(x); 3 | sum = 0; 4 | prod = 1; 5 | 6 | for ii = 1:d 7 | xi = x(ii); 8 | sum = sum + xi^2/4000; 9 | prod = prod * cos(xi/sqrt(ii)); 10 | end 11 | 12 | y = sum - prod + 1; 13 | 14 | end 15 | -------------------------------------------------------------------------------- /Classical functions/Shubert.m: -------------------------------------------------------------------------------- 1 | function [y] = Shubert(x) 2 | 3 | x1 = x(1); 4 | x2 = x(2); 5 | sum1 = 0; 6 | sum2 = 0; 7 | 8 | for ii = 1:5 9 | new1 = ii * cos((ii+1)*x1+ii); 10 | new2 = ii * cos((ii+1)*x2+ii); 11 | sum1 = sum1 + new1; 12 | sum2 = sum2 + new2; 13 | end 14 | 15 | y = sum1 * sum2; 16 | 17 | end 18 | -------------------------------------------------------------------------------- /Classical functions/Colville.m: -------------------------------------------------------------------------------- 1 | function [y] = Colville(x) 2 | 3 | x1 = x(1); 4 | x2 = x(2); 5 | x3 = x(3); 6 | x4 = x(4); 7 | 8 | term1 = 100 * (x1^2-x2)^2; 9 | term2 = (x1-1)^2; 10 | term3 = (x3-1)^2; 11 | term4 = 90 * (x3^2-x4)^2; 12 | term5 = 10.1 * ((x2-1)^2 + (x4-1)^2); 13 | term6 = 19.8*(x2-1)*(x4-1); 14 | 15 | y = term1 + term2 + term3 + term4 + term5 + term6; 16 | 17 | end 18 | -------------------------------------------------------------------------------- /Classical functions/Ackley.m: -------------------------------------------------------------------------------- 1 | function [y] = Ackley(x) 2 | 3 | a = 20; 4 | b = 0.2; 5 | c = 2*pi; 6 | 7 | d = length(x); 8 | 9 | if (nargin < 4) 10 | c = 2*pi; 11 | end 12 | if (nargin < 3) 13 | b = 0.2; 14 | end 15 | if (nargin < 2) 16 | a = 20; 17 | end 18 | 19 | sum1 = 0; 20 | sum2 = 0; 21 | for ii = 1:d 22 | xi = x(ii); 23 | sum1 = sum1 + xi^2; 24 | sum2 = sum2 + cos(c*xi); 25 | end 26 | 27 | term1 = -a * exp(-b*sqrt(sum1/d)); 28 | term2 = -exp(sum2/d); 29 | 30 | y = term1 + term2 + a + exp(1); 31 | 32 | end 33 | -------------------------------------------------------------------------------- /Algorithms/GeneticAlgorithm.m: -------------------------------------------------------------------------------- 1 | function [solution, fval, fvals, runtime] = GeneticAlgorithm(fitness, n, ... 2 | constraints, pop_size, num_gen) 3 | stall_gen_limit = 100; 4 | num_elite = 2; 5 | fvals = []; 6 | 7 | options = gaoptimset(... 8 | 'OutputFcn', @gaoutfun, ... 9 | 'PopulationType', 'doubleVector', ... 10 | 'Generations',num_gen-1,... 11 | 'EliteCount', num_elite,... 12 | 'TolFun', 0,... 13 | 'TolCon', 0,... 14 | 'PopulationSize', pop_size, ... 15 | 'StallGenLimit', stall_gen_limit,... 16 | 'Display', 'off'); 17 | A = []; 18 | b = []; 19 | Aeq = []; 20 | beq = []; 21 | nonlcon = []; 22 | LB = constraints(:,1); 23 | UB = constraints(:,2); 24 | tic; 25 | [solution, fval] = ga(fitness, n, A, b, Aeq, beq, LB, UB, nonlcon, options); 26 | runtime = toc; 27 | 28 | function [state,options,optchanged] = gaoutfun(options,state,flag) 29 | optchanged = false; 30 | % Find the best objective function 31 | if ~isempty(state.Best) 32 | ibest = state.Best(end); 33 | ibest = find(state.Score == ibest,1,'last'); 34 | bestx = state.Population(ibest,:); 35 | bestf = fitness(bestx); 36 | fvals = [fvals; bestf]; 37 | end 38 | end 39 | end -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Wingsuit-Flying-Search 2 | In this paper, a novel global optimization algorithm - Wingsuit Flying Search (WFS) is introduced. It is inspired by the popular extreme sport - wingsuit flying. The algorithm mimics the intention of a flier to land at the lowest possible point of the Earth surface within their range, i.e., a global minimum of the search space. This is achieved by probing the search space at each iteration with a carefully picked population of points. Iterative update of the population corresponds to the flier progressively getting a sharper image of the surface, thus shifting the focus to lower regions. The algorithm is described in detail, including the mathematical background and the pseudocode. It is validated using a variety of classical and CEC 2020 benchmark functions under a number of search space dimensionalities. The validation includes the comparison of WFS to several nature-inspired popular metaheuristic algorithms, including the winners of CEC 2017 competition. The numerical results indicate that WFS algorithm provides considerable performance improvements (mean solution values, standard deviation of solution values, runtime and convergence rate) with respect to other methods. The main advantages of this algorithm are that it is practically parameter-free, apart from the population size and maximal number of iterations. Moreover, it is considerably "lean" and easy to implement. 3 | -------------------------------------------------------------------------------- /Classical functions/Michalewicz_minimum.m: -------------------------------------------------------------------------------- 1 | function [ fmin, xmin ] = Michalewicz_minimum( dim ) 2 | 3 | % michalewicz_min 4 | % input: problem dimension (starting at 1), output: function value at minimum and 5 | % coordinates of minimum 6 | 7 | fmin = 0; 8 | xmin = zeros(1,dim); 9 | 10 | % compute the minimum for each dimension 11 | for d = 1:dim 12 | 13 | % compute the location of the peak, which is very close to the minimum 14 | n = round(0.25*d -0.5); 15 | fraction = sqrt((2*n+1)/(2*d)); 16 | 17 | % if the fraction equals 0.5, the peak is located at the minimum. 18 | if fraction == 0.5 19 | fmin = fmin + -1; 20 | xmin(d) = 0.5*pi; 21 | continue; 22 | end 23 | 24 | % determine the search domain for ternary search 25 | if (fraction < 0.5) 26 | x0 = fraction*pi; 27 | x3 = 0.5*pi; 28 | else 29 | x0 = 0.5*pi; 30 | x3 = fraction*pi; 31 | end 32 | 33 | % ternary search 34 | while(abs(x3-x0) > 1e-14) 35 | 36 | x1 = x0+(x3-x0)/3; 37 | f1 = michalewicz_term(x1,d); 38 | 39 | x2 = x3-(x3-x0)/3; 40 | f2 = michalewicz_term(x2,d); 41 | 42 | % update the search range 43 | if( f2 < f1 ) 44 | x0 = x1; 45 | else 46 | x3 = x2; 47 | end 48 | 49 | end 50 | 51 | % update the values of the minimum 52 | xmin(d) = (x3+x0)/2; 53 | fmin = fmin + michalewicz_term(xmin(d),d); 54 | 55 | 56 | end 57 | 58 | 59 | 60 | end 61 | 62 | function f = michalewicz_term( x, dim ) 63 | % a single term of the michalewicz function. 64 | 65 | f = -sin(x).*(sin(dim*x.^2/pi).^20); 66 | 67 | end 68 | 69 | -------------------------------------------------------------------------------- /Algorithms/DifferentialEvolution.m: -------------------------------------------------------------------------------- 1 | function [best_x, best_val, BestCost, runtime] = DifferentialEvolution(CostFunction, nVar, constraints, nPop, MaxIt) 2 | 3 | tic; 4 | %% Problem Definition 5 | %CostFunction=@(x) Sphere(x); % Cost Function 6 | %nVar=20; % Number of Decision Variables 7 | VarSize=[1 nVar]; % Decision Variables Matrix Size 8 | VarMin= constraints(1,1); % Lower Bound of Decision Variables 9 | VarMax= constraints(1,2); % Upper Bound of Decision Variables 10 | %% DE Parameters 11 | %MaxIt=1000; % Maximum Number of Iterations 12 | %nPop=50; % Population Size 13 | beta_min=0.2; % Lower Bound of Scaling Factor 14 | beta_max=0.8; % Upper Bound of Scaling Factor 15 | pCR=0.2; % Crossover Probability 16 | %% Initialization 17 | empty_individual.Position=[]; 18 | empty_individual.Cost=[]; 19 | BestSol.Cost=inf; 20 | pop=repmat(empty_individual,nPop,1); 21 | for i=1:nPop 22 | pop(i).Position=unifrnd(VarMin,VarMax,VarSize); 23 | 24 | pop(i).Cost=CostFunction(pop(i).Position); 25 | 26 | if pop(i).CostUb; 84 | ns_tmp(J)=Ub; 85 | % Update this new move 86 | s=ns_tmp; 87 | end 88 | 89 | function y=sensory_modality_NEW(x,Ngen) 90 | y=x+(0.025/(x*Ngen)); 91 | end 92 | 93 | function [X]=initialization(N,dim,up,down) 94 | 95 | if size(up,1)==1 96 | X=rand(N,dim).*(up-down)+down; 97 | end 98 | if size(up,1)>1 99 | for i=1:dim 100 | high=up(i);low=down(i); 101 | X(:,i)=rand(1,N).*(high-low)+low; 102 | end 103 | end 104 | end 105 | 106 | -------------------------------------------------------------------------------- /Algorithms/BatAlgorithm.m: -------------------------------------------------------------------------------- 1 | function [BestPositions, fmin, Convergence_curve, runtime] = BatAlgorithm(fobj, dim, constraints, N, Max_iter) 2 | %% 3 | %Max_iter=20; % maximum generations 4 | %N=10; % BAT numbers 5 | %dim=10; 6 | lb=constraints(:,1)'; 7 | ub=constraints(:,2)'; 8 | Fmax=2; %maximum frequency 9 | Fmin=0; %minimum frequency 10 | A=rand(N,1); %loudness for each BAT 11 | r=rand(N,1); %pulse emission rate for each BAT 12 | alpha=0.5; %constant for loudness update 13 | gamma=0.5; %constant for emission rate update 14 | ro=0.001; %initial pulse emission rate 15 | 16 | tic; 17 | % Initializing arrays 18 | F=zeros(N,1); % Frequency 19 | v=zeros(N,dim); % Velocities 20 | % Initialize the population 21 | x=initializationb(N,Max_iter,dim,ub,lb); 22 | Convergence_curve=zeros(1,Max_iter); 23 | %calculate the initial solution for initial positions 24 | 25 | for ii=1:N 26 | fitness(ii)=fobj(x(ii,:)); 27 | end 28 | 29 | [fmin,index]=min(fitness); %find the initial best fitness value 30 | Convergence_curve(1) = fmin; 31 | bestsol=x(index,:); %find the initial best solution for best fitness value 32 | %% 33 | iter=1; % start the loop counter 34 | while iterub; 42 | Flag4low=x(ii,:)r(ii) 46 | % The factor 0.001 limits the step sizes of random walks 47 | % x(ii,:)=bestsol+0.001*randn(1,dim); 48 | eps=-1+(1-(-1))*rand; 49 | x(ii,:)=bestsol+eps*mean(A); 50 | end 51 | fitnessnew=fobj(x(ii,:)); % calculate the objective function 52 | % Update if the solution improves, or not too loud 53 | if (fitnessnew<=fitness(ii)) && (rand1 90 | for i=1:dim 91 | ub_i=ub(i); 92 | lb_i=lb(i); 93 | x(:,i)=rand(N,1).*(ub_i-lb_i)+lb_i; 94 | end 95 | end 96 | end 97 | -------------------------------------------------------------------------------- /Algorithms/WhaleOptimizationAlgorithm.m: -------------------------------------------------------------------------------- 1 | function [Leader_pos, Leader_score, Convergence_curve, runtime] = WhaleOptimizationAlgorithm(fobj, dim, constraints, SearchAgents_no, Max_iter) 2 | 3 | tic; 4 | % initialize position vector and score for the leader 5 | Leader_pos=zeros(1,dim); 6 | Leader_score=inf; %change this to -inf for maximization problems 7 | 8 | 9 | %Initialize the positions of search agents 10 | lb = constraints(1,1); 11 | ub = constraints(1,2); 12 | Positions=initialization(SearchAgents_no,dim,ub,lb); 13 | 14 | Convergence_curve=zeros(1,Max_iter); 15 | 16 | t=0;% Loop counter 17 | 18 | % Main loop 19 | while tub; 24 | Flag4lb=Positions(i,:) for maximization problem 32 | Leader_score=fitness; % Update alpha 33 | Leader_pos=Positions(i,:); 34 | end 35 | 36 | end 37 | 38 | a=2-t*((2)/Max_iter); % a decreases linearly fron 2 to 0 in Eq. (2.3) 39 | 40 | % a2 linearly dicreases from -1 to -2 to calculate t in Eq. (3.12) 41 | a2=-1+t*((-1)/Max_iter); 42 | 43 | % Update the Position of search agents 44 | for i=1:size(Positions,1) 45 | r1=rand(); % r1 is a random number in [0,1] 46 | r2=rand(); % r2 is a random number in [0,1] 47 | 48 | A=2*a*r1-a; % Eq. (2.3) in the paper 49 | C=2*r2; % Eq. (2.4) in the paper 50 | 51 | 52 | b=1; % parameters in Eq. (2.5) 53 | l=(a2-1)*rand+1; % parameters in Eq. (2.5) 54 | 55 | p = rand(); % p in Eq. (2.6) 56 | 57 | for j=1:size(Positions,2) 58 | 59 | if p<0.5 60 | if abs(A)>=1 61 | rand_leader_index = floor(SearchAgents_no*rand()+1); 62 | X_rand = Positions(rand_leader_index, :); 63 | D_X_rand=abs(C*X_rand(j)-Positions(i,j)); % Eq. (2.7) 64 | Positions(i,j)=X_rand(j)-A*D_X_rand; % Eq. (2.8) 65 | 66 | elseif abs(A)<1 67 | D_Leader=abs(C*Leader_pos(j)-Positions(i,j)); % Eq. (2.1) 68 | Positions(i,j)=Leader_pos(j)-A*D_Leader; % Eq. (2.2) 69 | end 70 | 71 | elseif p>=0.5 72 | 73 | distance2Leader=abs(Leader_pos(j)-Positions(i,j)); 74 | % Eq. (2.5) 75 | Positions(i,j)=distance2Leader*exp(b.*l).*cos(l.*2*pi)+Leader_pos(j); 76 | 77 | end 78 | 79 | end 80 | end 81 | t=t+1; 82 | Convergence_curve(t)=Leader_score; 83 | end 84 | 85 | runtime = toc; 86 | 87 | end 88 | 89 | 90 | function Positions = initialization(SearchAgents_no,dim,ub,lb) 91 | 92 | Boundary_no= size(ub,2); % numnber of boundaries 93 | 94 | % If the boundaries of all variables are equal and user enter a signle 95 | % number for both ub and lb 96 | if Boundary_no==1 97 | Positions=rand(SearchAgents_no,dim).*(ub-lb)+lb; 98 | end 99 | 100 | % If each variable has a different lb and ub 101 | if Boundary_no>1 102 | for i=1:dim 103 | ub_i=ub(i); 104 | lb_i=lb(i); 105 | Positions(:,i)=rand(SearchAgents_no,1).*(ub_i-lb_i)+lb_i; 106 | end 107 | end 108 | 109 | end 110 | 111 | -------------------------------------------------------------------------------- /Algorithms/ParticleSwarmOptimization.m: -------------------------------------------------------------------------------- 1 | function [gbest, fmin0, fvals, runtime] = ParticleSwarmOptimization(cost_fun, dimensionality, constraints,... 2 | num_particles, maxite) 3 | t = cputime; 4 | 5 | % objective function (minimization) 6 | ofun = cost_fun; 7 | 8 | LB = constraints(:,1); %lower bounds of variables 9 | UB = constraints(:,2); %upper bounds of variables 10 | 11 | % pso parameters values 12 | m = dimensionality; % number of variables 13 | n = num_particles; % population size 14 | wmax = 0.9; % inertia weight 15 | wmin = 0.4; % inertia weight 16 | c1 = 2; % acceleration factor 17 | c2 = 2; % acceleration factor 18 | 19 | % pso main program----------------------------------------------------start 20 | maxrun = 1; % set maximum number of runs need to be 21 | for run=1:maxrun 22 | % pso initialization----------------------------------------------start 23 | for i=1:n 24 | for j=1:m 25 | x0(i,j)=LB(j)+rand()*(UB(j)-LB(j)); 26 | end 27 | end 28 | x=x0; % initial population 29 | v=0.1*x0; % initial velocity 30 | for i=1:n 31 | f0(i,1)=ofun(x0(i,:)); 32 | end 33 | [fmin0,index0]=min(f0); 34 | fvals = fmin0; 35 | pbest=x0; % initial pbest 36 | gbest=x0(index0,:); % initial gbest 37 | % pso initialization------------------------------------------------end 38 | 39 | % pso algorithm---------------------------------------------------start 40 | ite=1; 41 | tolerance=1; 42 | while ite<=maxite-1 43 | 44 | w=wmax-(wmax-wmin)*ite/maxite; % update inertial weight 45 | 46 | % pso velocity updates 47 | for i=1:n 48 | for j=1:m 49 | v(i,j)=w*v(i,j)+c1*rand()*(pbest(i,j)-x(i,j))... 50 | +c2*rand()*(gbest(1,j)-x(i,j)); 51 | end 52 | end 53 | 54 | % pso position update 55 | for i=1:n 56 | for j=1:m 57 | x(i,j)=x(i,j)+v(i,j); 58 | end 59 | end 60 | 61 | % handling boundary violations 62 | for i=1:n 63 | for j=1:m 64 | if x(i,j)UB(j) 67 | x(i,j)=UB(j); 68 | end 69 | end 70 | end 71 | 72 | % evaluating fitness 73 | for i=1:n 74 | f(i,1)=ofun(x(i,:)); 75 | end 76 | 77 | % updating pbest and fitness 78 | for i=1:n 79 | if f(i,1)100; 98 | tolerance=abs(ffmin(ite-100,run)-fmin0); 99 | end 100 | 101 | ite=ite+1; 102 | end 103 | % pso algorithm-----------------------------------------------------end 104 | end 105 | 106 | 107 | runtime = cputime-t; 108 | %% 109 | end -------------------------------------------------------------------------------- /Algorithms/GreyWolfOptimizer.m: -------------------------------------------------------------------------------- 1 | function [Alpha_pos, Alpha_score, Convergence_curve, runtime] = GreyWolfOptimizer(fobj, dim, constraints, SearchAgents_no, Max_iter) 2 | 3 | tic; 4 | % initialize alpha, beta, and delta_pos 5 | Alpha_pos=zeros(1,dim); 6 | Alpha_score=inf; %change this to -inf for maximization problems 7 | 8 | Beta_pos=zeros(1,dim); 9 | Beta_score=inf; %change this to -inf for maximization problems 10 | 11 | Delta_pos=zeros(1,dim); 12 | Delta_score=inf; %change this to -inf for maximization problems 13 | 14 | %Initialize the positions of search agents 15 | lb = constraints(1,1); 16 | ub = constraints(1,2); 17 | Positions=initialization(SearchAgents_no,dim,ub,lb); 18 | 19 | Convergence_curve=zeros(1,Max_iter); 20 | 21 | l=0;% Loop counter 22 | 23 | % Main loop 24 | while lub; 29 | Flag4lb=Positions(i,:)Alpha_score && fitnessAlpha_score && fitness>Beta_score && fitness1 111 | for i=1:dim 112 | ub_i=ub(i); 113 | lb_i=lb(i); 114 | Positions(:,i)=rand(SearchAgents_no,1).*(ub_i-lb_i)+lb_i; 115 | end 116 | end 117 | 118 | end 119 | 120 | 121 | -------------------------------------------------------------------------------- /Algorithms/MothFlameOptimization.m: -------------------------------------------------------------------------------- 1 | function [Best_flame_pos, Best_flame_score, Convergence_curve, runtime] = MothFlameOptimization(fobj, dim, constraints, N, Max_iteration) 2 | 3 | tic; 4 | 5 | lb = constraints(1,1); 6 | ub = constraints(1,2); 7 | 8 | %Initialize the positions of moths 9 | Moth_pos=initialization(N,dim,ub,lb); 10 | 11 | Convergence_curve=zeros(1,Max_iteration); 12 | 13 | Iteration=1; 14 | 15 | % Main loop 16 | while Iterationub; 25 | Flag4lb=Moth_pos(i,:)Flame_no % Upaate the position of the moth with respct to one flame 83 | 84 | % Eq. (3.13) 85 | distance_to_flame=abs(sorted_population(i,j)-Moth_pos(i,j)); 86 | b=1; 87 | t=(a-1)*rand+1; 88 | 89 | % Eq. (3.12) 90 | Moth_pos(i,j)=distance_to_flame*exp(b.*t).*cos(t.*2*pi)+sorted_population(Flame_no,j); 91 | end 92 | 93 | end 94 | 95 | end 96 | 97 | Convergence_curve(Iteration)=Best_flame_score; 98 | 99 | % Display the iteration and best optimum obtained so far 100 | Iteration=Iteration+1; 101 | end 102 | 103 | runtime = toc; 104 | 105 | end 106 | 107 | 108 | function X=initialization(SearchAgents_no,dim,ub,lb) 109 | 110 | Boundary_no= size(ub,2); % numnber of boundaries 111 | 112 | % If the boundaries of all variables are equal and user enter a signle 113 | % number for both ub and lb 114 | if Boundary_no==1 115 | X=rand(SearchAgents_no,dim).*(ub-lb)+lb; 116 | end 117 | 118 | % If each variable has a different lb and ub 119 | if Boundary_no>1 120 | for i=1:dim 121 | ub_i=ub(i); 122 | lb_i=lb(i); 123 | X(:,i)=rand(SearchAgents_no,1).*(ub_i-lb_i)+lb_i; 124 | end 125 | end 126 | 127 | end 128 | 129 | 130 | -------------------------------------------------------------------------------- /Algorithms/CuckooSearch.m: -------------------------------------------------------------------------------- 1 | function [bestnest, fmin, fvals, runtime] = CuckooSearch(fun, dim, constraints, ps, genn) 2 | %% Simple bounds of the search domain dim 3 | pa=0.25; 4 | Lb = constraints(1,1); 5 | Ub = constraints(1,2); 6 | opti=ones(1,genn); 7 | nest=zeros(ps,dim); 8 | new_nest=zeros(ps,dim); 9 | fitness=10^10*ones(ps,1); 10 | av=zeros(1,genn); 11 | Niter=1; 12 | s=zeros(1,dim); 13 | %% Change this if you want to get better results 14 | % Tolerance 15 | %Tol=1.0e-5; 16 | tic; 17 | % Random initial solutions 18 | nest=rand(ps,dim)*(Ub-Lb)+Lb; 19 | % Get the current best 20 | [fmin,bestnest,nest,fitness]=get_best_nest(fun, nest,nest,fitness,ps); 21 | fvals = fmin; 22 | av(Niter)=sum(fitness)/ps; 23 | opti(1)=fmin; 24 | %% Starting iterations 25 | while(Niter < genn) 26 | % Generate new solutions (but keep the current best) 27 | new_nest=get_cuckoos(nest,bestnest,Lb,Ub); 28 | [fnew,best,nest,fitness]=get_best_nest(fun, nest,new_nest,fitness,ps); 29 | % Update the counter 30 | Niter=Niter+1; 31 | av(Niter)=sum(fitness)/ps; 32 | opti(Niter)=opti(Niter-1); 33 | if opti(Niter)>=fnew 34 | opti(Niter)=fnew; 35 | bestnest=best; 36 | end 37 | 38 | fvals = [fvals; opti(Niter)]; 39 | % Discovery and randomization 40 | 41 | % A fraction of worse nests are discovered with a probability pa 42 | % Discovered or not -- a status vector 43 | K=rand(size(nest))>pa; 44 | % In the real world, if a cuckoo's egg is very similar to a host's eggs, then 45 | % this cuckoo's egg is less likely to be discovered, thus the fitness should 46 | % be related to the difference in solutions. Therefore, it is a good idea 47 | % to do a random walk in a biased way with some random step sizes. 48 | % New solution by biased/selective random walks 49 | stepsize=rand*(nest(randperm(ps),:)-nest(randperm(ps),:)); 50 | new_nest=nest+stepsize.*K; 51 | for j=1:ps 52 | s=new_nest(j,:); 53 | new_nest(j,:)=simplebounds(s,Lb,Ub); 54 | end 55 | if (Niter < genn) 56 | [fnew,best,nest,fitness]=get_best_nest(fun, nest,new_nest,fitness,ps); 57 | 58 | % Update the counter 59 | Niter=Niter+1; 60 | av(Niter)=sum(fitness)/ps; 61 | opti(Niter)=opti(Niter-1); 62 | if opti(Niter)>=fnew % Find the best objective so far 63 | opti(Niter)=fnew; 64 | bestnest=best; 65 | end 66 | fvals = [fvals; opti(Niter)]; 67 | end 68 | end %% End of iterations 69 | 70 | %% Post-optimization processing 71 | %% Display all the nests 72 | %disp(strcat('Total number of iterations=',num2str(Niter))); 73 | fmin=opti(Niter); 74 | runtime = toc; 75 | end 76 | 77 | 78 | %% Find the current best nest 79 | function [fmin,best,nest,fitness]=get_best_nest(fun, nest,newnest,fitness,ps) 80 | % Evaluating all new solutions 81 | for j=1:ps 82 | fnew=fun(newnest(j,:)); 83 | if fnew<=fitness(j), 84 | fitness(j)=fnew; 85 | nest(j,:)=newnest(j,:); 86 | end 87 | end 88 | % Find the current best 89 | [fmin,K]=min(fitness); 90 | best=nest(K,:); 91 | end 92 | 93 | 94 | %% --------------- All subfunctions are list below ------------------ 95 | %% Get cuckoos by ramdom walk 96 | function nest=get_cuckoos(nest,best,Lb,Ub) 97 | % Levy flights 98 | n=size(nest,1); 99 | % Levy exponent and coefficient 100 | % For details, see equation (2.21), Page 16 (chapter 2) of the book 101 | % X. S. Yang, Nature-Inspired Metaheuristic Algorithms, 2nd Edition, Luniver Press, (2010). 102 | beta=3/2; 103 | sigma=(gamma(1+beta)*sin(pi*beta/2)/(gamma((1+beta)/2)*beta*2^((beta-1)/2)))^(1/beta); 104 | 105 | for j=1:n, 106 | s=nest(j,:); 107 | % This is a simple way of implementing Levy flights 108 | % For standard random walks, use step=1; 109 | %% Levy flights by Mantegna's algorithm 110 | u=randn(size(s))*sigma; 111 | v=randn(size(s)); 112 | step=u./abs(v).^(1/beta); 113 | 114 | % In the next equation, the difference factor (s-best) means that 115 | % when the solution is the best solution, it remains unchanged. 116 | stepsize=0.01*step.*(s-best); 117 | % Here the factor 0.01 comes from the fact that L/100 should the typical 118 | % step size of walks/flights where L is the typical lenghtscale; 119 | % otherwise, Levy flights may become too aggresive/efficient, 120 | % which makes new solutions (even) jump out side of the design domain 121 | % (and thus wasting evaluations). 122 | % Now the actual random walks or flights 123 | s=s+stepsize.*randn(size(s)); 124 | % Apply simple bounds/limits 125 | nest(j,:)=simplebounds(s,Lb,Ub); 126 | end 127 | end 128 | 129 | 130 | % Application of simple constraints 131 | function s=simplebounds(s,Lb,Ub) 132 | % Apply the lower bound 133 | ns_tmp=s; 134 | 135 | II=ns_tmpUb; 140 | ns_tmp(JJ)=Ub; 141 | % Update this new move 142 | s=ns_tmp; 143 | end 144 | -------------------------------------------------------------------------------- /SetParametres.m: -------------------------------------------------------------------------------- 1 | function [f_real, constraints, fun] = SetParametres(fun_number, n) 2 | global x_real; 3 | if fun_number == 1 4 | fun = @Step; 5 | x_real = -0.5*ones(1, n); 6 | f_real = fun(x_real(1,:)); 7 | constraints = 5.12*[-ones(n,1), ones(n,1)]; 8 | elseif fun_number == 2 9 | fun = @Sphere; 10 | x_real = zeros(1, n); 11 | f_real = fun(x_real(1,:)); 12 | constraints = 100*[-ones(n,1), ones(n,1)]; 13 | elseif fun_number == 3 14 | fun = @SumSquares; 15 | x_real = zeros(1, n); 16 | f_real = fun(x_real(1,:)); 17 | constraints = 10*[-ones(n,1), ones(n,1)]; 18 | elseif fun_number == 4 19 | fun = @Quartic; 20 | x_real = zeros(1, n); 21 | f_real = fun(x_real(1,:)); 22 | constraints = 1.28*[-ones(n,1), ones(n,1)]; 23 | elseif fun_number == 5 24 | fun = @Beale; 25 | x_real = [3, 0.5]; 26 | f_real = fun(x_real(1,:)); 27 | constraints = 4.5*[-ones(n,1), ones(n,1)]; 28 | elseif fun_number == 6 29 | fun = @Easom; 30 | x_real = pi*ones(1, n); 31 | f_real = fun(x_real(1,:)); 32 | constraints = 100*[-ones(n,1), ones(n,1)]; 33 | elseif fun_number == 7 34 | fun = @Matyas; 35 | x_real = zeros(1, n); 36 | f_real = fun(x_real(1,:)); 37 | constraints = 10*[-ones(n,1), ones(n,1)]; 38 | elseif fun_number == 8 39 | fun = @Colville; 40 | x_real = ones(1, n); 41 | f_real = fun(x_real(1,:)); 42 | constraints = 10*[-ones(n,1), ones(n,1)]; 43 | elseif fun_number == 9 44 | fun = @Zakharov; 45 | x_real = zeros(1, n); 46 | f_real = fun(x_real(1,:)); 47 | constraints = [-5*ones(n,1), 10*ones(n,1)]; 48 | elseif fun_number == 10 49 | fun = @Schwefel2_22; 50 | x_real = zeros(1, n); 51 | f_real = fun(x_real(1,:)); 52 | constraints = 10*[-ones(n,1), ones(n,1)]; 53 | elseif fun_number == 11 54 | fun = @Schwefel1_2; 55 | x_real = zeros(1, n); 56 | f_real = fun(x_real(1,:)); 57 | constraints = 100*[-ones(n,1), ones(n,1)]; 58 | elseif fun_number == 12 59 | fun = @DixonPrice; 60 | i = 1:n; 61 | x_real(i) = 2.^(-(2.^i-2)./2.^i); 62 | f_real = 0; 63 | constraints = 10*[-ones(n,1), ones(n,1)]; 64 | elseif fun_number == 13 65 | fun = @Bohachevsky1; 66 | x_real = zeros(1, n); 67 | f_real = fun(x_real(1,:)); 68 | constraints = 100*[-ones(n,1), ones(n,1)]; 69 | elseif fun_number == 14 70 | fun = @Booth; 71 | x_real = [1 3]; 72 | f_real = fun(x_real(1,:)); 73 | constraints = 10*[-ones(n,1), ones(n,1)]; 74 | elseif fun_number == 15 75 | fun = @HolderTable; 76 | x_real = [8.055023472141116, 9.664590028909654; 8.055023472141116, -9.664590028909654; 77 | -8.055023472141116, 9.664590028909654; -8.055023472141116, -9.664590028909654]; 78 | f_real = fun(x_real(1,:)); 79 | constraints = 10*[-ones(n,1), ones(n,1)]; 80 | elseif fun_number == 16 81 | fun = @Michalewicz; 82 | [f_real, x_real] = Michalewicz_minimum(2); 83 | constraints = [zeros(n,1), pi*ones(n,1)]; 84 | elseif fun_number == 17 85 | fun = @Michalewicz; 86 | [f_real, x_real] = Michalewicz_minimum(5); 87 | constraints = [zeros(n,1), pi*ones(n,1)]; 88 | elseif fun_number == 18 89 | fun = @Michalewicz; 90 | [f_real, x_real] = Michalewicz_minimum(10); 91 | constraints = [zeros(n,1), pi*ones(n,1)]; 92 | elseif fun_number == 19 93 | fun = @Rastrigin; 94 | x_real = zeros(1, n); 95 | f_real = fun(x_real(1,:)); 96 | constraints = 5.12*[-ones(n,1), ones(n,1)]; 97 | elseif fun_number == 20 98 | fun = @Schaffer2; 99 | x_real = [0 0]; 100 | f_real = fun(x_real(1,:)); 101 | constraints = 100*[-ones(n,1), ones(n,1)]; 102 | elseif fun_number == 21 103 | fun = @Schaffer4; 104 | x_real = [0, 1.25313; 0, -1.25313; 1.25313, 0; -1.25313, 0]; 105 | f_real = fun(x_real(1,:)); 106 | constraints = 100*[-ones(n,1), ones(n,1)]; 107 | elseif fun_number == 22 108 | fun = @Schaffer6; 109 | x_real = zeros(1, n); 110 | f_real = fun(x_real(1,:)); 111 | constraints = 100*[-ones(n,1), ones(n,1)]; 112 | elseif fun_number == 23 113 | fun = @SixHumpCamelBack; 114 | x_real = [0.0898, -0.7126; -0.0898, 0.7126]; 115 | f_real = -1.031628453489836; 116 | constraints = 5*[-ones(n,1), ones(n,1)]; 117 | elseif fun_number == 24 118 | fun = @Bohachevsky2; 119 | x_real = zeros(1, n); 120 | f_real = fun(x_real(1,:)); 121 | constraints = 100*[-ones(n,1), ones(n,1)]; 122 | elseif fun_number == 25 123 | fun = @Bohachevsky3; 124 | x_real = zeros(1, n); 125 | f_real = fun(x_real(1,:)); 126 | constraints = 100*[-ones(n,1), ones(n,1)]; 127 | elseif fun_number == 26 128 | fun = @Shubert; 129 | x_real = [-7.708303 -0.800343]; % one of 18 global optima 130 | f_real = -186.7309; 131 | constraints = 10*[-ones(n,1), ones(n,1)]; 132 | elseif fun_number == 27 133 | fun = @DropWave; 134 | x_real = zeros(1, n); 135 | f_real = fun(x_real(1,:)); 136 | constraints = 5.12*[-ones(n,1), ones(n,1)]; 137 | elseif fun_number == 28 138 | fun = @Rosenbrock; 139 | x_real = ones(1, n); 140 | f_real = fun(x_real(1,:)); 141 | constraints = 30*[-ones(n,1), ones(n,1)]; 142 | elseif fun_number == 29 143 | fun = @Griewank; 144 | x_real = zeros(1, n); 145 | f_real = fun(x_real(1,:)); 146 | constraints = 600*[-ones(n,1), ones(n,1)]; 147 | elseif fun_number == 30 148 | fun = @Ackley; 149 | x_real = zeros(1, n); 150 | f_real = fun(x_real(1,:)); 151 | constraints = 32*[-ones(n,1), ones(n,1)]; 152 | end 153 | 154 | end -------------------------------------------------------------------------------- /CompareAlgorithms.m: -------------------------------------------------------------------------------- 1 | close all; 2 | set(groot,'defaulttextinterpreter','latex'); 3 | set(groot, 'defaultAxesTickLabelInterpreter','latex'); 4 | set(groot, 'defaultLegendInterpreter','latex'); 5 | 6 | %% Classical benchmark functions 7 | % Unimodal and separable benchmark functions 8 | % 1: Step % n-dim 9 | % 2: Sphere % n-dim 10 | % 3: SumSquares % n-dim 11 | % 4: Quartic % n-dim 12 | 13 | % Unimodal and non-separable benchmark functions 14 | % 5: Beale % 2D 15 | % 6: Easom % 2D 16 | % 7: Matyas % 2D 17 | % 8: Colville % 4D 18 | % 9: Zakharov % n-dim 19 | % 10: Schwefel2_22 % n-dim 20 | % 11: Schwefel1_2 % n-dim 21 | % 12: DixonPrice % n-dim 22 | 23 | % Multimodal and separable benchmark functions 24 | % 13: Bohachevsky1 % 2D 25 | % 14: Booth % 2D 26 | % 15: HolderTable % 2D 27 | % 16: Michalewicz2 % 2D 28 | % 17: Michalewicz5 % 5D 29 | % 18: Michalewicz10 % 10D 30 | % 19: Rastrigin % n-dim 31 | 32 | % Multimodal and non-separable benchmark functions 33 | % 20: Schaffer2 % 2D 34 | % 21: Schaffer4 % 2D 35 | % 22: Schaffer6 % n-dim 36 | % 23: SixHumpCamelBack % 2D 37 | % 24: Bohachevsky2 % 2D 38 | % 25: Bohachevsky3 % 2D 39 | % 26: Shubert % 2D 40 | % 27: DropWave % 2D 41 | % 28: Rosenbrock % n-dim 42 | % 29: Griewank % n-dim 43 | % 30: Ackley % n-dim 44 | 45 | %% CEC 2014 benchmark functions (see https://bee22.com/resources/Liang%20CEC2014.pdf) 46 | % Used functions: [1,2, 5,6,10,16, 17,22, 25,28] 47 | 48 | %% Settings 49 | n1 = [30,30,30,30, 2,2,2,4,10,30,30,30, 2,2,2,2,5,10,30, 2,2,30,2,2,2,2,2,30,30,30]; % dimensions for classical functions 50 | n2 = 30*ones(1,10); % dimensions for CEC 2014 functions 51 | fun_type = 1; % 1: using classical functions; 2: using CEC 2014 functions 52 | n = 30; % dimensionality 53 | functions = 19; % numbers of used test functions 54 | num_test = 3; % number of testing (repeating) 55 | N = 1000*n; % number of points per iteration 56 | M = 10; % number of iterations 57 | 58 | %% Algorithms 59 | algorithms = [ 60 | 1,... % Wingsuit Flying Search (WFS) 61 | 0,... % Genetic Algorithm (GA) 62 | 0,... % Particle Swarm Optimization (PSO) 63 | 0,... % Bat Algorithm (BA) 64 | 0,... % Grey Wolf Optimizer (GWO) 65 | 0,... % Butterfly Optimization Algorithm (BOA) 66 | 0,... % Whale Optimization Algorithm (WOA) 67 | 0,... % Moth Flame Optimization (MFO) 68 | 1,... % LSHADE 69 | 1,... % UMOEA 70 | ]; % 1 if used, 0 if not 71 | algorithms = ones(10,1); 72 | 73 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 74 | 75 | alg_names = { 76 | @WingsuitFlyingSearch 77 | @GeneticAlgorithm 78 | @ParticleSwarmOptimization 79 | @BatAlgorithm 80 | @GreyWolfOptimizer 81 | @ButterflyOptimizationAlgorithm 82 | @WhaleOptimizationAlgorithm 83 | @MothFlameOptimization 84 | @LSHADE 85 | @UMOEA 86 | }; 87 | global fun_num; 88 | 89 | for ii = 1:length(functions) 90 | num_alg = sum(algorithms); 91 | temp.algorithms = alg_names; 92 | temp.fun = functions(ii); 93 | if fun_type == 1 94 | temp.category = 'classical'; 95 | [f_real, constraints, fun] = SetParametres(functions(ii), n(ii)); 96 | disp(['Test function: ', func2str(fun)]); 97 | elseif fun_type == 2 98 | temp.category = 'CEC2014'; 99 | fun_num = functions(ii); 100 | f_real = 100*fun_num; 101 | constraints = 100*[-ones(n(ii),1), ones(n(ii),1)]; 102 | fun = @CEC2014_functions; 103 | disp(['Test function: ', func2str(fun), ' no. ', num2str(fun_num)]); 104 | end 105 | temp.n = n(ii); 106 | temp.mean_values = zeros(1,num_alg); 107 | temp.std = zeros(1,num_alg); 108 | temp.best_values = zeros(1,num_alg); 109 | temp.worst_values = zeros(1,num_alg); 110 | temp.mean_runtimes = zeros(1,num_alg); 111 | temp.values = zeros(num_test, num_alg); 112 | temp.all_values = zeros(M, num_test, num_alg); 113 | 114 | runtimes = zeros(num_test, num_alg); 115 | num_eval_fun_values = N*M; 116 | disp(['Dimensionality: ', num2str(n(ii))]); 117 | disp(' '); 118 | 119 | for i = 1:num_test 120 | disp(['Testing: ', num2str(i),' of ', num2str(num_test)]); 121 | f_val = zeros(num_alg, 1); 122 | x_best = zeros(num_alg, n(ii)); 123 | num = 1; 124 | for j = 1:length(algorithms) 125 | if algorithms(j) 126 | [x_best(num,:), temp.values(i,num), temp.all_values(:,i,num), runtimes(i,num)] = alg_names{j}(fun, n(ii), constraints, N(ii), M); 127 | temp.values(i,num) = temp.values(i,num)-f_real; 128 | if abs(temp.values(i,num)) < 1e-8 129 | temp.values(i,num) = 0; 130 | end 131 | num = num + 1; 132 | end 133 | end 134 | end 135 | 136 | for i=1:num_alg 137 | temp.mean_values(1,i) = 1/num_test*sum(temp.values(:,i)); 138 | temp.std(1,i) = sqrt(1/num_test*sum((temp.values(:,i)).^2)); 139 | temp.best_values(1,i) = min(temp.values(:,i)); 140 | temp.worst_values(1,i) = max(temp.values(:,i)); 141 | temp.mean_runtimes(1,i) = 1/num_test*sum(runtimes(:,i)); 142 | end 143 | 144 | format shortE; 145 | disp(' '); 146 | disp('Mean solution values: '); disp(temp.mean_values(1,:)); 147 | disp('Standard deviation of solution values: '); disp(temp.std(1,:)); 148 | disp('Best solution values: '); disp(temp.best_values(1,:)); 149 | disp('Worst solution values: '); disp(temp.worst_values(1,:)); 150 | disp('Mean runtimes: '); disp(temp.mean_runtimes(1,:)); 151 | disp('---------------------------------------------------------------------------------------------'); 152 | 153 | data{ii} = temp; 154 | save data2; 155 | end -------------------------------------------------------------------------------- /Algorithms/HarrisHawksOptimization.m: -------------------------------------------------------------------------------- 1 | % Developed in MATLAB R2013b 2 | % Source codes demo version 1.0 3 | % _____________________________________________________ 4 | % Main paper: 5 | % Harris hawks optimization: Algorithm and applications 6 | % Ali Asghar Heidari, Seyedali Mirjalili, Hossam Faris, Ibrahim Aljarah, Majdi Mafarja, Huiling Chen 7 | % Future Generation Computer Systems, 8 | % DOI: https://doi.org/10.1016/j.future.2019.02.028 9 | % https://www.sciencedirect.com/science/article/pii/S0167739X18313530 10 | % _____________________________________________________ 11 | % You can run the HHO code online at codeocean.com https://doi.org/10.24433/CO.1455672.v1 12 | % You can find the HHO code at https://github.com/aliasghar68/Harris-hawks-optimization-Algorithm-and-applications-.git 13 | % _____________________________________________________ 14 | % Author, inventor and programmer: Ali Asghar Heidari, 15 | % PhD research intern, Department of Computer Science, School of Computing, National University of Singapore, Singapore 16 | % Exceptionally Talented Ph. DC funded by Iran's National Elites Foundation (INEF), University of Tehran 17 | % 03-03-2019 18 | % Researchgate: https://www.researchgate.net/profile/Ali_Asghar_Heidari 19 | % e-Mail: as_heidari@ut.ac.ir, aliasghar68@gmail.com, 20 | % e-Mail (Singapore): aliasgha@comp.nus.edu.sg, t0917038@u.nus.edu 21 | % _____________________________________________________ 22 | % Co-author and Advisor: Seyedali Mirjalili 23 | % 24 | % e-Mail: ali.mirjalili@gmail.com 25 | % seyedali.mirjalili@griffithuni.edu.au 26 | % 27 | % Homepage: http://www.alimirjalili.com 28 | % _____________________________________________________ 29 | % Co-authors: Hossam Faris, Ibrahim Aljarah, Majdi Mafarja, and Hui-Ling Chen 30 | % Homepage: http://www.evo-ml.com/2019/03/02/hho/ 31 | % _____________________________________________________ 32 | %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 33 | % Harris's hawk optimizer: In this algorithm, Harris' hawks try to catch the rabbit. 34 | % T: maximum iterations, N: populatoin size, CNVG: Convergence curve 35 | % To run HHO: [Rabbit_Energy,Rabbit_Location,CNVG]=HHO(N,T,lb,ub,dim,fobj) 36 | function [Rabbit_Location, Rabbit_Energy, CNVG, runtime] = HarrisHawksOptimization(fobj, dim, bounds, N, T) 37 | 38 | tic 39 | % initialize the location and Energy of the rabbit 40 | Rabbit_Location=zeros(1,dim); 41 | Rabbit_Energy=inf; 42 | %Initialize the locations of Harris' hawks 43 | lb = bounds(1,1); 44 | ub = bounds(1,2); 45 | X=initialization(N,dim,ub,lb); 46 | CNVG=zeros(1,T); 47 | t=0; % Loop counter 48 | while tub;FL=X(i,:)=1 68 | %% Exploration: 69 | % Harris' hawks perch randomly based on 2 strategy: 70 | 71 | q=rand(); 72 | rand_Hawk_index = floor(N*rand()+1); 73 | X_rand = X(rand_Hawk_index, :); 74 | if q<0.5 75 | % perch based on other family members 76 | X(i,:)=X_rand-rand()*abs(X_rand-2*rand()*X(i,:)); 77 | elseif q>=0.5 78 | % perch on a random tall tree (random site inside group's home range) 79 | X(i,:)=(Rabbit_Location(1,:)-mean(X))-rand()*((ub-lb)*rand+lb); 80 | end 81 | 82 | elseif abs(Escaping_Energy)<1 83 | %% Exploitation: 84 | % Attacking the rabbit using 4 strategies regarding the behavior of the rabbit 85 | 86 | %% phase 1: surprise pounce (seven kills) 87 | % surprise pounce (seven kills): multiple, short rapid dives by different hawks 88 | 89 | r=rand(); % probablity of each event 90 | 91 | if r>=0.5 && abs(Escaping_Energy)<0.5 % Hard besiege 92 | X(i,:)=(Rabbit_Location)-Escaping_Energy*abs(Rabbit_Location-X(i,:)); 93 | end 94 | 95 | if r>=0.5 && abs(Escaping_Energy)>=0.5 % Soft besiege 96 | Jump_strength=2*(1-rand()); % random jump strength of the rabbit 97 | X(i,:)=(Rabbit_Location-X(i,:))-Escaping_Energy*abs(Jump_strength*Rabbit_Location-X(i,:)); 98 | end 99 | 100 | %% phase 2: performing team rapid dives (leapfrog movements) 101 | if r<0.5 && abs(Escaping_Energy)>=0.5, % Soft besiege % rabbit try to escape by many zigzag deceptive motions 102 | 103 | Jump_strength=2*(1-rand()); 104 | X1=Rabbit_Location-Escaping_Energy*abs(Jump_strength*Rabbit_Location-X(i,:)); 105 | 106 | if fobj(X1)1 164 | for i=1:dim 165 | high=up(i);low=down(i); 166 | X(:,i)=rand(1,N).*(high-low)+low; 167 | end 168 | end 169 | end -------------------------------------------------------------------------------- /Algorithms/LSHADE.m: -------------------------------------------------------------------------------- 1 | function [bsf_solution, bsf_fit_var, Convergence_curve, runtime] = LSHADE(fhd, problem_size, constraints, N, Max_iter) 2 | 3 | tic; 4 | max_nfes = N*Max_iter; 5 | rand('seed', sum(100 * clock)); 6 | val_2_reach = 0; 7 | min_region = constraints(1,1); 8 | max_region = constraints(1,2); 9 | lu = [min_region * ones(1, problem_size); max_region * ones(1, problem_size)]; 10 | 11 | for run_id = 1 : 1 12 | %% parameter settings for L-SHADE 13 | p_best_rate = 0.11; 14 | arc_rate = 1.4; 15 | memory_size = 5; 16 | pop_size = N; 17 | 18 | max_pop_size = pop_size; 19 | min_pop_size = 4.0; 20 | 21 | %% Initialize the main population 22 | popold = repmat(lu(1, :), pop_size, 1) + rand(pop_size, problem_size) .* (repmat(lu(2, :) - lu(1, :), pop_size, 1)); 23 | pop = popold; % the old population becomes the current population 24 | 25 | fitness = zeros(pop_size, 1); 26 | for ii = 1:pop_size 27 | fitness(ii) = feval(fhd, pop(ii,:)); 28 | end 29 | 30 | nfes = 0; 31 | bsf_fit_var = 1e+30; 32 | bsf_solution = zeros(1, problem_size); 33 | 34 | %%%%%%%%%%%%%%%%%%%%%%%% for out 35 | for i = 1 : pop_size 36 | nfes = nfes + 1; 37 | 38 | if fitness(i) < bsf_fit_var 39 | bsf_fit_var = fitness(i); 40 | bsf_solution = pop(i, :); 41 | end 42 | Convergence_curve = bsf_fit_var; 43 | 44 | %% if mod(nfes, 1000) == 0 45 | %% bsf_error_var = bsf_fit_var - optimum; 46 | %% if bsf_error_var < val_2_reach; bsf_error_var = 0; end; 47 | %% fprintf(sprintf('%1.16e \n', bsf_error_var)); 48 | %% fprintf(sprintf('%d %1.16e \n', nfes, bsf_error_var)); 49 | %% end 50 | 51 | %% if nfes > max_nfes; exit(1); end 52 | if nfes > max_nfes; break; end 53 | end 54 | %%%%%%%%%%%%%%%%%%%%%%%% for out 55 | 56 | memory_sf = 0.5 .* ones(memory_size, 1); 57 | memory_cr = 0.5 .* ones(memory_size, 1); 58 | memory_pos = 1; 59 | 60 | archive.NP = arc_rate * pop_size; % the maximum size of the archive 61 | archive.pop = zeros(0, problem_size); % the solutions stored in te archive 62 | archive.funvalues = zeros(0, 1); % the function value of the archived solutions 63 | 64 | %% main loop 65 | while nfes < max_nfes 66 | pop = popold; % the old population becomes the current population 67 | [temp_fit, sorted_index] = sort(fitness, 'ascend'); 68 | 69 | mem_rand_index = ceil(memory_size * rand(pop_size, 1)); 70 | mu_sf = memory_sf(mem_rand_index); 71 | mu_cr = memory_cr(mem_rand_index); 72 | 73 | %% for generating crossover rate 74 | cr = normrnd(mu_cr, 0.1); 75 | term_pos = find(mu_cr == -1); 76 | cr(term_pos) = 0; 77 | cr = min(cr, 1); 78 | cr = max(cr, 0); 79 | 80 | %% for generating scaling factor 81 | sf = mu_sf + 0.1 * tan(pi * (rand(pop_size, 1) - 0.5)); 82 | pos = find(sf <= 0); 83 | 84 | while ~ isempty(pos) 85 | sf(pos) = mu_sf(pos) + 0.1 * tan(pi * (rand(length(pos), 1) - 0.5)); 86 | pos = find(sf <= 0); 87 | end 88 | 89 | sf = min(sf, 1); 90 | 91 | r0 = [1 : pop_size]; 92 | popAll = [pop; archive.pop]; 93 | [r1, r2] = gnR1R2(pop_size, size(popAll, 1), r0); 94 | 95 | pNP = max(round(p_best_rate * pop_size), 2); %% choose at least two best solutions 96 | randindex = ceil(rand(1, pop_size) .* pNP); %% select from [1, 2, 3, ..., pNP] 97 | randindex = max(1, randindex); %% to avoid the problem that rand = 0 and thus ceil(rand) = 0 98 | pbest = pop(sorted_index(randindex), :); %% randomly choose one of the top 100p% solutions 99 | 100 | vi = pop + sf(:, ones(1, problem_size)) .* (pbest - pop + pop(r1, :) - popAll(r2, :)); 101 | vi = boundConstraint(vi, pop, lu); 102 | 103 | mask = rand(pop_size, problem_size) > cr(:, ones(1, problem_size)); % mask is used to indicate which elements of ui comes from the parent 104 | rows = (1 : pop_size)'; cols = floor(rand(pop_size, 1) * problem_size)+1; % choose one position where the element of ui doesn't come from the parent 105 | jrand = sub2ind([pop_size problem_size], rows, cols); mask(jrand) = false; 106 | ui = vi; ui(mask) = pop(mask); 107 | children_fitness = zeros(pop_size, 1); 108 | for ii = 1:pop_size 109 | children_fitness(ii) = feval(fhd, ui(ii,:)); 110 | end 111 | 112 | %%%%%%%%%%%%%%%%%%%%%%%% for out 113 | for i = 1 : pop_size 114 | nfes = nfes + 1; 115 | 116 | if children_fitness(i) < bsf_fit_var 117 | bsf_fit_var = children_fitness(i); 118 | bsf_solution = ui(i, :); 119 | end 120 | 121 | %% if mod(nfes, 1000) == 0 122 | %% bsf_error_var = bsf_fit_var - optimum; 123 | %% if bsf_error_var < val_2_reach; bsf_error_var = 0; end; 124 | %% fprintf(sprintf('%1.16e \n', bsf_error_var)); 125 | %% fprintf(sprintf('%d %1.16e \n', nfes, bsf_error_var)); 126 | %%end 127 | 128 | %% if nfes > max_nfes; exit(1); end 129 | if nfes > max_nfes; break; end 130 | end 131 | %%%%%%%%%%%%%%%%%%%%%%%% for out 132 | 133 | dif = abs(fitness - children_fitness); 134 | 135 | 136 | %% I == 1: the parent is better; I == 2: the offspring is better 137 | I = (fitness > children_fitness); 138 | goodCR = cr(I == 1); 139 | goodF = sf(I == 1); 140 | dif_val = dif(I == 1); 141 | 142 | % isempty(popold(I == 1, :)) 143 | archive = updateArchive(archive, popold(I == 1, :), fitness(I == 1)); 144 | 145 | [fitness, I] = min([fitness, children_fitness], [], 2); 146 | 147 | popold = pop; 148 | popold(I == 2, :) = ui(I == 2, :); 149 | 150 | num_success_params = numel(goodCR); 151 | 152 | if num_success_params > 0 153 | sum_dif = sum(dif_val); 154 | dif_val = dif_val / sum_dif; 155 | 156 | %% for updating the memory of scaling factor 157 | memory_sf(memory_pos) = (dif_val' * (goodF .^ 2)) / (dif_val' * goodF); 158 | 159 | %% for updating the memory of crossover rate 160 | if max(goodCR) == 0 || memory_cr(memory_pos) == -1 161 | memory_cr(memory_pos) = -1; 162 | else 163 | memory_cr(memory_pos) = (dif_val' * (goodCR .^ 2)) / (dif_val' * goodCR); 164 | end 165 | 166 | memory_pos = memory_pos + 1; 167 | if memory_pos > memory_size; memory_pos = 1; end 168 | end 169 | 170 | %% for resizing the population size 171 | plan_pop_size = round((((min_pop_size - max_pop_size) / max_nfes) * nfes) + max_pop_size); 172 | 173 | if pop_size > plan_pop_size 174 | reduction_ind_num = pop_size - plan_pop_size; 175 | if pop_size - reduction_ind_num < min_pop_size; reduction_ind_num = pop_size - min_pop_size;end 176 | 177 | pop_size = pop_size - reduction_ind_num; 178 | for r = 1 : reduction_ind_num 179 | [valBest indBest] = sort(fitness, 'ascend'); 180 | worst_ind = indBest(end); 181 | popold(worst_ind,:) = []; 182 | pop(worst_ind,:) = []; 183 | fitness(worst_ind,:) = []; 184 | end 185 | 186 | archive.NP = round(arc_rate * pop_size); 187 | 188 | if size(archive.pop, 1) > archive.NP 189 | rndpos = randperm(size(archive.pop, 1)); 190 | rndpos = rndpos(1 : archive.NP); 191 | archive.pop = archive.pop(rndpos, :); 192 | end 193 | end 194 | 195 | Convergence_curve = [Convergence_curve, bsf_fit_var]; 196 | end 197 | 198 | end 199 | L = length(Convergence_curve); 200 | ind = round((1:Max_iter)*L/Max_iter); 201 | Convergence_curve = Convergence_curve(ind); 202 | runtime = toc; 203 | 204 | end 205 | 206 | 207 | function archive = updateArchive(archive, pop, funvalue) 208 | % Update the archive with input solutions 209 | % Step 1: Add new solution to the archive 210 | % Step 2: Remove duplicate elements 211 | % Step 3: If necessary, randomly remove some solutions to maintain the archive size 212 | % 213 | % Version: 1.1 Date: 2008/04/02 214 | % Written by Jingqiao Zhang (jingqiao@gmail.com) 215 | 216 | if archive.NP == 0, return; end 217 | 218 | % Method 2: Remove duplicate elements 219 | popAll = [archive.pop; pop ]; 220 | funvalues = [archive.funvalues; funvalue ]; 221 | [dummy IX]= unique(popAll, 'rows'); 222 | if length(IX) < size(popAll, 1) % There exist some duplicate solutions 223 | popAll = popAll(IX, :); 224 | funvalues = funvalues(IX, :); 225 | end 226 | 227 | if size(popAll, 1) <= archive.NP % add all new individuals 228 | archive.pop = popAll; 229 | archive.funvalues = funvalues; 230 | else % randomly remove some solutions 231 | rndpos = randperm(size(popAll, 1)); % equivelent to "randperm"; 232 | rndpos = rndpos(1 : archive.NP); 233 | 234 | archive.pop = popAll (rndpos, :); 235 | archive.funvalues = funvalues(rndpos, :); 236 | end 237 | end 238 | 239 | 240 | function [r1, r2] = gnR1R2(NP1, NP2, r0) 241 | 242 | % gnA1A2 generate two column vectors r1 and r2 of size NP1 & NP2, respectively 243 | % r1's elements are choosen from {1, 2, ..., NP1} & r1(i) ~= r0(i) 244 | % r2's elements are choosen from {1, 2, ..., NP2} & r2(i) ~= r1(i) & r2(i) ~= r0(i) 245 | % 246 | % Call: 247 | % [r1 r2 ...] = gnA1A2(NP1) % r0 is set to be (1:NP1)' 248 | % [r1 r2 ...] = gnA1A2(NP1, r0) % r0 should be of length NP1 249 | % 250 | % Version: 2.1 Date: 2008/07/01 251 | % Written by Jingqiao Zhang (jingqiao@gmail.com) 252 | 253 | NP0 = length(r0); 254 | 255 | r1 = floor(rand(1, NP0) * NP1) + 1; 256 | %for i = 1 : inf 257 | for i = 1 : 99999999 258 | pos = (r1 == r0); 259 | if sum(pos) == 0 260 | break; 261 | else % regenerate r1 if it is equal to r0 262 | r1(pos) = floor(rand(1, sum(pos)) * NP1) + 1; 263 | end 264 | if i > 1000 % this has never happened so far 265 | error('Can not genrate r1 in 1000 iterations'); 266 | end 267 | end 268 | 269 | r2 = floor(rand(1, NP0) * NP2) + 1; 270 | %for i = 1 : inf 271 | for i = 1 : 99999999 272 | pos = ((r2 == r1) | (r2 == r0)); 273 | if sum(pos)==0 274 | break; 275 | else % regenerate r2 if it is equal to r0 or r1 276 | r2(pos) = floor(rand(1, sum(pos)) * NP2) + 1; 277 | end 278 | if i > 1000 % this has never happened so far 279 | error('Can not genrate r2 in 1000 iterations'); 280 | end 281 | end 282 | end 283 | 284 | 285 | function vi = boundConstraint (vi, pop, lu) 286 | 287 | % if the boundary constraint is violated, set the value to be the middle 288 | % of the previous value and the bound 289 | % 290 | % Version: 1.1 Date: 11/20/2007 291 | % Written by Jingqiao Zhang, jingqiao@gmail.com 292 | 293 | [NP, D] = size(pop); % the population size and the problem's dimension 294 | 295 | %% check the lower bound 296 | xl = repmat(lu(1, :), NP, 1); 297 | pos = vi < xl; 298 | vi(pos) = (pop(pos) + xl(pos)) / 2; 299 | 300 | %% check the upper bound 301 | xu = repmat(lu(2, :), NP, 1); 302 | pos = vi > xu; 303 | vi(pos) = (pop(pos) + xu(pos)) / 2; 304 | end -------------------------------------------------------------------------------- /Algorithms/WingsuitFlyingSearch.m: -------------------------------------------------------------------------------- 1 | function [x_min_m, f_min_m, f_vals, runtime] = WingsuitFlyingSearch(fun, n, bounds, N, M) 2 | % -------------------------------------------------------------------------- 3 | % Wingsuit Flying Search algorithm 4 | % Inputs: 5 | % 'fun' - function needs to be minimized 6 | % 'n' - dimensionality of the search space 7 | % 'bounds' - bounds of the search space 8 | % 'N' - total number of points at each iteration 9 | % 'M' - total number of the algorithm iterations 10 | % Outputs: 11 | % 'x_min_m' - best solution 12 | % 'f_min_m' - best solution value 13 | % 'f_vals' - best solutions from each iteration (convergence curve) 14 | % 'runtime' - total runtime of the algorithm 15 | % -------------------------------------------------------------------------- 16 | 17 | % -------------------------------------------------------------------------- 18 | % Wingsuit Flying Search Settings 19 | v = 90*rand+10; % flier's velocity (random between 10 and 100) 20 | delta_x_min = zeros(1,n); % minimal discretization step 21 | plot_res = 0; % plot results 22 | % -------------------------------------------------------------------------- 23 | 24 | tic; 25 | num_x = 1; % aux. variable for plotting 26 | N = N - 2; % number of considered points (two more are added in the end of each iteration) 27 | 28 | N0 = ceil((N)^(1/n)); % number of points in regular grid per one dimension 29 | step = zeros(1, n); % initial discretization step 30 | for i = 1:n 31 | step(i) = (bounds(i,2)-bounds(i,1))/N0; 32 | end 33 | 34 | % Generating initial Halton points 35 | halton_set = haltonset(n, 'Skip', 0, 'Leap', 0); 36 | halton_set = scramble(halton_set, 'RR2'); 37 | x_temp = ceil(rand*1e6); 38 | x = halton_set(x_temp:x_temp+N-1, :); 39 | for i = 1:n 40 | x(:,i) = x(:,i).*(bounds(i,2)-bounds(i,1))+bounds(i,1); 41 | end 42 | 43 | f = GetValues(x, n, bounds, fun); % values of the initial points 44 | m = 1; % number of current iteration number 45 | f_max = max(f); % maximal found value 46 | a_m = f_max; % flier's altitude 47 | 48 | [f_min_m, index] = min(f); % current solution value 49 | x_min_m = x(index,:); % current solution 50 | 51 | % Generating centroid and random point and updating current solution if necessary 52 | [x_centr, x_rand] = GenerateCRP(x, n, f, f_min_m, a_m); 53 | f_temp = GetValues([x_centr; x_rand], n, bounds, fun); 54 | x = [x; x_centr; x_rand]; 55 | f = [f; f_temp]; 56 | [x_min_m, f_min_m] = UpdateMin(x(N+1:N+2,:), f(N+1:N+2), x_min_m, f_min_m); 57 | f_vals(m) = f_min_m; 58 | 59 | % Plotting results 60 | if plot_res 61 | num_x = PlotRes(x, f, n, num_x, bounds, f_min_m); 62 | end 63 | 64 | % Another format of discretization step 65 | delta_x1 = zeros(3, n); 66 | delta_x1(1,:) = step; 67 | delta_x1(2,:) = zeros(1,n); 68 | delta_x1(3,:) = -step; 69 | 70 | SC = CheckSC(delta_x1, delta_x_min, m, M); % checking stopping condition 71 | %% 72 | while(SC == false) 73 | m = m+1; 74 | alpha_m = 1-v^(-(m-1)/(M-1)); % search sharpness 75 | P_max_m = ceil(alpha_m*N); % maximal number of neighborhood points 76 | N_m = ceil(2*N/P_max_m); % number of considered points 77 | if N_m > length(f) 78 | N_m = length(f); 79 | end 80 | delta_x_m = (1-alpha_m)*delta_x1; % discretization step 81 | 82 | % Sorting points in ascending order w.r.t. their solution values 83 | for i = 1:N_m 84 | for j = i+1:length(f) 85 | if f(j) 0 112 | P_m(i) = N_m-S; 113 | end 114 | 115 | % Generating new points 116 | x_size = size(x,1); 117 | for i = 1:length(f) 118 | if P_m(i)>0 119 | direction = x_min_m-x(i,:); 120 | row = zeros(n, 2); 121 | for j = 1:n 122 | if direction(j)>0 123 | direction(j) = 1; 124 | row(j,:) = [1,2]; 125 | elseif direction(j)<0 126 | direction(j) = -1; 127 | row(j,:) = [2,3]; 128 | else 129 | row(j,:) = [1,3]; 130 | end 131 | end 132 | x_selected = zeros(P_m(i), n); 133 | x_temp = ceil(rand*1e6); 134 | neighborhood = halton_set(x_temp:x_temp+P_m(i)-1, :); 135 | for j = 1:n 136 | x_selected(:,j) = (2*neighborhood(:,j)-1+direction(j))*delta_x_m(1,j)+... 137 | x(i,j)*ones(P_m(i),1); 138 | end 139 | x = [x; x_selected]; 140 | end 141 | end 142 | 143 | f_temp = GetValues(x(x_size+1:size(x,1),:), n, bounds, fun); % new points values 144 | f = [f; f_temp]; % all values: old and new 145 | 146 | [f_min_m, index] = min(f); % new solution value 147 | x_min_m = x(index, :); % new solution 148 | 149 | % Generating centroid and random point and updating current solution if necessary 150 | [x_centr, x_rand] = GenerateCRP(x, n, f, f_min_m, a_m); 151 | f_temp = GetValues([x_centr; x_rand], n, bounds, fun); 152 | x = [x; x_centr; x_rand]; 153 | f = [f; f_temp]; 154 | [x_min_m, f_min_m] = UpdateMin(x(N+1:N+2,:), f(N+1:N+2), x_min_m, f_min_m); 155 | f_vals(m) = f_min_m; 156 | 157 | % Plotting results 158 | if plot_res 159 | num_x = PlotRes(x, f, n, num_x, bounds, f_min_m); 160 | end 161 | 162 | SC = CheckSC(delta_x_m, delta_x_min, m, M); % checking stopping condition 163 | end 164 | runtime = toc; 165 | end 166 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 167 | %% 168 | % Get values 'f' for 'n'-dim. points 'x' of function 'fun' with constraints 'constraints' of serach space 169 | function f = GetValues(x, n, constraints, fun) 170 | f = zeros(size(x,1),1); 171 | for i = 1:size(x,1) 172 | for j = 1:n 173 | if x(i,j) <= constraints(j,1) 174 | x(i,j) = 2*constraints(j,1) - x(i,j); 175 | elseif x(i,j) >= constraints(j,2) 176 | x(i,j) = 2*constraints(j,2) - x(i,j); 177 | end 178 | end 179 | f(i) = fun(x(i,:)); 180 | end 181 | end 182 | 183 | % Update minimum 'x_min_m' and its value 'f_min_m' considering points 'x' and its values 'f' 184 | function [x_min_m, f_min_m] = UpdateMin(x, f, x_min_m, f_min_m) 185 | for i = 1:length(f) 186 | if f(i) < f_min_m 187 | f_min_m = f(i); 188 | x_min_m = x(i,:); 189 | break; 190 | end 191 | end 192 | end 193 | 194 | % Generate centroid 'x_centr' and random point 'x_rand' from 'n'-dim. 195 | % points 'x', its values 'f', current solution value 'f_min_m', and current 196 | % flier's attitude 'a_m' 197 | function [x_centr, x_rand] = GenerateCRP(x, n, f, f_min_m, a_m) 198 | gama = 1-(f-f_min_m)/(a_m-f_min_m); 199 | gama = (gama > 0).*gama; 200 | x_centr = zeros(1,n); 201 | current_constr = zeros(n,2); 202 | for i = 1:n 203 | x_centr(i) = (x(:,i))'*gama/sum(gama); 204 | current_constr(i,:) = [min(x(:,i)); max(x(:,i))]; 205 | end 206 | x_rand = ((current_constr(:,2)-current_constr(:,1)).*rand(n,1)+current_constr(:,1))'; 207 | end 208 | 209 | % Check stopping condition 'SC' comparing current discretization step 210 | % 'delta_x_m' with its minimal 'delta_x_min', and current iteration number 211 | % 'm' with total ones 'M' 212 | function SC = CheckSC(delta_x_m, delta_x_min, m, M) 213 | SC = false; 214 | for i = 1:length(delta_x_min) 215 | if abs(delta_x_m(1,i)) < delta_x_min(i) 216 | SC = true; 217 | disp('Discretization step is less than minimal. Algorithm terminated.'); 218 | break; 219 | end 220 | end 221 | if m == M 222 | SC = true; 223 | %disp('*********** algorithm terminated ***********'); disp(' '); 224 | end 225 | end 226 | 227 | % Plot results using 'n'-dim. points 'x', its values 'f', current 228 | % considered point number 'num_x', constraints of search space 229 | % 'constraints', and current solution value 'f_min_m' 230 | function num_x = PlotRes(x, f, n, num_x, constraints, f_min_m) 231 | global x_real; 232 | for i = 1:length(f) 233 | if i < length(f)-3 234 | color = 'b'; 235 | marker_size = 5; 236 | elseif i == length(f)-3 237 | color = 'r'; 238 | marker_size = 20; 239 | elseif i == length(f)-2 240 | color = 'g'; 241 | marker_size = 20; 242 | elseif i == length(f)-1 243 | color = 'm'; 244 | marker_size = 20; 245 | else 246 | color = 'k'; 247 | marker_size = 20; 248 | end 249 | if f(i) < 1e10 250 | if mod(n,2)==0 251 | n_temp = n; 252 | else 253 | n_temp = n-3; 254 | end 255 | for k = 1:2:n_temp 256 | figure((k+1)/2); 257 | if mod(num_x, 500) == 1 258 | for ii = 1:size(x_real,1) 259 | plot(x_real(ii,k), x_real(ii,k+1), 'green x', 'MarkerSize', 20); hold on; 260 | end 261 | xlabel(strjoin({'$x_{', num2str(k),'}$'})); 262 | ylabel(strjoin({'$x_{', num2str(k+1),'}$'})); 263 | axis([constraints(k,:), constraints(k+1,:)]); 264 | grid on; 265 | end 266 | plot(x(i,k), x(i,k+1), [color, '.'], 'MarkerSize', marker_size); 267 | hold on; 268 | drawnow; 269 | end 270 | if n > n_temp 271 | figure(n_temp+1); 272 | if mod(num_x, 50) == 1 273 | for ii = 1:size(x_real,1) 274 | plot3(x_real(ii,n_temp+1), x_real(ii,n_temp+2), x_real(ii,n_temp+3), ... 275 | 'green x', 'MarkerSize', 20); hold on; 276 | end 277 | xlabel(strjoin({'$x_{', num2str(n_temp+1),'}$'})); 278 | ylabel(strjoin({'$x_{', num2str(n_temp+2),'}$'})); 279 | zlabel(strjoin({'$x_{', num2str(n_temp+3),'}$'})); 280 | axis([constraints(n_temp+1,:), constraints(n_temp+2,:), constraints(n_temp+3,:)]); 281 | grid on; 282 | end 283 | plot3(x(i,n_temp+1), x(i,n_temp+2), x(i,n_temp+3), [color, '.'], 'MarkerSize', marker_size); 284 | hold on; 285 | drawnow; 286 | end 287 | figure(n_temp+2) 288 | plot(num_x, f(i),'r.'); 289 | xlabel('Point ordinal number'); 290 | ylabel('Function value'); 291 | axis([0, num_x, f_min_m, f_min_m+10*abs(f_min_m)]); 292 | grid on; hold on; 293 | drawnow; 294 | end 295 | num_x = num_x+1; 296 | end 297 | end -------------------------------------------------------------------------------- /Algorithms/MonarchButterflyOptimization.m: -------------------------------------------------------------------------------- 1 | 2 | %% Monarch Butterfly Optimization (MBO) 3 | % Author: Gai-Ge Wang 4 | % Email: gaigewang@163.com 5 | % gaigewang@gmail.com 6 | % Main paper: 7 | % Gai-Ge Wang, Suash Deb, and Zhihua Cui, Monarch Butterfly Optimization. 8 | % Neural Computing and Applications, in press. 9 | % DOI: 10.1007/s00521-015-1923-y 10 | % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %% 11 | %% Notes: 12 | % Different run may generate different solutions, this is determined by 13 | % the the nature of metaheuristic algorithms. 14 | %% 15 | function [x_best, f_best, MinCost, runtime] = MonarchButterflyOptimization(costFun, numVar, bounds, popsize, Maxgen) 16 | % Monarch Butterfly Optimization (MBO) software for minimizing a general function 17 | % The fixed Function Evaluations (FEs) is considered as termination condition. 18 | % INPUTS: ProblemFunction is the handle of the function that returns 19 | % the handles of the initialization, cost, and feasibility functions. 20 | % DisplayFlag = true or false, whether or not to display and plot results. 21 | % ProbFlag = true or false, whether or not to use probabilities to update emigration rates. 22 | % RandSeed = random number seed 23 | % OUTPUTS: MinCost = array of best solution, one element for each generation 24 | % Hamming = final Hamming distance between solutions 25 | % CAVEAT: The "ClearDups" function that is called below replaces duplicates with randomly-generated 26 | % individuals, but it does not then recalculate the cost of the replaced individuals. 27 | tic 28 | DisplayFlag = false; 29 | RandSeed = round(sum(100*clock)); 30 | 31 | [OPTIONS, MinCost, AvgCost, InitFunction, CostFunction, FeasibleFunction, ... 32 | MaxParValue, MinParValue, Population] = Init(DisplayFlag, @FUN, RandSeed, costFun, numVar, bounds, popsize, Maxgen); 33 | nEvaluations = OPTIONS.popsize; 34 | % % % % % % % % % % % % Initial parameter setting % % % % % % % % % % % %%%% 35 | %% Initial parameter setting 36 | Keep = 2; % elitism parameter: how many of the best habitats to keep from one generation to the next 37 | maxStepSize = 1.0; %Max Step size 38 | partition = OPTIONS.partition; 39 | numButterfly1 = ceil(partition*OPTIONS.popsize); % NP1 in paper 40 | numButterfly2 = OPTIONS.popsize - numButterfly1; % NP2 in paper 41 | period = 1.2; % 12 months in a year 42 | Land1 = zeros(numButterfly1, OPTIONS.numVar); 43 | Land2 = zeros(numButterfly2, OPTIONS.numVar); 44 | BAR = partition; % you can change the BAR value in order to get much better performance 45 | % % % % % % % % % % % % End of Initial parameter setting % % % % % % % % % % % %% 46 | %% 47 | % % % % % % % % % % % % Begin the optimization loop % % % % % % % % % %%%% 48 | % Begin the optimization loop 49 | GenIndex = 1; 50 | % for GenIndex = 1 : OPTIONS.Maxgen 51 | while nEvaluations< OPTIONS.MaxFEs 52 | % % % % % % % % % % % % Elitism Strategy % % % % % % % % % % % %%%%% 53 | %% Save the best monarch butterflis in a temporary array. 54 | for j = 1 : Keep 55 | chromKeep(j,:) = Population(j).chrom; 56 | costKeep(j) = Population(j).cost; 57 | end 58 | % % % % % % % % % % % % End of Elitism Strategy % % % % % % % % % % % %%%% 59 | %% 60 | 61 | % % % % % % % % % % % % Divide the whole population into two subpopulations % % % %%% 62 | %% Divide the whole population into Population1 (Land1) and Population2 (Land2) 63 | % according to their fitness. 64 | % The monarch butterflis in Population1 are better than or equal to Population2. 65 | % Of course, we can randomly divide the whole population into Population1 and Population2. 66 | % We do not test the different performance between two ways. 67 | for popindex = 1 : OPTIONS.popsize 68 | if popindex <= numButterfly1 69 | Population1(popindex).chrom = Population(popindex).chrom; 70 | else 71 | Population2(popindex-numButterfly1).chrom = Population(popindex).chrom; 72 | end 73 | end 74 | % % % % % % % % % % % End of Divide the whole population into two subpopulations % % %%% 75 | %% 76 | 77 | % % % % % % % % % % % %% Migration operator % % % % % % % % % % % %%%% 78 | %% Migration operator 79 | for k1 = 1 : numButterfly1 80 | for parnum1 = 1 : OPTIONS.numVar 81 | r1 = rand*period; 82 | if r1 <= partition 83 | r2 = round(numButterfly1 * rand + 0.5); 84 | Land1(k1,parnum1) = Population1(r2).chrom(parnum1); 85 | else 86 | r3 = round(numButterfly2 * rand + 0.5); 87 | Land1(k1,parnum1) = Population2(r3).chrom(parnum1); 88 | end 89 | end %% for parnum1 90 | NewPopulation1(k1).chrom = Land1(k1,:); 91 | end %% for k1 92 | % % % % % % % % % % % %%% End of Migration operator % % % % % % % % % % % %%% 93 | %% 94 | 95 | % % % % % % % % % % % % Evaluate NewPopulation1 % % % % % % % % % % % %% 96 | %% Evaluate NewPopulation1 97 | SavePopSize = OPTIONS.popsize; 98 | OPTIONS.popsize = numButterfly1; 99 | % Make sure each individual is legal. 100 | NewPopulation1 = FeasibleFunction(OPTIONS, NewPopulation1); 101 | % Calculate cost 102 | NewPopulation1 = CostFunction(OPTIONS, NewPopulation1, costFun); 103 | % the number of fitness evaluations 104 | nEvaluations = nEvaluations + OPTIONS.popsize; 105 | OPTIONS.popsize = SavePopSize; 106 | % % % % % % % % % % % % End of Evaluate NewPopulation1 % % % % % % % % % % % %% 107 | %% 108 | 109 | % % % % % % % % % % % % Butterfly adjusting operator % % % % % % % % % % % %% 110 | %% Butterfly adjusting operator 111 | for k2 = 1 : numButterfly2 112 | scale = maxStepSize/(GenIndex^2); %Smaller step for local walk 113 | StepSzie = ceil(exprnd(2*OPTIONS.Maxgen,1,1)); 114 | delataX = LevyFlight(StepSzie,OPTIONS.numVar); 115 | for parnum2 = 1:OPTIONS.numVar, 116 | if (rand >= partition) 117 | Land2(k2,parnum2) = Population(1).chrom(parnum2); 118 | else 119 | r4 = round(numButterfly2*rand + 0.5); 120 | Land2(k2,parnum2) = Population2(r4).chrom(1); 121 | if (rand > BAR) % Butterfly-Adjusting rate 122 | Land2(k2,parnum2) = Land2(k2,parnum2) + scale*(delataX(parnum2)-0.5); 123 | end 124 | end 125 | end %% for parnum2 126 | NewPopulation2(k2).chrom = Land2(k2,:); 127 | end %% for k2 128 | % % % % % % % % % % % % End of Butterfly adjusting operator % % % % % % % % % % % % 129 | %% 130 | 131 | % % % % % % % % % % % % Evaluate NewPopulation2 % % % % % % % % % % % %% 132 | %% Evaluate NewPopulation2 133 | SavePopSize = OPTIONS.popsize; 134 | OPTIONS.popsize = numButterfly2; 135 | % Make sure each individual is legal. 136 | NewPopulation2 = FeasibleFunction(OPTIONS, NewPopulation2); 137 | % Calculate cost 138 | NewPopulation2 = CostFunction(OPTIONS, NewPopulation2, costFun); 139 | % the number of fitness evaluations 140 | nEvaluations = nEvaluations + OPTIONS.popsize; 141 | OPTIONS.popsize = SavePopSize; 142 | % % % % % % % % % % % % End of Evaluate NewPopulation2 % % % % % % % % % % % %% 143 | %% 144 | 145 | % % % % % % % Combine two subpopulations into one and rank monarch butterflis % % % % % % 146 | %% Combine Population1 with Population2 to generate a new Population 147 | Population = CombinePopulation(OPTIONS, NewPopulation1, NewPopulation2); 148 | % Sort from best to worst 149 | Population = PopSort(Population); 150 | % % % % % % End of Combine two subpopulations into one and rank monarch butterflis % %% % % 151 | %% 152 | 153 | % % % % % % % % % % % % Elitism Strategy % % % % % % % % % % % %%% %% % 154 | %% Replace the worst with the previous generation's elites. 155 | n = length(Population); 156 | for k3 = 1 : Keep 157 | Population(n-k3+1).chrom = chromKeep(k3,:); 158 | Population(n-k3+1).cost = costKeep(k3); 159 | end % end for k3 160 | % % % % % % % % % % % % End of Elitism Strategy % % % % % % % % % % % %%% %% % 161 | %% 162 | 163 | % % % % % % % % % % Precess and output the results % % % % % % % % % % % %%% 164 | % Sort from best to worst 165 | Population = PopSort(Population); 166 | % Compute the average cost 167 | [AverageCost, nLegal] = ComputeAveCost(Population); 168 | % Display info to screen 169 | MinCost = [MinCost Population(1).cost]; 170 | AvgCost = [AvgCost AverageCost]; 171 | if DisplayFlag 172 | disp(['The best and mean of Generation # ', num2str(GenIndex), ' are ',... 173 | num2str(MinCost(end)), ' and ', num2str(AvgCost(end))]); 174 | end 175 | % % % % % % % % % % % End of Precess and output the results %%%%%%%%%% %% % 176 | %% 177 | 178 | %% Update generation number 179 | GenIndex = GenIndex+1; 180 | 181 | end % end for GenIndex 182 | f_best = min(MinCost); 183 | x_best = Population(1).chrom; 184 | runtime = toc; 185 | % % % % % % % % % % End of Monarch Butterfly Optimization implementation %%%% %% % 186 | %% 187 | function [delataX] = LevyFlight(StepSize, Dim) 188 | %Allocate matrix for solutions 189 | delataX = zeros(1,Dim); 190 | %Loop over each dimension 191 | for i=1:Dim 192 | % Cauchy distribution 193 | fx = tan(pi * rand(1,StepSize)); 194 | delataX(i) = sum(fx); 195 | end 196 | 197 | 198 | 199 | function [Population, indices] = PopSort(Population) 200 | % Sort the population members from best to worst 201 | popsize = length(Population); 202 | Cost = zeros(1, popsize); 203 | indices = zeros(1, popsize); 204 | for i = 1 : popsize 205 | Cost(i) = Population(i).cost; 206 | end 207 | [Cost, indices] = sort(Cost, 2, 'ascend'); 208 | Chroms = zeros(popsize, length(Population(1).chrom)); 209 | for i = 1 : popsize 210 | Chroms(i, :) = Population(indices(i)).chrom; 211 | end 212 | for i = 1 : popsize 213 | Population(i).chrom = Chroms(i, :); 214 | Population(i).cost = Cost(i); 215 | end 216 | 217 | 218 | 219 | function [OPTIONS, MinCost, AvgCost, InitFunction, CostFunction, FeasibleFunction, ... 220 | MaxParValue, MinParValue, Population] = Init(DisplayFlag, ProblemFunction, RandSeed, costFun, numVar, constraints, popsize, Maxgen) 221 | % Initialize population-based optimization software. 222 | % WARNING: some of the optimization routines will not work if population size is odd. 223 | OPTIONS.popsize = popsize; % total population size 224 | OPTIONS.Maxgen = Maxgen; % generation count limit 225 | OPTIONS.numVar = numVar; % number of variables in each population member 226 | OPTIONS.MaxFEs = popsize*Maxgen; % number of Function Evaluations (FEs) 227 | OPTIONS.partition = 5/12; % the percentage of population for MBO 228 | if ~exist('RandSeed', 'var') 229 | RandSeed = round(sum(100*clock)); 230 | end 231 | rand('state', RandSeed); % initialize random number generator 232 | if DisplayFlag 233 | disp(['random # seed = ', num2str(RandSeed)]); 234 | end 235 | % Get the addresses of the initialization, cost, and feasibility functions. 236 | [InitFunction, CostFunction, FeasibleFunction] = ProblemFunction(); 237 | % Initialize the population. 238 | [MaxParValue, MinParValue, Population, OPTIONS] = InitFunction(OPTIONS, constraints); 239 | % Make sure the population does not have duplicates. 240 | Population = ClearDups(Population, MaxParValue, MinParValue); 241 | % Compute cost of each individual 242 | Population = CostFunction(OPTIONS, Population, costFun); 243 | % Sort the population from most fit to least fit 244 | Population = PopSort(Population); 245 | % Compute the average cost 246 | AverageCost = ComputeAveCost(Population); 247 | % Display info to screen 248 | MinCost = [Population(1).cost]; 249 | AvgCost = [AverageCost]; 250 | if DisplayFlag 251 | disp(['The best and mean of Generation # 0 are ', num2str(MinCost(end)), ' and ', num2str(AvgCost(end))]); 252 | end 253 | return; 254 | 255 | 256 | 257 | function [AveCost, nLegal] = ComputeAveCost(Population) 258 | % Compute the average cost of all legal individuals in the population. 259 | % OUTPUTS: AveCost = average cost 260 | % nLegal = number of legal individuals in population 261 | % Save valid population member fitnesses in temporary array 262 | Cost = []; 263 | nLegal = 0; 264 | for i = 1 : length(Population) 265 | if Population(i).cost < inf 266 | Cost = [Cost Population(i).cost]; 267 | nLegal = nLegal + 1; 268 | end 269 | end 270 | % Compute average cost. 271 | AveCost = mean(Cost); 272 | return; 273 | 274 | 275 | 276 | 277 | 278 | function Population1 = CombinePopulation(OPTIONS, Population1, Population2) 279 | numButterfly1 = ceil(OPTIONS.partition*OPTIONS.popsize); 280 | for i = 1: OPTIONS.popsize - numButterfly1 281 | Population1(numButterfly1 + i).chrom = Population2(i).chrom; 282 | Population1(numButterfly1 + i).cost = Population2(i).cost; 283 | end 284 | 285 | 286 | 287 | function [Population] = ClearDups(Population, MaxParValue, MinParValue) 288 | % Make sure there are no duplicate individuals in the population. 289 | % This logic does not make 100% sure that no duplicates exist, but any duplicates that are found are 290 | % randomly mutated, so there should be a good chance that there are no duplicates after this procedure. 291 | for i = 1 : length(Population) 292 | Chrom1 = sort(Population(i).chrom); 293 | for j = i+1 : length(Population) 294 | Chrom2 = sort(Population(j).chrom); 295 | if isequal(Chrom1, Chrom2) 296 | parnum = ceil(length(Population(j).chrom) * rand); 297 | Population(j).chrom(parnum) = floor(MinParValue(parnum)... 298 | + (MaxParValue(parnum) - MinParValue(parnum) + 1) * rand); 299 | end 300 | end 301 | end 302 | return; 303 | 304 | 305 | 306 | 307 | function [InitFunction, CostFunction, FeasibleFunction] = FUN 308 | InitFunction = @FUNInit; 309 | CostFunction = @FUNCost; 310 | FeasibleFunction = @FUNFeasible; 311 | return; 312 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 313 | function [MaxParValue, MinParValue, Population, OPTIONS] = FUNInit(OPTIONS, constraints) 314 | global MinParValue MaxParValue 315 | Granularity = 0.1; 316 | MinParValue = constraints(1,1)*ones(1,OPTIONS.numVar); 317 | MaxParValue = constraints(1,2)*ones(1,OPTIONS.numVar); 318 | % Initialize population 319 | for popindex = 1 : OPTIONS.popsize 320 | chrom = MinParValue + (MaxParValue - MinParValue + 1) .* rand(1,OPTIONS.numVar); 321 | Population(popindex).chrom = chrom; 322 | end 323 | OPTIONS.OrderDependent = false; 324 | return; 325 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 326 | function [Population] = FUNCost(OPTIONS, Population, costFun) 327 | % Compute the cost of each member in Population 328 | global MinParValue MaxParValue 329 | popsize = OPTIONS.popsize; 330 | p = OPTIONS.numVar; 331 | for popindex = 1 : popsize 332 | Population(popindex).cost = costFun(Population(popindex).chrom); 333 | end 334 | return 335 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 336 | function [Population] = FUNFeasible(OPTIONS, Population) 337 | global MinParValue MaxParValue 338 | for i = 1 : OPTIONS.popsize 339 | for k = 1 : OPTIONS.numVar 340 | Population(i).chrom(k) = max(Population(i).chrom(k), MinParValue(k)); 341 | Population(i).chrom(k) = min(Population(i).chrom(k), MaxParValue(k)); 342 | end 343 | end 344 | return; 345 | -------------------------------------------------------------------------------- /Algorithms/UMOEA.m: -------------------------------------------------------------------------------- 1 | function [bestx, bestold, Convergence_curve, com_time]= UMOEA(fun, dim, constraints, N, Max_iter) 2 | 3 | Par.n_opr=3; %% number of operators in MODE 4 | Par.n=dim; %% number of decision vriables 5 | 6 | if Par.n==10 7 | Par.CS=50; %% cycle 8 | elseif Par.n==30 9 | Par.CS=100; %% cycle 10 | elseif Par.n==50 11 | Par.CS=150; %% cycle 12 | else 13 | Par.CS=150; %% cycle 14 | end 15 | % Par.CS=1; %% cycle 16 | 17 | Par.xmin= constraints(:,1)'; 18 | Par.xmax= constraints(:,2)'; 19 | Par.Max_FES=N*Max_iter; 20 | Par.PopSize=N; %% population size 21 | Par.MinPopSize=4; 22 | Par.prob_ls=0.1; 23 | 24 | %% printing the detailed results- this will increase the computational time 25 | Par.Printing=0; %% 1 to print; 0 otherwise 26 | 27 | 28 | iter=0; %% current generation 29 | 30 | 31 | stream = RandStream('mt19937ar','Seed',sum(100*clock)); 32 | seed_run=stream.Seed; %% to record seeds for further validation, if needed 33 | RandStream.setGlobalStream(stream); 34 | 35 | %% define variables 36 | current_eval=0; %% current fitness evaluations 37 | PS1=Par.PopSize; %% define PS1 38 | PS2=4+floor(3*log(Par.n)); %% define PS2 39 | PS1 = PS1-PS2; 40 | Par.PopSize=PS1+PS2; %% PS = PS1+PS2 41 | 42 | %% ====================== Initalize x ================================== 43 | x=repmat(Par.xmin,Par.PopSize,1)+repmat((Par.xmax-Par.xmin),Par.PopSize,1).*rand(Par.PopSize,Par.n); 44 | 45 | %% calc. fit. and update FES 46 | tic; 47 | fitx = zeros(Par.PopSize,1); 48 | for ii = 1:Par.PopSize 49 | fitx(ii) = fun(x(ii,:)); 50 | end 51 | current_eval =current_eval+Par.PopSize; 52 | res_det= min(repmat(min(fitx),1,Par.PopSize), fitx); %% used to record the convergence 53 | 54 | %% ====================== store the best ================== 55 | [bestold, bes_l]=min(fitx); bestx= x(bes_l,:); 56 | Convergence_curve = bestold; 57 | %% ================== fill in each MOEA =================================== 58 | %% DE 59 | EA_1= x(1:PS1,:); EA_obj1= fitx(1:PS1); 60 | %% ES 61 | EA_2= x(PS1+1:size(x,1),:); EA_obj2= fitx(PS1+1:size(x,1)); 62 | %% ================ define CMA-ES parameters ============================== 63 | setting=[];fitness=[];bnd=[]; 64 | [setting,fitness,bnd]= init_cmaes_par(setting,fitness,bnd,EA_obj2,EA_2, Par.n, PS2, Par.xmin, Par.xmax); 65 | 66 | %% ===== prob. of each DE variant 67 | probDE1=1./Par.n_opr .* ones(1,Par.n_opr); 68 | %% ===================== archive data ==================================== 69 | arch_rate=2.6; 70 | archive.NP = arch_rate * PS1; % the maximum size of the archive 71 | archive.pop = zeros(0, Par.n); % the solutions stored in te archive 72 | archive.funvalues = zeros(0, 1); % the function value of the archived solutions 73 | %% ==================== to adapt CR and F ================================= 74 | hist_pos=1; 75 | memory_size=6; 76 | archive_f= ones(1,memory_size).*0.5; 77 | archive_Cr= ones(1,memory_size).*0.5; 78 | %% 79 | stop_con=0; avgFE=Par.Max_FES; InitPop=PS1; 80 | 81 | cy=0;indx = 0; Probs=ones(1,2); 82 | 83 | %% main loop 84 | while stop_con==0 85 | 86 | iter=iter+1; 87 | cy=cy+1; % to control CS 88 | % ================ determine the best MOEA =========================== 89 | if(cy==ceil(Par.CS+1)) 90 | 91 | %%calc normalized qualit -- NQual 92 | qual(1) = EA_obj1(1);qual(2) = EA_obj2(1); 93 | norm_qual = qual./sum(qual); 94 | norm_qual=1-norm_qual; %% to satisfy the bigger is the better 95 | 96 | %%Normalized diversity 97 | D(1) = mean(pdist2(EA_1(2:PS1,:),EA_1(1,:))); 98 | D(2) = mean(pdist2(EA_2(2:PS2,:),EA_2(1,:))); 99 | norm_div= D./sum(D); 100 | 101 | %%Total Imp 102 | Probs=norm_qual+norm_div; 103 | %%Update Prob_MODE and Prob_CMAES 104 | Probs = max(0.1, min(0.9,Probs./sum(Probs))); 105 | 106 | [~,indx]=max(Probs); 107 | if Probs(1)==Probs(2) 108 | indx=0;%% no sharing of information 109 | end 110 | 111 | elseif cy==2*ceil(Par.CS) 112 | 113 | %% share information 114 | if indx==1 115 | list_ind = randperm(PS1); 116 | list_ind= list_ind(1:(min(PS2,PS1))); 117 | EA_2(1:size(list_ind,2),:)= EA_1(list_ind,:); 118 | EA_obj2(1:size(list_ind,2))= EA_obj1(list_ind); 119 | [setting,fitness,bnd]= init_cmaes_par(setting,fitness,bnd,EA_obj2,EA_2, Par.n, PS2, Par.xmin, Par.xmax); 120 | setting.sigma= setting.sigma*(1- (current_eval/Par.Max_FES)); 121 | else 122 | if (min (EA_2(1,:)))> -100 && (max(EA_2(1,:)))<100 %% share best sol. in EA_2 if it is feasible 123 | EA_1(PS1,:)= EA_2(1,:); 124 | EA_obj1(PS1)= EA_obj2(1); 125 | [EA_obj1, ind]=sort(EA_obj1); 126 | EA_1=EA_1(ind,:); 127 | end 128 | 129 | end 130 | %% reset cy and Probs 131 | cy=1; Probs=ones(1,2); 132 | end 133 | %% ====================== MOEA1 <-- SAMODE ============================ 134 | if (current_eval UpdPopSize 140 | reduction_ind_num = PS1 - UpdPopSize; 141 | if PS1 - reduction_ind_num < Par.MinPopSize; 142 | reduction_ind_num = PS1 - Par.MinPopSize; 143 | end 144 | %% remove the worst ind. 145 | for r = 1 : reduction_ind_num 146 | vv=PS1; 147 | EA_1(vv,:)=[]; 148 | EA_obj1(vv)=[]; 149 | PS1 = PS1 - 1; 150 | end 151 | archive.NP = round(arch_rate * PS1); 152 | if size(archive.pop, 1) > archive.NP 153 | rndpos = randperm(size(archive.pop, 1)); 154 | rndpos = rndpos(1 : archive.NP); 155 | archive.pop = archive.pop(rndpos, :); 156 | end 157 | end 158 | 159 | %% apply MODE 160 | [EA_1, EA_obj1,probDE1,bestold,bestx,archive,hist_pos,memory_size, archive_f,archive_Cr,current_eval,res_det] = ... 161 | SAMO_DE(fun, EA_1, EA_obj1,probDE1,bestold,bestx,archive,hist_pos,memory_size, archive_f,archive_Cr,... 162 | Par.xmin, Par.xmax, Par.n, PS1, current_eval,res_det,Par.Printing,Par.Max_FES); 163 | end 164 | end 165 | %% ====================== MOEA2 <-- SAMO-ES ====================== 166 | if (current_eval0.75*Par.Max_FES 176 | if rand=Par.Max_FES) 205 | stop_con=1; 206 | end 207 | 208 | %% =============================== Print ============================== 209 | % fprintf('current_eval\t %d fitness\t %d \n', current_eval, abs(Par.f_optimal-bestold)); 210 | if stop_con 211 | L = length(Convergence_curve); 212 | ind = round((1:Max_iter)*L/Max_iter); 213 | Convergence_curve = Convergence_curve(ind); 214 | com_time= toc;%cputime-start_time; 215 | end 216 | end 217 | end 218 | 219 | 220 | 221 | function [setting,fitness,bnd]= init_cmaes_par(setting,fitness,bnd,EA_obj2, EA_2, n, n2, xmin, xmax) 222 | % Initialize dynamic internal state parameters 223 | 224 | setting.flgActiveCMA=0; 225 | setting.flgresume=0; 226 | setting.flgDiagonalOnly=0; 227 | %% remember that EA_2 was uniformly generated between xmin and xmax. 228 | %% So, mean(EA_2) does not violate the initialization condition in the competition 229 | setting.xmean = mean(EA_2); 230 | setting.xmean=setting.xmean'; 231 | setting.insigma=0.3; 232 | setting.sigma = setting.insigma; 233 | setting.maxdx = Inf; 234 | setting.mindx = 0; 235 | 236 | setting.sigma = max(setting.insigma); % overall standard deviation 237 | setting.pc = zeros(n,1); setting.ps = zeros(n,1); % evolution paths for setting.C and setting.sigma 238 | 239 | 240 | setting.idx = (xmin > -Inf) | (xmax < Inf); 241 | if length(setting.idx) == 1 242 | setting.idx = setting.idx * ones(n,1); 243 | end 244 | if length(setting.insigma) == 1 245 | setting.insigma = setting.insigma * ones(n,1) ; 246 | end 247 | setting.diagD = setting.insigma/max(setting.insigma); % diagonal matrix D defines the scaling 248 | setting.diagC = setting.diagD.^2; 249 | if setting.flgDiagonalOnly ~= 1 % use at some point full covariance matrix 250 | setting.B = eye(n,n); % setting.B defines the coordinate system 251 | setting.BD = setting.B.*repmat(setting.diagD',n,1); % setting.B*D for speed up only 252 | setting.C = diag(setting.diagC); % covariance matrix == setting.BD*(setting.BD)' 253 | end 254 | 255 | if setting.flgDiagonalOnly 256 | setting.B = 1; 257 | end 258 | setting.D = ones(n,1); 259 | setting.invsqrtC = setting.B * diag( setting.D.^-1) * setting.B'; 260 | 261 | fitness.hist=NaN*ones(1,10+ceil(3*10*n/n2)); % history of fitness values 262 | fitness.histsel=NaN*ones(1,10+ceil(3*10*n/n2)); % history of fitness values 263 | fitness.histbest=[]; % history of fitness values 264 | fitness.histmedian=[]; % history of fitness values 265 | 266 | % Initialize boundary handling 267 | bnd.isactive = any(xmin > -Inf) || any(xmax < Inf); 268 | if bnd.isactive 269 | bnd.weights = zeros(n,1); % setting.weights for bound penalty 270 | % scaling is better in axis-parallel case, worse in rotated 271 | bnd.flgscale = 0; % scaling will be omitted if zero 272 | if bnd.flgscale ~= 0 273 | bnd.scale = setting.diagC/mean(setting.diagC); 274 | else 275 | bnd.scale = ones(n,1); 276 | end 277 | setting.idx = (xmin > -Inf) | (xmax < Inf); 278 | if length(setting.idx) == 1 279 | setting.idx = setting.idx * ones(n,1); 280 | end 281 | setting.idx = (xmin > -Inf) | (xmax < Inf); 282 | if length(setting.idx) == 1 283 | setting.idx = setting.idx * ones(n,1); 284 | end 285 | bnd.isbounded = zeros(n,1); 286 | bnd.isbounded(setting.idx) = 1; 287 | setting.maxdx = min(setting.maxdx, (xmax - xmin)/2); 288 | if any(setting.sigma*sqrt(setting.diagC) > setting.maxdx') 289 | setting.fac = min(setting.maxdx ./ sqrt(setting.diagC))/setting.sigma; 290 | setting.sigma = min(setting.maxdx ./ sqrt(setting.diagC)); 291 | end 292 | 293 | setting.dd = setting.diagC; 294 | bnd.dfithist = 1; % delta fit for setting setting.weights 295 | bnd.aridxpoints = []; % remember complete outside points 296 | bnd.arfitness = []; % and their fitness 297 | bnd.validfitval = 0; 298 | bnd.iniphase = 1; 299 | % scaling is better in axis-parallel case, worse in rotated 300 | bnd.flgscale = 0; % scaling will be omitted if zero 301 | if bnd.flgscale ~= 0 302 | bnd.scale = setting.diagC/mean(setting.diagC); 303 | else 304 | bnd.scale = ones(n,1); 305 | end 306 | end 307 | 308 | % Initialize dynamic (internal) strategy parameters and constants 309 | % usually close to 1 310 | % Initialize dynamic (internal) strategy parameters and constants 311 | 312 | 313 | setting.endinvsqrtC = 0;%setting.B * diag(D.^-1) * setting.B'; % setting.C^-1/2 314 | setting.eigeneval = 0; % track update of setting.B and D 315 | setting.chiN=n^0.5*(1-1/(4*n)+1/(21*n^2)); % expectation of 316 | % ||n(0,I)|| == norm(randn(n,1)) 317 | 318 | setting.mu = ceil(n2/2); % number of parents/points for recombination 319 | setting.weights = log(max(setting.mu, n/2) + 1/2)-log(1:setting.mu)'; % muXone array for weighted recombination setting.mu = floor(setting.mu); 320 | setting.mueff=sum(setting.weights)^2/sum(setting.weights.^2); % variance-effective size of setting.mu 321 | setting.weights = setting.weights/sum(setting.weights); % normalize recombination setting.weights array 322 | 323 | % Strategy parameter setting: Adaptation 324 | setting.cc = (4 + setting.mueff/n) / (n+4 + 2*setting.mueff/n); % time constant for cumulation for setting.C 325 | setting.cs = (setting.mueff+2) / (n+setting.mueff+3); % t-const for cumulation for setting.sigma control 326 | setting.ccov1 = 2 / ((n+1.3)^2+setting.mueff); % learning rate for rank-one update of setting.C 327 | setting.ccovmu = 2 * (setting.mueff-2+1/setting.mueff) / ((n+2)^2+setting.mueff); % and for rank-setting.mu update 328 | setting.damps = 0.5 + 0.5*min(1, (0.27*n2/setting.mueff-1)^2) + 2*max(0,sqrt((setting.mueff-1)/(n+1))-1) + setting.cs; % damping for setting.sigma 329 | 330 | if setting.flgDiagonalOnly 331 | setting.ccov1_sep = min(1, setting.ccov1 * (n+1.5) / 3); 332 | setting.ccovmu_sep = min(1-setting.ccov1_sep, setting.ccovmu * (n+1.5) / 3); 333 | else 334 | setting.ccov1_sep=0; 335 | setting.ccovmu_sep=0; 336 | end 337 | 338 | setting.stopOnEqualFunctionValues= 2 + n/3; 339 | setting.arrEqualFunvals = zeros(1, 10+n); 340 | if isempty(setting.insigma) 341 | if all(size(( setting.xmean)) > 1) 342 | setting.insigma = std( setting.xmean, 0, 2); 343 | else 344 | end 345 | end 346 | 347 | 348 | fitness.hist(1)= EA_obj2(1);%cec14_func( setting.xmean,I_fno); 349 | fitness.histsel(1)=fitness.hist(1); 350 | 351 | setting.xold = setting.xmean; 352 | end 353 | 354 | 355 | 356 | 357 | function [x, fitx,prob,bestold,bestx,archive,hist_pos,memory_size, archive_f,archive_Cr,current_eval,res_det ] = ... 358 | SAMO_DE(fun, x, fitx,prob,bestold,bestx,archive,hist_pos,memory_size, archive_f,archive_Cr,xmin, xmax, n,... 359 | PopSize, current_eval,res_det,Printing,Max_FES) 360 | 361 | 362 | vi=zeros(PopSize,n); 363 | 364 | %% calc CR and F 365 | mem_rand_index = ceil(memory_size * rand(PopSize, 1)); 366 | mu_sf = archive_f(mem_rand_index); 367 | mu_cr = archive_Cr(mem_rand_index); 368 | 369 | %% ========================= generate CR ================================== 370 | cr = normrnd(mu_cr, 0.1)'; 371 | cr(mu_cr == -1) = 0; 372 | cr = min(cr, 1); 373 | 374 | %% ========================= generate F =================================== 375 | F = mu_sf + 0.1 * tan(pi * (rand( 1,PopSize) - 0.5)); 376 | pos = find(F <= 0); 377 | while ~ isempty(pos) 378 | F(pos) = mu_sf(pos) + 0.1 * tan(pi * (rand( 1,length(pos)) - 0.5)); 379 | pos = find(F <= 0); 380 | end 381 | F = min(F, 1)'; 382 | 383 | %% ======================== generate new x ================================= 384 | popAll = [x;archive.pop]; %% set archive 385 | r0 = 1 : PopSize; 386 | %% generate random integer numbers 387 | [r1, r2,r3] = gnR1R2(PopSize, size(popAll, 1), r0); 388 | 389 | %% mutation 390 | bb= rand(PopSize, 1); 391 | probiter = prob(1,:); 392 | l2= sum(prob(1:2)); 393 | op_1 = bb <= probiter(1)*ones(PopSize, 1); 394 | op_2 = bb > probiter(1)*ones(PopSize, 1) & bb <= (l2*ones(PopSize, 1)) ; 395 | op_3 = bb > l2*ones(PopSize, 1) & bb <= (ones(PopSize, 1)) ; 396 | 397 | pNP = max(round(0.1 * PopSize), 2); %% choose at least two best solutions 398 | randindex = ceil(rand(1, PopSize) .* pNP); %% select from [1, 2, 3, ..., pNP] 399 | randindex = max(1, randindex); %% to avoid the problem that rand = 0 and thus ceil(rand) = 0 400 | phix = x(randindex, :); %% randomly choose one of the top 10% solutions 401 | %% DE2 -- current-to-pbest/archive 402 | vi(op_1==1,:) = x(op_1==1,:)+ F(op_1==1, ones(1, n)) .*(phix(op_1==1,:) - x(op_1==1,:) + x(r1(op_1==1), :) - popAll(r2(op_1==1), :)); 403 | %% DE2 -- current-to-pbest/without archive 404 | vi(op_2==1,:) = x(op_2==1,:)+ F(op_2==1, ones(1, n)) .*(phix(op_2==1,:) - x(op_2==1,:) + x(r1(op_2==1), :) - x(r3(op_2==1), :)); 405 | %% DE3 -- weighted-phi-rand 406 | pNP = max(round(0.5 * PopSize), 2); %% choose at least two best solutions 407 | randindex = ceil(rand(1, PopSize) .* pNP); %% select from [1, 2, 3, ..., pNP] 408 | randindex = max(1, randindex); %% to avoid the problem that rand = 0 and thus ceil(rand) = 0 409 | phix = x(randindex, :); %% randomly choose one of the top 50% solutions 410 | %% DE3 -- weighted DE 411 | vi(op_3==1,:) = F(op_3==1, ones(1, n)).* x(r1(op_3==1), :) + phix(op_3==1,:) - x(r3(op_3==1), :); 412 | 413 | %% handle boundaries 414 | vi = han_boun(vi, xmax, xmin, x,PopSize,1); 415 | %% crossover 416 | mask = rand(PopSize, n) > cr(:, ones(1, n)); % mask is used to indicate which elements of ui comes from the parent 417 | rows = (1 : PopSize)'; cols = floor(rand(PopSize, 1) * n)+1; % choose one position where the element of ui doesn't come from the parent 418 | jrand = sub2ind([PopSize n], rows, cols); mask(jrand) = false; 419 | ui = vi; ui(mask) = x(mask); 420 | 421 | %% evaluate 422 | fitx_new = zeros(PopSize,1); 423 | for ii = 1:PopSize 424 | fitx_new(ii) = fun(ui(ii,:)); 425 | end 426 | %% update FITNESS EVALUATIONS 427 | current_eval =current_eval+PopSize; 428 | 429 | %% calc. imprv. for Cr and F 430 | diff = abs(fitx - fitx_new); 431 | I =(fitx_new < fitx); 432 | goodCR = cr(I == 1); 433 | goodF = F(I == 1); 434 | 435 | %% ========================= update archive =============================== 436 | archive = updateArchive(archive, x(I == 1, :), fitx(I == 1)'); 437 | %% ==================== update Prob. of each DE =========================== 438 | diff2 = max(0,(fitx - fitx_new))./abs(fitx); 439 | count_S(1)=max(0,mean(diff2(op_1==1))); 440 | count_S(2)=max(0,mean(diff2(op_2==1))); 441 | count_S(3)=max(0,mean(diff2(op_3==1))); 442 | 443 | %% update probs. 444 | %%% Althouth count_S~=0 may slow down the convergence, it gives more 445 | %%% diversity. In case you look for a better convergence you can set it to 446 | %%% sum(count_S)~=0 447 | if count_S~=0 448 | prob= max(0.1,min(0.9,count_S./(sum(count_S)))); 449 | else 450 | prob=1/3 * ones(1,3); 451 | end 452 | %% ==================== update x and fitx ================================= 453 | fitx(I==1)= fitx_new(I==1); 454 | x(I == 1, :) = ui(I == 1, :); 455 | %% =================== update memory cr and F ============================= 456 | num_success_params = numel(goodCR); 457 | if num_success_params > 0 458 | weightsDE = diff(I == 1)./ sum(diff(I == 1)); 459 | %% for updating the memory of scaling factor 460 | archive_f(hist_pos) = (weightsDE' * (goodF .^ 2))./ (weightsDE' * goodF); 461 | 462 | %% for updating the memory of crossover rate 463 | if max(goodCR) == 0 || archive_Cr(hist_pos) == -1 464 | archive_Cr(hist_pos) = -1; 465 | else 466 | archive_Cr(hist_pos) = (weightsDE' * (goodCR .^ 2)) / (weightsDE' * goodCR); 467 | end 468 | 469 | hist_pos= hist_pos+1; 470 | if hist_pos > memory_size; hist_pos = 1; end 471 | 472 | end 473 | 474 | %% sort new x, fitness 475 | [fitx, ind]=sort(fitx); 476 | x=x(ind,:); 477 | 478 | %% record the best value after checking its feasiblity status 479 | if fitx(1)=xmin(1) && max(x(ind(1),:))<=xmax(1) 480 | bestold=fitx(1); 481 | bestx= x(1,:); 482 | end 483 | %% check to print 484 | if Printing==1 485 | res_det= [res_det repmat(bestold,1,PopSize)]; 486 | end 487 | 488 | end 489 | 490 | 491 | 492 | function [r1, r2,r3] = gnR1R2(NP1, NP2, r0) 493 | 494 | % gnA1A2 generate two column vectors r1 and r2 of size NP1 & NP2, respectively 495 | % r1's elements are choosen from {1, 2, ..., NP1} & r1(i) ~= r0(i) 496 | % r2's elements are choosen from {1, 2, ..., NP2} & r2(i) ~= r1(i) & r2(i) ~= r0(i) 497 | % 498 | % Call: 499 | % [r1 r2 ...] = gnA1A2(NP1) % r0 is set to be (1:NP1)' 500 | % [r1 r2 ...] = gnA1A2(NP1, r0) % r0 should be of length NP1 501 | % 502 | % Version: 2.1 Date: 2008/07/01 503 | % Written by Jingqiao Zhang (jingqiao@gmail.com) 504 | 505 | NP0 = length(r0); 506 | 507 | r1 = floor(rand(1, NP0) * NP1) + 1; 508 | 509 | %for i = 1 : inf 510 | for i = 1 : 99999999 511 | pos = (r1 == r0); 512 | if sum(pos) == 0 513 | break; 514 | else % regenerate r1 if it is equal to r0 515 | r1(pos) = floor(rand(1, sum(pos)) * NP1) + 1; 516 | end 517 | if i > 1000 % this has never happened so far 518 | error('Can not genrate r1 in 1000 iterations'); 519 | end 520 | end 521 | 522 | r2 = floor(rand(1, NP0) * NP2) + 1; 523 | %for i = 1 : inf 524 | for i = 1 : 99999999 525 | pos = ((r2 == r1) | (r2 == r0)); 526 | if sum(pos)==0 527 | break; 528 | else % regenerate r2 if it is equal to r0 or r1 529 | r2(pos) = floor(rand(1, sum(pos)) * NP2) + 1; 530 | end 531 | if i > 1000 % this has never happened so far 532 | error('Can not genrate r2 in 1000 iterations'); 533 | end 534 | end 535 | 536 | r3= floor(rand(1, NP0) * NP1) + 1; 537 | %for i = 1 : inf 538 | for i = 1 : 99999999 539 | pos = ((r3 == r0) | (r3 == r1) | (r3==r2)); 540 | if sum(pos)==0 541 | break; 542 | else % regenerate r2 if it is equal to r0 or r1 543 | r3(pos) = floor(rand(1, sum(pos)) * NP1) + 1; 544 | end 545 | if i > 1000 % this has never happened so far 546 | error('Can not genrate r2 in 1000 iterations'); 547 | end 548 | end 549 | end 550 | 551 | 552 | %% ============United Multi-Operator Evolutionary AlgorithmsII ============ 553 | % Should you have any queries, please contact 554 | % Dr. Saber Elsayed. University of New South Wales at Canberra 555 | % s.elsayed@adfa.edu.au 556 | % www.saberelsayd.net or 557 | % https://sites.google.com/site/saberelsayed3/home 558 | % ========================================================================= 559 | 560 | function x = han_boun (x, xmax, xmin, x2, PopSize,hb) 561 | 562 | switch hb 563 | case 1 % for DE 564 | x_L = repmat(xmin, PopSize, 1); 565 | pos = x < x_L; 566 | x(pos) = (x2(pos) + x_L(pos)) / 2; 567 | 568 | x_U = repmat(xmax, PopSize, 1); 569 | pos = x > x_U; 570 | x(pos) = (x2(pos) + x_U(pos)) / 2; 571 | 572 | case 2 % for CMA-ES 573 | x_L = repmat(xmin, PopSize, 1); 574 | pos = x < x_L; 575 | x_U = repmat(xmax, PopSize, 1); 576 | x(pos) = min(x_U(pos),max(x_L(pos),2*x_L(pos)-x2(pos))) ; 577 | pos = x > x_U; 578 | x(pos) = max(x_L(pos),min(x_U(pos),2*x_L(pos)-x2(pos))); 579 | 580 | end 581 | end 582 | 583 | 584 | function archive = updateArchive(archive, pop, funvalue) 585 | % Update the archive with input solutions 586 | % Step 1: Add new solution to the archive 587 | % Step 2: Remove duplicate elements 588 | % Step 3: If necessary, randomly remove some solutions to maintain the archive size 589 | % 590 | % Version: 1.1 Date: 2008/04/02 591 | % Written by Jingqiao Zhang (jingqiao@gmail.com) 592 | 593 | if archive.NP == 0, return; end 594 | 595 | % Method 2: Remove duplicate elements 596 | popAll = [archive.pop; pop ]; 597 | funvalues = [archive.funvalues; funvalue' ]; 598 | [dummy IX]= unique(popAll, 'rows'); 599 | if length(IX) < size(popAll, 1) % There exist some duplicate solutions 600 | popAll = popAll(IX, :); 601 | funvalues = funvalues(IX, :); 602 | end 603 | 604 | if size(popAll, 1) <= archive.NP % add all new individuals 605 | archive.pop = popAll; 606 | archive.funvalues = funvalues; 607 | else % randomly remove some solutions 608 | rndpos = randperm(size(popAll, 1)); % equivelent to "randperm"; 609 | rndpos = rndpos(1 : archive.NP); 610 | 611 | archive.pop = popAll (rndpos, :); 612 | archive.funvalues = funvalues(rndpos, :); 613 | end 614 | end 615 | 616 | 617 | 618 | function[ x, fitx, setting,bestold,bestx,bnd,fitness,current_eval,res_det] = ... 619 | SAMO_ES(fun, x, ~, setting, iter,bestold,bestx,fitness,bnd,xmin,xmax,n,PopSize,current_eval,res_det,Printing,Max_FES) 620 | 621 | stopOnWarnings=0; 622 | noiseReevals = 0; 623 | fitness.raw = NaN(1, PopSize + noiseReevals); 624 | fitness.raw(PopSize + find(isnan(fitness.raw(1:noiseReevals)))) = NaN; 625 | 626 | arz = randn(n,PopSize); 627 | arx = repmat(setting.xmean, 1, PopSize) + setting.sigma * (setting.BD * arz); 628 | 629 | %% ignore handling the boundaries constraints during the first 50% evolutionary process 630 | %%-this is based on our earlier analysis carried out on UMOEAs in 2014. 631 | handle_limit=0.5; 632 | if current_eval >=handle_limit*Max_FES 633 | arxvalid =han_boun(arx', xmax, xmin, x,PopSize,2); 634 | arxvalid=arxvalid'; 635 | else 636 | arxvalid=arx; 637 | end 638 | %% evaluate and update cfe 639 | fitness.raw = zeros(size(arxvalid,2),1); 640 | for ii = 1:size(arxvalid,2) 641 | fitness.raw(ii) = fun(arxvalid(:,ii)'); 642 | end 643 | current_eval=current_eval+PopSize; %% increase the fitness evaluations 644 | 645 | fitness.sel= fitness.raw ; 646 | [fitness.sel, fitness.idxsel] = sort(fitness.sel); 647 | 648 | fitness.raw= fitness.raw(fitness.idxsel); 649 | arxvalid= arxvalid(:, fitness.idxsel); 650 | arx= arx(:, fitness.idxsel); 651 | arz=arz(:, fitness.idxsel); 652 | [~,pos_ro]=min(fitness.raw); 653 | 654 | %% record the best value after checking its feasiblity status 655 | if fitness.raw(pos_ro) < bestold && (min(arxvalid(:,pos_ro)))>=xmin(1) && (max(arxvalid(:,pos_ro)))<=xmax(1) 656 | bestold=fitness.raw(pos_ro); 657 | bestx= arxvalid(:,pos_ro)'; 658 | end 659 | if Printing==1 660 | res_det= [res_det repmat(bestold,1,PopSize)]; 661 | end 662 | 663 | 664 | % Calculate new setting.xmean, this is selection and recombination 665 | setting.xold = setting.xmean; % for speed up of Eq. (2) and (3) 666 | cmean =1;% 1/min(max((PopSize-1*n)/2, 1), n); % == 1/kappa 667 | setting.xmean = (1-cmean) * setting.xold + cmean * arx(:,(1:setting.mu))*setting.weights; 668 | if current_eval >=handle_limit*Max_FES 669 | % setting.xmean = xintobounds(setting.xmean, xmin', xmax'); 670 | setting.xmean =han_boun(setting.xmean', xmax, xmin, x(1,:),1,2); 671 | setting.xmean=setting.xmean'; 672 | end 673 | zmean = arz(:,(1:setting.mu))*setting.weights;%==D^-1*setting.B'*(setting.xmean-setting.xold)/setting.sigma 674 | % Cumulation: update evolution paths 675 | setting.ps = (1-setting.cs)*setting.ps + sqrt(setting.cs*(2-setting.cs)*setting.mueff) * (setting.B*zmean); % Eq. (4) 676 | hsig = norm(setting.ps)/sqrt(1-(1-setting.cs)^(2*iter))/setting.chiN < 1.4 + 2/(n+1); 677 | 678 | setting.pc = (1-setting.cc)*setting.pc ... 679 | + hsig*(sqrt(setting.cc*(2-setting.cc)*setting.mueff)/setting.sigma/cmean) * (setting.xmean-setting.xold); % Eq. (2) 680 | if hsig == 0 681 | % disp([num2str(iter) ' ' num2str(counteval) ' setting.pc update stalled']); 682 | end 683 | % Adapt covariance matrix 684 | neg.ccov = 0; % TODO: move parameter setting upwards at some point 685 | if setting.ccov1 + setting.ccovmu > 0 % Eq. (3) 686 | if setting.flgDiagonalOnly % internal linear(?) complexity 687 | setting.diagC = (1-setting.ccov1_sep-setting.ccovmu_sep+(1-hsig)*setting.ccov1_sep*setting.cc*(2-setting.cc)) * setting.diagC ... % regard old matrix 688 | + setting.ccov1_sep * setting.pc.^2 ... % plus rank one update 689 | + setting.ccovmu_sep ... % plus rank setting.mu update 690 | * (setting.diagC .* (arz(:,(1:setting.mu)).^2 * setting.weights)); 691 | % * (repmat(setting.diagC,1,setting.mu) .* arz(:,(1:setting.mu)).^2 * setting.weights); 692 | setting.diagD = sqrt(setting.diagC); % replaces eig(setting.C) 693 | else 694 | arpos = (arx(:,(1:setting.mu))-repmat(setting.xold,1,setting.mu)) / setting.sigma; 695 | setting.C = (1-setting.ccov1-setting.ccovmu+(1-hsig)*setting.ccov1*setting.cc*(2-setting.cc)) * setting.C ... % regard old matrix 696 | + setting.ccov1 * setting.pc*setting.pc' ... % plus rank one update 697 | + setting.ccovmu ... % plus rank setting.mu update 698 | * arpos * (repmat(setting.weights,1,n) .* arpos'); 699 | % is now O(setting.mu*n^2 + setting.mu*n), was O(setting.mu*n^2 + setting.mu^2*n) when using diag(setting.weights) 700 | % for setting.mu=30*n it is now 10 times faster, overall 3 times faster 701 | 702 | setting.diagC = diag(setting.C); 703 | end 704 | end 705 | 706 | 707 | % Adapt setting.sigma 708 | setting.sigma = setting.sigma * exp(min(1, (sqrt(sum(setting.ps.^2))/setting.chiN - 1) * setting.cs/setting.damps)); % Eq. (5) 709 | % disp([iter norm(setting.ps)/setting.chiN]); 710 | 711 | if 11 < 3 % testing with optimal step-size 712 | setting.sigma = 0.04 * setting.mueff * sqrt(sum(setting.xmean.^2)) / n; % 20D,lam=1000:25e3 713 | setting.sigma = 0.3 * setting.mueff * sqrt(sum(setting.xmean.^2)) / n; % 20D,lam=(40,1000):17e3 714 | % 75e3 with def (1.5) 715 | % 35e3 with setting.damps=0.25 716 | end 717 | if 11 < 3 718 | 719 | setting.xmean = ones(n,1); 720 | end 721 | 722 | % Update setting.B and D from setting.C 723 | 724 | if ~setting.flgDiagonalOnly && (setting.ccov1+setting.ccovmu+neg.ccov) > 0 && mod(iter, 1/(setting.ccov1+setting.ccovmu+neg.ccov)/n/10) < 1 725 | setting.C=triu(setting.C)+triu(setting.C,1)'; % enforce symmetry to prevent complex numbers 726 | [setting.B,tmp] = eig(setting.C); % eigen decomposition, setting.B==normalized eigenvectors 727 | % effort: approx. 15*n matrix-vector multiplications 728 | setting.diagD = diag(tmp); 729 | 730 | % limit condition of setting.C to 1e14 + 1 731 | if min(setting.diagD) <= 0 732 | 733 | setting.diagD(setting.diagD<0) = 0; 734 | tmp = max(setting.diagD)/1e14; 735 | setting.C = setting.C + tmp*eye(n,n); setting.diagD = setting.diagD + tmp*ones(n,1); 736 | 737 | end 738 | if max(setting.diagD) > 1e14*min(setting.diagD) 739 | 740 | tmp = max(setting.diagD)/1e14 - min(setting.diagD); 741 | setting.C = setting.C + tmp*eye(n,n); setting.diagD = setting.diagD + tmp*ones(n,1); 742 | 743 | end 744 | 745 | setting.diagC = diag(setting.C); 746 | setting.diagD = sqrt(setting.diagD); % D contains standard deviations now 747 | % setting.diagD = setting.diagD / prod(setting.diagD)^(1/n); setting.C = setting.C / prod(setting.diagD)^(2/n); 748 | setting.BD = setting.B.*repmat(setting.diagD',n,1); % O(n^2) 749 | end % if mod 750 | 751 | % Align/rescale order of magnitude of scales of setting.sigma and setting.C for nicer output 752 | % TODO: interference with sigmafacup: replace 1e10 with 2*sigmafacup 753 | % not a very usual case 754 | if 1 < 2 && setting.sigma > 1e10*max(setting.diagD) && setting.sigma > 8e14 * max(setting.insigma) 755 | fac = setting.sigma; % / max(setting.diagD); 756 | setting.sigma = setting.sigma/fac; 757 | setting.pc = fac * setting.pc; 758 | setting.diagD = fac * setting.diagD; 759 | if ~setting.flgDiagonalOnly 760 | setting.C = fac^2 * setting.C; % disp(fac); 761 | setting.BD = setting.B .* repmat(setting.diagD',n,1); % O(n^2), but repmat might be inefficient todo? 762 | end 763 | setting.diagC = fac^2 * setting.diagC; 764 | end 765 | 766 | if setting.flgDiagonalOnly > 1 && iter > setting.flgDiagonalOnly 767 | % full covariance matrix from now on 768 | setting.flgDiagonalOnly = 0; 769 | setting.B = eye(n,n); 770 | setting.BD = diag(setting.diagD); 771 | setting.C = diag(setting.diagC); % is better, because correlations are spurious anyway 772 | end 773 | 774 | % ----- numerical error management ----- 775 | % Adjust maximal coordinate axis deviations 776 | if any(setting.sigma*sqrt(setting.diagC) > setting.maxdx') 777 | setting.sigma = min(setting.maxdx ./ sqrt(setting.diagC')); 778 | %warning(['Iteration ' num2str(iter) ': coordinate axis std ' ... 779 | % 'deviation at upper limit of ' num2str(setting.maxdx)]); 780 | % stopflag(end+1) = {'maxcoorddev'}; 781 | end 782 | % Adjust minimal coordinate axis deviations 783 | if any(setting.sigma*sqrt(setting.diagC) < setting.mindx) 784 | setting.sigma = max(setting.mindx ./ sqrt(setting.diagC)) * exp(0.05+setting.cs/setting.damps); 785 | %warning(['Iteration ' num2str(iter) ': coordinate axis std ' ... 786 | % 'deviation at lower limit of ' num2str(setting.mindx)]); 787 | % stopflag(end+1) = {'mincoorddev'};; 788 | end 789 | % Adjust too low coordinate axis deviations 790 | if any(setting.xmean == setting.xmean + 0.2*setting.sigma*sqrt(setting.diagC)) 791 | if stopOnWarnings 792 | % stopflag(end+1) = {'warnnoeffectcoord'}; 793 | else 794 | % warning(['Iteration ' num2str(iter) ': coordinate axis std ' ... 795 | % 'deviation too low' ]); 796 | if setting.flgDiagonalOnly 797 | setting.diagC = setting.diagC + (setting.ccov1_sep+setting.ccovmu_sep) * (setting.diagC .* ... 798 | (setting.xmean == setting.xmean + 0.2*setting.sigma*sqrt(setting.diagC))); 799 | else 800 | setting.C = setting.C + (setting.ccov1+setting.ccovmu) * diag(setting.diagC .* ... 801 | (setting.xmean == setting.xmean + 0.2*setting.sigma*sqrt(setting.diagC))); 802 | end 803 | setting.sigma = setting.sigma * exp(0.05+setting.cs/setting.damps); 804 | end 805 | end 806 | % Adjust step size in case of (numerical) precision problem 807 | if setting.flgDiagonalOnly 808 | tmp = 0.1*setting.sigma*setting.diagD; 809 | else 810 | tmp = 0.1*setting.sigma*setting.BD(:,1+floor(mod(iter,n))); 811 | end 812 | if all(setting.xmean == setting.xmean + tmp) 813 | % ii = 1+floor(mod(iter,n)); 814 | if stopOnWarnings 815 | else 816 | setting.sigma = setting.sigma * exp(0.2+setting.cs/setting.damps); 817 | end 818 | end 819 | % Adjust step size in case of equal function values (flat fitness) 820 | % isequalfuncvalues = 0; 821 | if fitness.sel(1) == fitness.sel(1+ceil(0.1+PopSize/4)) 822 | % isequalfuncvalues = 1; 823 | if setting.stopOnEqualFunctionValues 824 | setting.arrEqualFunvals = [iter setting.arrEqualFunvals(1:end-1)]; 825 | % stop if this happens in more than 33% 826 | if setting.arrEqualFunvals(end) > iter - 3 * length(setting.arrEqualFunvals) 827 | % stopflag(end+1) = {'equalfunvals'}; 828 | end 829 | else 830 | if flgWarnOnEqualFunctionValues 831 | % warning(['Iteration ' num2str(iter) ... 832 | % ': equal function values f=' num2str(fitness.sel(1)) ... 833 | % ' at maximal main axis setting.sigma ' ... 834 | % num2str(setting.sigma*max(setting.diagD))]); 835 | end 836 | setting.sigma = setting.sigma * exp(0.2+setting.cs/setting.damps); 837 | end 838 | end 839 | % Adjust step size in case of equal function values 840 | if iter > 2 && myrange([fitness.hist fitness.sel(1)]) == 0 841 | if stopOnWarnings 842 | % stopflag(end+1) = {'warnequalfunvalhist'}; 843 | else 844 | % warning(['Iteration ' num2str(iter) ... 845 | % ': equal function values in history at maximal main ' ... 846 | % 'axis setting.sigma ' num2str(setting.sigma*max(setting.diagD))]); 847 | setting.sigma = setting.sigma * exp(0.2+setting.cs/setting.damps); 848 | end 849 | end 850 | 851 | %% print out final results 852 | x= arxvalid'; 853 | fitx= fitness.raw; 854 | end 855 | 856 | function res=myrange(x) 857 | res = max(x) - min(x); 858 | end 859 | 860 | 861 | function [x,f,current_eval,succ] = LS (fun, bestx,f,Par,current_eval,Max_FES,xmin,xmax) 862 | 863 | 864 | Par.LS_FE=ceil(20.0000e-003*Max_FES ); %% Max FFEs_LS 865 | 866 | options=optimset('Display','off','algorithm','interior-point',... 867 | 'UseParallel','never','MaxFunEvals',Par.LS_FE) ; 868 | 869 | [Xsqp, FUN , ~ , details]=fmincon(fun, bestx(1,:),[],[],[],[],xmin,xmax, [],options); 870 | 871 | %% check if there is an improvement in the fitness value and update P_{ls} 872 | if (f-FUN)>0 873 | succ=1; 874 | f = FUN; 875 | x(1,:)=Xsqp; 876 | else 877 | succ=0; 878 | x=bestx; 879 | 880 | end 881 | %% update FFEs 882 | current_eval=current_eval+details.funcCount; 883 | end -------------------------------------------------------------------------------- /Algorithms/EBOwithCMAR.m: -------------------------------------------------------------------------------- 1 | %% Some part of this code is taken from UMOEA-II 2 | %%============================================================================== 3 | function [bestx,bestold,CONV,com_time]= EBOwithCMAR(fhd, problem_size, bounds, pop_size, M) 4 | tic; 5 | 6 | global fun_num; 7 | I_fno = fun_num; 8 | run = 1; 9 | CONV = []; 10 | 11 | Par.n_opr=2; %% number of operators in EBOwithCMAR 12 | Par.n=problem_size; %% number of decision vriables 13 | Par.CS=3*problem_size; %% cycle 14 | Par.Gmax = M; 15 | Par.xmin= bounds(1,1)*ones(1,Par.n); 16 | Par.xmax= bounds(1,2)*ones(1,Par.n); 17 | Par.Max_FES=M*pop_size; 18 | %opt= 100:100:3000; %% define the optimal solution as shown in the TR 19 | %Par.f_optimal=opt(I_fno); 20 | %Par.PopSize=18*Par.n; %% population size 21 | Par.PopSize = pop_size; 22 | Par.MinPopSize=4; 23 | Par.prob_ls=0.1; 24 | %% printing the detailed results- this will increase the computational time 25 | Par.Printing=0; %% 1 to print; 0 otherwise 26 | 27 | 28 | iter=0; %% current generation 29 | 30 | %% =================== Define a random seed =============================== 31 | %%------use the seeds we used in the initial submission (Saved Read the seeds saved in Results_Record\seeds), 32 | 33 | %% ======== else use a new set of seed 34 | %% == use it if your computer's specifications are different from tthose mentioned above======= 35 | %%-----Becase we ran experiments in parallel, we used "*run" to differentiate 36 | %%-----among runs which started at the same time 37 | 38 | stream = RandStream('mt19937ar','Seed',sum(100*clock)*run); 39 | RandStream.setGlobalStream(stream); 40 | 41 | %% to record seeds for further validation, if needed 42 | seed_run=stream.Seed; 43 | 44 | %% define variables 45 | current_eval=0; %% current fitness evaluations 46 | PS1=Par.PopSize; %% define PS1 47 | PS2=4+floor(3*log(Par.n)); %% define PS2 48 | % PS2 = 15; 49 | Par.PopSize=PS1+PS2; %% PS = PS1+PS2 50 | 51 | %% ====================== Initalize x ================================== 52 | x=repmat(Par.xmin,Par.PopSize,1)+repmat((Par.xmax-Par.xmin),Par.PopSize,1).*rand(Par.PopSize,Par.n); 53 | xold=repmat(Par.xmin,Par.PopSize,1)+repmat((Par.xmax-Par.xmin),Par.PopSize,1).*rand(Par.PopSize,Par.n); 54 | 55 | %% calc. fit. and update FES 56 | fitx = []; 57 | for brojac = 1:size(x,1) 58 | fitx(brojac) = fhd(x(brojac,:)); 59 | end 60 | %fitx = cec17_func(x',I_fno); 61 | current_eval =current_eval+Par.PopSize; 62 | res_det= min(repmat(min(fitx),1,Par.PopSize), fitx); %% used to record the convergence 63 | 64 | %% ====================== store the best ================== 65 | [bestold, bes_l]=min(fitx); bestx= x(bes_l,:); 66 | %% ================== fill in for each phase butterfly =================================== 67 | %% DE 68 | EA_1= x(1:PS1,:); EA_obj1= fitx(1:PS1); EA_1old = x(randperm(PS1),:); 69 | %% ES 70 | EA_2= x(PS1+1:size(x,1),:); EA_obj2= fitx(PS1+1:size(x,1)); 71 | %% ================ define CMA-ES parameters ============================== 72 | setting=[];bnd =[]; fitness = []; 73 | [setting]= init_cma_par(setting,EA_2, Par.n, PS2); 74 | 75 | %% ===== prob. of each patrolling and perching 76 | probDE1=1./Par.n_opr .* ones(1,Par.n_opr); 77 | %% ===== prob. of each scout variant 78 | probSC = 1./Par.n_opr .* ones(1,Par.n_opr); 79 | %% ===================== archive data ==================================== 80 | arch_rate=2.6; 81 | archive.NP = arch_rate * PS1; % the maximum size of the archive 82 | archive.pop = zeros(0, Par.n); % the solutions stored in te archive 83 | archive.funvalues = zeros(0, 1); % the function value of the archived solutions 84 | %% ==================== to adapt CR and F ================================= 85 | hist_pos=1; 86 | memory_size=6; 87 | archive_f= ones(1,memory_size).*0.7; 88 | archive_Cr= ones(1,memory_size).*0.5; 89 | archive_T = ones(1,memory_size).*0.1; 90 | archive_freq = ones(1, memory_size).*0.5; 91 | %% 92 | stop_con=0; avgFE=Par.Max_FES; InitPop=PS1; thrshold=1e-08; 93 | 94 | cy=0;indx = 0; Probs=ones(1,2); 95 | 96 | %% main loop 97 | while stop_con==0; 98 | iter=iter+1; 99 | cy=cy+1; % to control CS 100 | % ================ determine the best phase =========================== 101 | if(cy==ceil(Par.CS+1)) 102 | 103 | %%calc normalized qualit -- NQual 104 | qual(1) = EA_obj1(1);qual(2) = EA_obj2(1); 105 | norm_qual = qual./sum(qual); 106 | norm_qual=1-norm_qual; %% to satisfy the bigger is the better 107 | 108 | %%Normalized diversity 109 | D(1) = mean(pdist2(EA_1(2:PS1,:),EA_1(1,:))); 110 | D(2) = mean(pdist2(EA_2(2:PS2,:),EA_2(1,:))); 111 | norm_div= D./sum(D); 112 | 113 | %%Total Imp 114 | Probs=norm_qual+norm_div; 115 | %%Update Prob_MODE and Prob_CMAES 116 | Probs = max(0.1, min(0.9,Probs./sum(Probs))); 117 | 118 | [~,indx]=max(Probs); 119 | if Probs(1)==Probs(2) 120 | indx=0;%% no sharing of information 121 | end 122 | 123 | 124 | elseif cy==2*ceil(Par.CS) 125 | 126 | %% share information 127 | if indx==1 128 | list_ind = randperm(PS1); 129 | list_ind= list_ind(1:(min(PS2,PS1))); 130 | EA_2(1:size(list_ind,2),:)= EA_1(list_ind,:); 131 | EA_obj2(1:size(list_ind,2))= EA_obj1(list_ind); 132 | [setting]= init_cma_par(setting,EA_2, Par.n, PS2); 133 | setting.sigma= setting.sigma*(1- (current_eval/Par.Max_FES)); 134 | else 135 | if (min (EA_2(1,:)))> bounds(1,1) && (max(EA_2(1,:))) UpdPopSize 154 | reduction_ind_num = PS1 - UpdPopSize; 155 | if PS1 - reduction_ind_num < Par.MinPopSize; 156 | reduction_ind_num = PS1 - Par.MinPopSize; 157 | end 158 | %% remove the worst ind. 159 | for r = 1 : reduction_ind_num 160 | vv=PS1; 161 | EA_1(vv,:)=[];EA_1old(vv,:)=[]; 162 | EA_obj1(vv)=[]; 163 | PS1 = PS1 - 1; 164 | end 165 | archive.NP = round(arch_rate * PS1); 166 | if size(archive.pop, 1) > archive.NP 167 | rndpos = randperm(size(archive.pop, 1)); 168 | rndpos = rndpos(1 : archive.NP); 169 | archive.pop = archive.pop(rndpos, :); 170 | end 171 | end 172 | 173 | %% apply EBO 174 | [EA_1, EA_1old, EA_obj1,probDE1,bestold,bestx,archive,hist_pos,memory_size, archive_f,archive_Cr,archive_T,archive_freq, current_eval,res_det] = ... 175 | EBO(fhd, EA_1,EA_1old, EA_obj1,probDE1,bestold,bestx,archive,hist_pos,memory_size, archive_f,archive_Cr,archive_T,.... 176 | archive_freq, Par.xmin, Par.xmax, Par.n, PS1, current_eval, I_fno,res_det,Par.Printing,Par.Max_FES, Par.Gmax, iter, bounds); 177 | end 178 | end 179 | %% ====================== Scout/CMAR phase ====================== 180 | if (current_eval0.75*Par.Max_FES 190 | if rand=Par.Max_FES) 217 | stop_con=1; 218 | end 219 | % if ( (abs (Par.f_optimal - bestold)<= thrshold)) 220 | % stop_con=1; 221 | % bestold=Par.f_optimal; 222 | % avgFE=current_eval; 223 | % end 224 | 225 | %% =============================== Print ============================== 226 | % fprintf('current_eval\t %d fitness\t %d \n', current_eval, abs(Par.f_optimal-bestold)); 227 | 228 | CONV = [CONV, bestold]; 229 | if stop_con 230 | com_time= toc;%cputime-start_time; 231 | % fprintf('run\t %d, fitness\t %d, avg.FFE\t %d\t %d\n', run, abs(Par.f_optimal-bestold),avgFE,indx(1)); 232 | % outcome= abs(Par.f_optimal-bestold); 233 | % if (min (bestx))< -100 || (max(bestx))>100 %% make sure that the best solution is feasible 234 | % fprintf('in problem: %d, there is a violation',I_fno); 235 | % end 236 | % SR= (outcome==0); 237 | CONV = CONV(round(linspace(1,length(CONV),M))); 238 | end 239 | end 240 | 241 | 242 | end 243 | 244 | 245 | 246 | function i = bestt(n,D) 247 | i = zeros(1,n);k = n; 248 | if 2*D > n 249 | D = 1; 250 | n = max(round(0.1*n),2); 251 | end 252 | for j = 1:k 253 | i(j) = min(randperm(n,D)); 254 | end 255 | end 256 | 257 | 258 | 259 | 260 | 261 | function [x, xold, fitx,prob,bestold,bestx,archive,hist_pos,memory_size, archive_f,archive_Cr,archive_T,archive_freq,current_eval,res_det ] = ... 262 | EBO(fhd, x,xold, fitx,prob,bestold,bestx,archive,hist_pos,memory_size, archive_f,archive_Cr,archive_T,archive_freq, xmin, xmax, n,... 263 | PopSize, current_eval, I_fno,res_det,Printing,Max_FES, G_Max, gg, constraints) 264 | 265 | 266 | vi=zeros(PopSize,n); 267 | 268 | %% calc CR and F 269 | mem_rand_index = ceil(memory_size * rand(PopSize, 1)); 270 | mu_sf = archive_f(mem_rand_index); 271 | mu_cr = archive_Cr(mem_rand_index); 272 | mu_T = archive_T(mem_rand_index); 273 | mu_freq = archive_freq(mem_rand_index); 274 | %% ========================= generate CR ================================== 275 | cr = (mu_cr + 0.1*sqrt(pi)*(asin(-rand(1,PopSize))+asin(rand(1,PopSize))))'; 276 | cr(mu_cr == -1) = 0; 277 | cr = min(cr, 1); 278 | cr = max(cr, 0); 279 | 280 | 281 | %% ========================= generate F =================================== 282 | F = mu_sf + 0.1 * tan(pi * (rand( 1,PopSize) - 0.5)); 283 | pos = find(F <= 0); 284 | while ~ isempty(pos) 285 | F(pos) = mu_sf(pos) + 0.1 * tan(pi * (rand( 1,length(pos)) - 0.5)); 286 | pos = find(F <= 0); 287 | end 288 | F = min(F, 1)'; 289 | 290 | %% ========================= generate T =================================== 291 | T = mu_T + 0.05*(sqrt(pi)*(asin(-rand(1, PopSize))+asin(rand(1, PopSize)))); 292 | T = max(T,0)'; T = min(T,0.5)'; 293 | l = floor(n*rand(1,PopSize))+1; 294 | CR = []; 295 | if n == 1 296 | CR = cr; 297 | else 298 | for i = 1:PopSize 299 | if rem(n,2) == 0 300 | mm = exp(-T(i)/n*(0:n/2-1)); 301 | ll = cr(i).*[mm fliplr(mm)]; 302 | CR(i,[l(i):n (1:l(i)-1)]) =ll; 303 | else 304 | mm = exp(-T(i)/n*(0:floor(n/2-1))); 305 | mm1 = exp(-T(i)/n*floor(n/2)); 306 | ll = cr(i).*[mm mm1 fliplr(mm)]; 307 | CR(i,[l(i):n (1:l(i)-1)]) =ll; 308 | end 309 | end 310 | end 311 | 312 | %% ========================= genrate freq ================================= 313 | freq = mu_freq + 0.1 * tan(pi*(rand(1, PopSize) - 0.5)); 314 | pos_f = find(freq <=0); 315 | while ~ isempty(pos_f) 316 | freq(pos_f) = mu_freq(pos_f) + 0.1 * tan(pi * (rand(1,length(pos_f)) - 0.5)); 317 | pos_f = find(freq <= 0); 318 | end 319 | freq = min(freq, 1)'; 320 | if(current_eval <= Max_FES/2) 321 | c=rand; 322 | if(c<0.5) 323 | F = 0.5.*( tan(2.*pi.*0.5.*gg+pi) .* ((G_Max-gg)/G_Max) + 1 ) .* ones(PopSize,1); 324 | else 325 | F = 0.5 *( tan(2*pi .* freq(:, ones(1, 1)) .* gg) .* (gg/G_Max) + 1 ) .* ones(PopSize, 1); 326 | end 327 | end 328 | 329 | %% ======================== generate new x ================================= 330 | popAll = [x;archive.pop]; %% set archive 331 | r0 = 1 : PopSize; 332 | %% generate random integer numbers 333 | [r1, r2,r3] = gnR1R2(PopSize, size(popAll, 1), r0); 334 | 335 | %% mutation 336 | bb= rand(PopSize, 1); 337 | probiter = prob(1,:); 338 | l2= sum(prob(1:2)); 339 | op_1 = bb <= probiter(1)*ones(PopSize, 1); 340 | op_2 = bb > probiter(1)*ones(PopSize, 1) & bb <= (l2*ones(PopSize, 1)) ; 341 | 342 | 343 | 344 | pNP = max(round(0.1 * PopSize), 2); %% choose at least two best solutions 345 | randindex = ceil(rand(1, PopSize) .* pNP); %% select from [1, 2, 3, ..., pNP] 346 | randindex = max(1, randindex); %% to avoid the problem that rand = 0 and thus ceil(rand) = 0 347 | randindex = bestt(PopSize,n); 348 | phix = x(randindex, :); 349 | %% crisscross modification 350 | 351 | vi(op_1==1,:) = x(op_1==1,:)+ F(op_1==1, ones(1, n)) .*(x(r1(op_1==1),:) - x(op_1==1,:) + x(r3(op_1==1), :) - popAll(r2(op_1==1), :)); 352 | 353 | %% towards-best modification 354 | vi(op_2==1,:) = x(op_2==1,:)+ F(op_2==1, ones(1, n)) .*(phix(op_2==1,:) - x(op_2==1,:) + x(r1(op_2==1), :) - x(r3(op_2==1), :));%+w.*( x(op_2==1,:)- xold(op_2==1,:)); 355 | 356 | 357 | 358 | %% handle boundaries 359 | vi = han_boun(vi, xmax, xmin, x,PopSize,1); 360 | %% crossover 361 | mask = rand(PopSize, n) > CR; 362 | % mask = rand(PopSize, n) > cr(:, ones(1, n)); % mask is used to indicate which elements of ui comes from the parent 363 | % mask = expo_mex(PopSize,n,cr,T); 364 | rows = (1 : PopSize)'; cols = floor(rand(PopSize, 1) * n)+1; % choose one position where the element of ui doesn't come from the parent 365 | jrand = sub2ind([PopSize n], rows, cols); mask(jrand) = false; 366 | ui = vi; ui(mask) = x(mask); 367 | % ui = x; ui(mask) = vi(mask); 368 | %% evaluate 369 | fitx_new = []; 370 | for brojac = 1:size(ui,1) 371 | fitx_new(brojac) = fhd(ui(brojac,:)); 372 | end 373 | %fitx_new = cec17_func(ui',I_fno); 374 | %% update FITNESS EVALUATIONS 375 | current_eval =current_eval+PopSize; 376 | 377 | %% calc. imprv. for Cr and F 378 | diff = abs(fitx - fitx_new); 379 | I =(fitx_new < fitx); 380 | goodCR = cr(I == 1); 381 | goodF = F(I == 1); 382 | goodT = T(I == 1)'; 383 | goodFreq = freq(I == 1); 384 | 385 | %% ========================= update archive =============================== 386 | archive = updateArchive(archive, x(I == 1, :), fitx(I == 1)'); 387 | %% ==================== update Prob. of each DE =========================== 388 | diff2 = max(0,(fitx - fitx_new))./abs(fitx); 389 | count_S(1)=max(0,mean(diff2(op_1==1))); 390 | count_S(2)=max(0,mean(diff2(op_2==1))); 391 | % count_S(3)=max(0,mean(diff2(op_3==1))); 392 | 393 | %% update probs. 394 | %%% Althouth count_S~=0 may slow down the convergence, it gives more 395 | %%% diversity. In case you look for a better convergence you can set it to 396 | %%% sum(count_S)~=0 397 | if count_S~=0 398 | prob= max(0.1,min(0.9,count_S./(sum(count_S)))); 399 | else 400 | prob=1/2 * ones(1,2); 401 | end 402 | %% ==================== update x and fitx ================================= 403 | fitx(I==1)= fitx_new(I==1); xold(I == 1, :) = x(I == 1, :); 404 | x(I == 1, :) = ui(I == 1, :); 405 | %% =================== update memory cr and F ============================= 406 | num_success_params = numel(goodCR); 407 | if num_success_params > 0 408 | weightsDE = diff(I == 1)./ sum(diff(I == 1)); 409 | %% for updating the memory of scaling factor 410 | archive_f(hist_pos) = (weightsDE * (goodF .^ 2))./ (weightsDE * goodF); 411 | 412 | %% for updating the memory of crossover rate 413 | if max(goodCR) == 0 || archive_Cr(hist_pos) == -1 414 | archive_Cr(hist_pos) = -1; 415 | else 416 | archive_Cr(hist_pos) = (weightsDE * (goodCR .^ 2)) / (weightsDE * goodCR); 417 | end 418 | 419 | hist_pos= hist_pos+1; 420 | if hist_pos > memory_size; hist_pos = 1; end 421 | 422 | %% for updating the memory of T 423 | archive_T(hist_pos) = (weightsDE * (goodT .^ 2)) ./ (weightsDE * goodT); 424 | 425 | %% for updating the memory of freq 426 | if max(goodFreq) == 0 || archive_freq(hist_pos) == -1 427 | archive_freq(hist_pos) = -1; 428 | else 429 | archive_freq(hist_pos) = (weightsDE * (goodFreq .^ 2)) / (weightsDE * goodFreq); 430 | end 431 | end 432 | 433 | %% sort new x, fitness 434 | [fitx, ind]=sort(fitx); 435 | x=x(ind,:);xold = xold(ind,:); 436 | 437 | %% record the best value after checking its feasiblity status 438 | if fitx(1)=constraints(1,1) && max(x(ind(1),:))<=constraints(1,2) 439 | bestold=fitx(1); 440 | bestx= x(1,:); 441 | end 442 | %% check to print 443 | if Printing==1 444 | res_det= [res_det repmat(bestold,1,PopSize)]; 445 | end 446 | 447 | end 448 | 449 | 450 | 451 | 452 | 453 | function [r1, r2,r3] = gnR1R2(NP1, NP2, r0) 454 | 455 | % gnA1A2 generate two column vectors r1 and r2 of size NP1 & NP2, respectively 456 | % r1's elements are choosen from {1, 2, ..., NP1} & r1(i) ~= r0(i) 457 | % r2's elements are choosen from {1, 2, ..., NP2} & r2(i) ~= r1(i) & r2(i) ~= r0(i) 458 | % 459 | % Call: 460 | % [r1 r2 ...] = gnA1A2(NP1) % r0 is set to be (1:NP1)' 461 | % [r1 r2 ...] = gnA1A2(NP1, r0) % r0 should be of length NP1 462 | % 463 | % Version: 2.1 Date: 2008/07/01 464 | % Written by Jingqiao Zhang (jingqiao@gmail.com) 465 | 466 | NP0 = length(r0); 467 | 468 | r1 = floor(rand(1, NP0) * NP1) + 1; 469 | % r1 = randperm(NP1,NP0); 470 | 471 | %for i = 1 : inf 472 | for i = 1 : 99999999 473 | pos = (r1 == r0); 474 | if sum(pos) == 0 475 | break; 476 | else % regenerate r1 if it is equal to r0 477 | r1(pos) = floor(rand(1, sum(pos)) * NP1) + 1; 478 | end 479 | if i > 1000, % this has never happened so far 480 | error('Can not genrate r1 in 1000 iterations'); 481 | end 482 | end 483 | 484 | r2 = floor(rand(1, NP0) * NP2) + 1; 485 | %for i = 1 : inf 486 | for i = 1 : 99999999 487 | pos = ((r2 == r1) | (r2 == r0)); 488 | if sum(pos)==0 489 | break; 490 | else % regenerate r2 if it is equal to r0 or r1 491 | r2(pos) = floor(rand(1, sum(pos)) * NP2) + 1; 492 | end 493 | if i > 1000, % this has never happened so far 494 | error('Can not genrate r2 in 1000 iterations'); 495 | end 496 | end 497 | 498 | r3= floor(rand(1, NP0) * NP1) + 1; 499 | %for i = 1 : inf 500 | for i = 1 : 99999999 501 | pos = ((r3 == r0) | (r3 == r1) | (r3==r2)); 502 | if sum(pos)==0 503 | break; 504 | else % regenerate r2 if it is equal to r0 or r1 505 | r3(pos) = floor(rand(1, sum(pos)) * NP1) + 1; 506 | end 507 | if i > 1000, % this has never happened so far 508 | error('Can not genrate r2 in 1000 iterations'); 509 | end 510 | end 511 | end 512 | 513 | 514 | 515 | 516 | %% ============EBOwithCMAR============ 517 | % This code is taken from UMOEA-II 518 | % ========================================================================= 519 | 520 | function x = han_boun (x, xmax, xmin, x2, PopSize,hb) 521 | 522 | switch hb; 523 | case 1 % for DE 524 | x_L = repmat(xmin, PopSize, 1); 525 | pos = x < x_L; 526 | x(pos) = (x2(pos) + x_L(pos)) / 2; 527 | 528 | x_U = repmat(xmax, PopSize, 1); 529 | pos = x > x_U; 530 | x(pos) = (x2(pos) + x_U(pos)) / 2; 531 | 532 | case 2 % for CMA-ES 533 | x_L = repmat(xmin, PopSize, 1); 534 | pos = x < x_L; 535 | x_U = repmat(xmax, PopSize, 1); 536 | x(pos) = min(x_U(pos),max(x_L(pos),2*x_L(pos)-x2(pos))) ; 537 | pos = x > x_U; 538 | x(pos) = max(x_L(pos),min(x_U(pos),2*x_L(pos)-x2(pos))); 539 | 540 | end 541 | end 542 | 543 | 544 | 545 | 546 | 547 | 548 | function [setting]= init_cma_par(setting, EA_2, n, n2) 549 | %% So, mean(EA_2) does not violate the initialization condition in the competition 550 | setting.xmean = mean(EA_2); 551 | setting.xmean=setting.xmean'; 552 | setting.insigma=0.3; 553 | setting.sigma = setting.insigma; 554 | 555 | 556 | setting.sigma = max(setting.insigma); % overall standard deviation 557 | setting.pc = zeros(n,1); setting.ps = zeros(n,1); % evolution paths for setting.C and setting.sigma 558 | 559 | if length(setting.insigma) == 1 560 | setting.insigma = setting.insigma * ones(n,1) ; 561 | end 562 | setting.diagD = setting.insigma/max(setting.insigma); % diagonal matrix D defines the scaling 563 | setting.diagC = setting.diagD.^2; 564 | setting.B = eye(n,n); % setting.B defines the coordinate system 565 | setting.BD = setting.B.*repmat(setting.diagD',n,1); % setting.B*D for speed up only 566 | setting.C = diag(setting.diagC); % covariance matrix == setting.BD*(setting.BD)' 567 | setting.D = ones(n,1); 568 | setting.chiN=n^0.5*(1-1/(4*n)+1/(21*n^2)); % expectation of 569 | setting.mu = ceil(n2/2); % number of parents/points for recombination 570 | % setting.mu = n2; 571 | setting.weights = log(max(setting.mu, n/2) + 1/2)-log(1:setting.mu)'; % muXone array for weighted recombination setting.mu = floor(setting.mu); 572 | setting.mueff=sum(setting.weights)^2/sum(setting.weights.^2); % variance-effective size of setting.mu 573 | setting.weights = setting.weights/sum(setting.weights); % normalize recombination setting.weights array 574 | 575 | % Strategy parameter setting: Adaptation 576 | setting.cc = (4 + setting.mueff/n) / (n+4 + 2*setting.mueff/n); % time constant for cumulation for setting.C 577 | setting.cs = (setting.mueff+2) / (n+setting.mueff+3); % t-const for cumulation for setting.sigma control 578 | setting.ccov1 = 2 / ((n+1.3)^2+setting.mueff); % learning rate for rank-one update of setting.C 579 | setting.ccovmu = 2 * (setting.mueff-2+1/setting.mueff) / ((n+2)^2+setting.mueff); % and for rank-setting.mu update 580 | setting.damps = 0.5 + 0.5*min(1, (0.27*n2/setting.mueff-1)^2) + 2*max(0,sqrt((setting.mueff-1)/(n+1))-1) + setting.cs; % damping for setting.sigma 581 | 582 | setting.xold = setting.xmean; 583 | end 584 | 585 | 586 | 587 | 588 | 589 | %% ============EBOwithCMAR ============ 590 | % Should you have any queries, please contact 591 | % Mr.Abhishek Kumar 592 | % emailid: abhishek.kumar.eee13@iitbhu.ac.in 593 | % ========================================================================= 594 | function [x,f,current_eval,succ] = LS2 (fhd, bestx,f,Par,current_eval,Max_FES,xmin,xmax) 595 | 596 | 597 | Par.LS_FE=ceil(20.0000e-003*Max_FES ); %% Max FFEs_LS 598 | % Par.LS_FE = 20*Par.n; 599 | options=optimset('Display','off','algorithm','sqp',... 600 | 'UseParallel','never','MaxFunEvals',Par.LS_FE) ; 601 | 602 | [Xsqp, FUN , ~ , details]=fmincon(fhd, bestx(1,:),[],[],[],[],xmin,xmax, [],options); 603 | 604 | %% check if there is an improvement in the fitness value and update P_{ls} 605 | if (f-FUN)>0 606 | succ=1; 607 | f = FUN; 608 | x(1,:)=Xsqp; 609 | else 610 | succ=0; 611 | x=bestx; 612 | 613 | end 614 | %% update FFEs 615 | current_eval=current_eval+details.funcCount; 616 | % details.funcCount 617 | end 618 | 619 | 620 | 621 | 622 | %% Parts of this code were taken from (https://www.lri.fr/~hansen/cmaes_inmatlab.html#matlab). 623 | function[ x, fitx, setting,bestold,bestx,bnd,fitness,current_eval,res_det] = ... 624 | Scout(fhd, x, ~, prob, setting, iter,bestold,bestx,fitness,bnd,xmin,xmax,n,PopSize,current_eval,I_fno,res_det,Printing,Max_FES, constraints) 625 | 626 | % stopOnWarnings=0; 627 | % noiseReevals = 0; 628 | fitness.raw = NaN(1, PopSize);% + noiseReevals); 629 | % fitness.raw(PopSize + find(isnan(fitness.raw(1:noiseReevals)))) = NaN; 630 | 631 | % arz = randn(n,PopSize); 632 | if rand < 1*prob(1) 633 | arz = sqrt(pi)*(asin(rand(n,PopSize))+asin(-rand(n,PopSize))); 634 | else 635 | arz = sqrt(pi)*asin(2*rand(n,PopSize)-1); 636 | end 637 | arx = repmat(setting.xmean, 1, PopSize) + setting.sigma * (setting.BD * arz); 638 | 639 | %% ignore handling the boundaries constraints during the first 50% evolutionary process 640 | %%-this is based on our earlier analysis carried out on UMOEAs in 2014. 641 | handle_limit=0.5; 642 | if current_eval >=handle_limit*Max_FES 643 | arxvalid =han_boun(arx', xmax, xmin, x,PopSize,2); 644 | arxvalid=arxvalid'; 645 | else 646 | arxvalid=arx; 647 | end 648 | %% evaluate and update cfe 649 | fitness.raw = []; 650 | for brojac = 1:size(arxvalid,2) 651 | fitness.raw(brojac) = fhd(arxvalid(:,brojac)'); 652 | end 653 | %fitness.raw = cec17_func(arxvalid,I_fno); 654 | current_eval=current_eval+PopSize; %% increase the fitness evaluations 655 | 656 | fitness.sel= fitness.raw ; 657 | [fitness.sel, fitness.idxsel] = sort(fitness.sel); 658 | 659 | fitness.raw= fitness.raw(fitness.idxsel); 660 | arxvalid= arxvalid(:, fitness.idxsel); 661 | arx= arx(:, fitness.idxsel); 662 | arz=arz(:, fitness.idxsel); 663 | [~,pos_ro]=min(fitness.raw); 664 | 665 | %% record the best value after checking its feasiblity status 666 | if fitness.raw(pos_ro) < bestold && (min(arxvalid(:,pos_ro)))>=constraints(1,1) && (max(arxvalid(:,pos_ro)))<=constraints(1,2) 667 | bestold=fitness.raw(pos_ro); 668 | bestx= arxvalid(:,pos_ro)'; 669 | end 670 | if Printing==1 671 | res_det= [res_det repmat(bestold,1,PopSize)]; 672 | end 673 | 674 | %% setting.weights 675 | setting.weights = fitness.raw(1:setting.mu)';%./sum(fitness.raw(1:setting.mu)); 676 | if sum(setting.weights)>1e25 677 | setting.weights = 1/setting.mu*ones(setting.mu,1); 678 | end 679 | setting.weights = setting.weights/sum(setting.weights); % normalize recombination setting.weights array 680 | setting.weights = fliplr(setting.weights); 681 | % Calculate new setting.xmean, this is selection and recombination 682 | setting.xold = setting.xmean; % for speed up of Eq. (2) and (3) 683 | cmean =1;% 1/min(max((PopSize-1*n)/2, 1), n); % == 1/kappa 684 | setting.xmean = (1-cmean) * setting.xold + cmean * arx(:,(1:setting.mu))*setting.weights; 685 | if current_eval >=handle_limit*Max_FES 686 | % setting.xmean = xintobounds(setting.xmean, xmin', xmax'); 687 | setting.xmean =han_boun(setting.xmean', xmax, xmin, x(1,:),1,2); 688 | setting.xmean=setting.xmean'; 689 | end 690 | zmean = arz(:,(1:setting.mu))*setting.weights;%==D^-1*setting.B'*(setting.xmean-setting.xold)/setting.sigma 691 | % Cumulation: update evolution paths 692 | setting.ps = (1-setting.cs)*setting.ps + sqrt(setting.cs*(2-setting.cs)*setting.mueff) * (setting.B*zmean); % Eq. (4) 693 | hsig = norm(setting.ps)/sqrt(1-(1-setting.cs)^(2*iter))/setting.chiN < 1.4 + 2/(n+1); 694 | 695 | setting.pc = (1-setting.cc)*setting.pc ... 696 | + hsig*(sqrt(setting.cc*(2-setting.cc)*setting.mueff)/setting.sigma/cmean) * (setting.xmean-setting.xold); % Eq. (2) 697 | % if hsig == 0 698 | % % disp([num2str(iter) ' ' num2str(counteval) ' setting.pc update stalled']); 699 | % end 700 | % Adapt covariance matrix 701 | neg.ccov = 0; % TODO: move parameter setting upwards at some point 702 | if setting.ccov1 + setting.ccovmu > 0 % Eq. (3) 703 | % if setting.flgDiagonalOnly % internal linear(?) complexity 704 | % setting.diagC = (1-setting.ccov1_sep-setting.ccovmu_sep+(1-hsig)*setting.ccov1_sep*setting.cc*(2-setting.cc)) * setting.diagC ... % regard old matrix 705 | % + setting.ccov1_sep * setting.pc.^2 ... % plus rank one update 706 | % + setting.ccovmu_sep ... % plus rank setting.mu update 707 | % * (setting.diagC .* (arz(:,(1:setting.mu)).^2 * setting.weights)); 708 | % % * (repmat(setting.diagC,1,setting.mu) .* arz(:,(1:setting.mu)).^2 * setting.weights); 709 | % setting.diagD = sqrt(setting.diagC); % replaces eig(setting.C) 710 | % else 711 | arpos = (arx(:,(1:setting.mu))-repmat(setting.xold,1,setting.mu)) / setting.sigma; 712 | setting.C = (1-setting.ccov1-setting.ccovmu) * setting.C ... % regard old matrix 713 | + setting.ccov1 * setting.pc*setting.pc' ... % plus rank one update 714 | + setting.ccovmu ... % plus rank setting.mu update 715 | * arpos * (repmat(setting.weights,1,n) .* arpos'); 716 | % is now O(setting.mu*n^2 + setting.mu*n), was O(setting.mu*n^2 + setting.mu^2*n) when using diag(setting.weights) 717 | % for setting.mu=30*n it is now 10 times faster, overall 3 times faster 718 | 719 | setting.diagC = diag(setting.C); 720 | % end 721 | end 722 | 723 | 724 | % Adapt setting.sigma 725 | setting.sigma = setting.sigma * exp(min(1, (sqrt(sum(setting.ps.^2))/setting.chiN - 1) * setting.cs/setting.damps)); % Eq. (5) 726 | % disp([iter norm(setting.ps)/setting.chiN]); 727 | 728 | % if 11 < 3 % testing with optimal step-size 729 | % setting.sigma = 0.04 * setting.mueff * sqrt(sum(setting.xmean.^2)) / n; % 20D,lam=1000:25e3 730 | % setting.sigma = 0.3 * setting.mueff * sqrt(sum(setting.xmean.^2)) / n; % 20D,lam=(40,1000):17e3 731 | % % 75e3 with def (1.5) 732 | % % 35e3 with setting.damps=0.25 733 | % end 734 | % if 11 < 3 735 | % 736 | % setting.xmean = ones(n,1); 737 | % end 738 | 739 | % Update setting.B and D from setting.C 740 | 741 | if (setting.ccov1+setting.ccovmu+neg.ccov) > 0 && mod(iter, 1/(setting.ccov1+setting.ccovmu+neg.ccov)/n/10) < 1 742 | setting.C=triu(setting.C)+triu(setting.C,1)'; % enforce symmetry to prevent complex numbers 743 | [setting.B,tmp] = eig(setting.C); % eigen decomposition, setting.B==normalized eigenvectors 744 | % effort: approx. 15*n matrix-vector multiplications 745 | setting.diagD = diag(tmp); 746 | 747 | % limit condition of setting.C to 1e14 + 1 748 | if min(setting.diagD) <= 0 749 | 750 | setting.diagD(setting.diagD<0) = 0; 751 | tmp = max(setting.diagD)/1e14; 752 | setting.C = setting.C + tmp*eye(n,n); setting.diagD = setting.diagD + tmp*ones(n,1); 753 | 754 | end 755 | if max(setting.diagD) > 1e14*min(setting.diagD) 756 | 757 | tmp = max(setting.diagD)/1e14 - min(setting.diagD); 758 | setting.C = setting.C + tmp*eye(n,n); setting.diagD = setting.diagD + tmp*ones(n,1); 759 | 760 | end 761 | 762 | setting.diagC = diag(setting.C); 763 | setting.diagD = sqrt(setting.diagD); % D contains standard deviations now 764 | % setting.diagD = setting.diagD / prod(setting.diagD)^(1/n); setting.C = setting.C / prod(setting.diagD)^(2/n); 765 | setting.BD = setting.B.*repmat(setting.diagD',n,1); % O(n^2) 766 | end % if mod 767 | 768 | % Align/rescale order of magnitude of scales of setting.sigma and setting.C for nicer output 769 | % TODO: interference with sigmafacup: replace 1e10 with 2*sigmafacup 770 | % not a very usual case 771 | % if 1 < 2 && setting.sigma > 1e10*max(setting.diagD) && setting.sigma > 8e14 * max(setting.insigma) 772 | % fac = setting.sigma; % / max(setting.diagD); 773 | % setting.sigma = setting.sigma/fac; 774 | % setting.pc = fac * setting.pc; 775 | % setting.diagD = fac * setting.diagD; 776 | % % if ~setting.flgDiagonalOnly 777 | % setting.C = fac^2 * setting.C; % disp(fac); 778 | % setting.BD = setting.B .* repmat(setting.diagD',n,1); % O(n^2), but repmat might be inefficient todo? 779 | % % end 780 | % setting.diagC = fac^2 * setting.diagC; 781 | % end 782 | % 783 | % % if setting.flgDiagonalOnly > 1 && iter > setting.flgDiagonalOnly 784 | % % % full covariance matrix from now on 785 | % % setting.flgDiagonalOnly = 0; 786 | % % setting.B = eye(n,n); 787 | % % setting.BD = diag(setting.diagD); 788 | % % setting.C = diag(setting.diagC); % is better, because correlations are spurious anyway 789 | % % end 790 | % 791 | % % ----- numerical error management ----- 792 | % % Adjust maximal coordinate axis deviations 793 | % % if any(setting.sigma*sqrt(setting.diagC) > setting.maxdx') 794 | % % setting.sigma = min(setting.maxdx ./ sqrt(setting.diagC')); 795 | % % %warning(['Iteration ' num2str(iter) ': coordinate axis std ' ... 796 | % % % 'deviation at upper limit of ' num2str(setting.maxdx)]); 797 | % % % stopflag(end+1) = {'maxcoorddev'}; 798 | % % end 799 | % % % Adjust minimal coordinate axis deviations 800 | % % if any(setting.sigma*sqrt(setting.diagC) < setting.mindx) 801 | % % setting.sigma = max(setting.mindx ./ sqrt(setting.diagC)) * exp(0.05+setting.cs/setting.damps); 802 | % % %warning(['Iteration ' num2str(iter) ': coordinate axis std ' ... 803 | % % % 'deviation at lower limit of ' num2str(setting.mindx)]); 804 | % % % stopflag(end+1) = {'mincoorddev'};; 805 | % % end 806 | % % Adjust too low coordinate axis deviations 807 | % if any(setting.xmean == setting.xmean + 0.2*setting.sigma*sqrt(setting.diagC)) 808 | % % if stopOnWarnings 809 | % % % stopflag(end+1) = {'warnnoeffectcoord'}; 810 | % % else 811 | % % % warning(['Iteration ' num2str(iter) ': coordinate axis std ' ... 812 | % % 'deviation too low' ]); 813 | % % if setting.flgDiagonalOnly 814 | % % setting.diagC = setting.diagC + (setting.ccov1_sep+setting.ccovmu_sep) * (setting.diagC .* ... 815 | % % (setting.xmean == setting.xmean + 0.2*setting.sigma*sqrt(setting.diagC))); 816 | % % else 817 | % setting.C = setting.C + (setting.ccov1+setting.ccovmu) * diag(setting.diagC .* ... 818 | % (setting.xmean == setting.xmean + 0.2*setting.sigma*sqrt(setting.diagC))); 819 | % % end 820 | % setting.sigma = setting.sigma * exp(0.05+setting.cs/setting.damps); 821 | % % end 822 | % end 823 | % % Adjust step size in case of (numerical) precision problem 824 | % % if setting.flgDiagonalOnly 825 | % % tmp = 0.1*setting.sigma*setting.diagD; 826 | % % else 827 | % tmp = 0.1*setting.sigma*setting.BD(:,1+floor(mod(iter,n))); 828 | % % end 829 | % if all(setting.xmean == setting.xmean + tmp) 830 | % % ii = 1+floor(mod(iter,n)); 831 | % % if stopOnWarnings 832 | % % else 833 | % setting.sigma = setting.sigma * exp(0.2+setting.cs/setting.damps); 834 | % % end 835 | % end 836 | % % Adjust step size in case of equal function values (flat fitness) 837 | % % isequalfuncvalues = 0; 838 | % % if fitness.sel(1) == fitness.sel(1+ceil(0.1+PopSize/4)) 839 | % % % isequalfuncvalues = 1; 840 | % % if setting.stopOnEqualFunctionValues 841 | % % setting.arrEqualFunvals = [iter setting.arrEqualFunvals(1:end-1)]; 842 | % % % stop if this happens in more than 33% 843 | % % if setting.arrEqualFunvals(end) > iter - 3 * length(setting.arrEqualFunvals) 844 | % % % stopflag(end+1) = {'equalfunvals'}; 845 | % % end 846 | % % else 847 | % % if flgWarnOnEqualFunctionValues 848 | % % % warning(['Iteration ' num2str(iter) ... 849 | % % % ': equal function values f=' num2str(fitness.sel(1)) ... 850 | % % % ' at maximal main axis setting.sigma ' ... 851 | % % % num2str(setting.sigma*max(setting.diagD))]); 852 | % % end 853 | % % setting.sigma = setting.sigma * exp(0.2+setting.cs/setting.damps); 854 | % % end 855 | % % end 856 | % % % Adjust step size in case of equal function values 857 | % % if iter > 2 && myrange([fitness.hist fitness.sel(1)]) == 0 858 | % % if stopOnWarnings 859 | % % % stopflag(end+1) = {'warnequalfunvalhist'}; 860 | % % else 861 | % % % warning(['Iteration ' num2str(iter) ... 862 | % % % ': equal function values in history at maximal main ' ... 863 | % % % 'axis setting.sigma ' num2str(setting.sigma*max(setting.diagD))]); 864 | % % setting.sigma = setting.sigma * exp(0.2+setting.cs/setting.damps); 865 | % % end 866 | % % end 867 | 868 | %% print out final results 869 | x= arxvalid'; 870 | fitx= fitness.raw; 871 | 872 | % function res=myrange(x) 873 | % res = max(x) - min(x); 874 | 875 | 876 | 877 | end 878 | 879 | 880 | 881 | 882 | function archive = updateArchive(archive, pop, funvalue) 883 | % Update the archive with input solutions 884 | % Step 1: Add new solution to the archive 885 | % Step 2: Remove duplicate elements 886 | % Step 3: If necessary, randomly remove some solutions to maintain the archive size 887 | % 888 | % Version: 1.1 Date: 2008/04/02 889 | % Written by Jingqiao Zhang (jingqiao@gmail.com) 890 | 891 | if archive.NP == 0, return; end 892 | 893 | if size(pop, 1) ~= size(funvalue,1), error('check it'); end 894 | 895 | % Method 2: Remove duplicate elements 896 | popAll = [archive.pop; pop ]; 897 | funvalues = [archive.funvalues; funvalue ]; 898 | [dummy IX]= unique(popAll, 'rows'); 899 | if length(IX) < size(popAll, 1) % There exist some duplicate solutions 900 | popAll = popAll(IX, :); 901 | funvalues = funvalues(IX, :); 902 | end 903 | 904 | if size(popAll, 1) <= archive.NP % add all new individuals 905 | archive.pop = popAll; 906 | archive.funvalues = funvalues; 907 | else % randomly remove some solutions 908 | rndpos = randperm(size(popAll, 1)); % equivelent to "randperm"; 909 | rndpos = rndpos(1 : archive.NP); 910 | 911 | archive.pop = popAll (rndpos, :); 912 | archive.funvalues = funvalues(rndpos, :); 913 | end 914 | end 915 | 916 | 917 | 918 | --------------------------------------------------------------------------------