%%______________________________________________________________________________________________________________________________________________________%
%% Main: Used to test and benchmark the proposed SASMA (Surrogate Assisted Slime Mould Algorithm) by Pedro Bento November 2023 -UBI, Covilha Portugal
% Note: To remove algorithms from the simulation comment them! 
% Researcher: https://www.researchgate.net/profile/Pmr-Bento-2 
% When using please cite and refer this code and its author!
%%______________________________________________________________________________________________________________________________________________________% 
clear all
close all
clc
%______________________________________________________________________%
% Parpool settings
myPool=parpool('local',7);
%______________________________________________________________________%
%% This script will implement the test conditions of the paper
tic
% "Improved surrogate-assisted whale optimization algorithm for fractional chaotic systems parameters identification (Engineering Applications of Artificial Intelligence 2022)"
% ---- Parameters ---- %
num_testfunctions=13+1+3; % 7 Unimodais + 6 Multimodais + 1 added normal Ellipsoid unimodal (from the updated Get_Functions_details3.m) + 3 Rotated (F10, F16 e F19 from cec2005_benchmark_func.m)
SearchAgents_no=30 %population size
dim=30 % dim=[30,100];
flagoption=1;
if (dim<100 && flagoption) %dim<100 && by the book in terms of stopping criterion (flagoption on!)
    FunctionEvals=330 %330FEs ->11*D
elseif (flagoption) % dim>=100  && by the book in terms of stopping criterion (flagoption on!)
    FunctionEvals=1020 %1000FEs ->10*D
else % flagoption==0 _>personalized number of FEs
    FunctionEvals=5000
end
max_iters=round(FunctionEvals/SearchAgents_no) 
n_runs=5
DB_size=1000;
%______________________________________________________________________%
%% Rotate test functions data and the tested algorithms
% 9 Metaheuristicos (PSO_wInertia, PSO_constriction, WOA, GWO, GSA, FPA, BA, GSK, SMA_orig)
% 6 SAEAs (CALSAPSO, GORS_SSLPSO, SAEA_RFS, SHPSO, TL-SSLPSO, TLSAPSO)
% 1 Proposed SurrAssistedSMAv3_f2_4b_corr7
num_algs2test=9+6+1;
% Init Vars
functions_toTest=1:num_testfunctions;
Best_score_perFunc=cell(length(functions_toTest),1);
Best_pos_perFunc=cell(length(functions_toTest),num_algs2test);
Convergence_curve_perFunc=cell(length(functions_toTest),num_algs2test);
DBsperfunction=cell(length(functions_toTest),1);
time_c_perFunc=cell(length(functions_toTest),1);
mean_errors=zeros(num_testfunctions,num_algs2test);
std_errors=zeros(num_testfunctions,num_algs2test);
% $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ %
% Inic ciclo
for funcs=functions_toTest
    sel_f=strcat('F',num2str(funcs))
    [lb,ub,~,fobj]=Get_Functions_details3(sel_f);
    % Test the swarms with the surrogates with different methodologies
    % Initialize Results Variables
    % - - - - - - - - - - - - - %
    Best_score1=zeros(n_runs,1);
    Best_score2=zeros(n_runs,1);
    Best_score3=zeros(n_runs,1);
    Best_score4=zeros(n_runs,1);
    Best_score5=zeros(n_runs,1);
    Best_score6=zeros(n_runs,1);
    Best_score7=zeros(n_runs,1);
    Best_score8=zeros(n_runs,1);
    Best_score9=zeros(n_runs,1);
    Best_score10=zeros(n_runs,1);
    Best_score11=zeros(n_runs,1);
    Best_score12=zeros(n_runs,1);
    Best_score13=zeros(n_runs,1);
    Best_score14=zeros(n_runs,1);
    Best_score15=zeros(n_runs,1);
    Best_score16=zeros(n_runs,1);
    % - - - - - - - - - - - - - %
    best_pos1=zeros(n_runs,dim);
    best_pos2=zeros(n_runs,dim);
    best_pos3=zeros(n_runs,dim);
    best_pos4=zeros(n_runs,dim);
    best_pos5=zeros(n_runs,dim);
    best_pos6=zeros(n_runs,dim);
    best_pos7=zeros(n_runs,dim);
    best_pos8=zeros(n_runs,dim);
    best_pos9=zeros(n_runs,dim);
    best_pos10=zeros(n_runs,dim);
    best_pos11=zeros(n_runs,dim);
    best_pos12=zeros(n_runs,dim);
    best_pos13=zeros(n_runs,dim);
    best_pos14=zeros(n_runs,dim);
    best_pos15=zeros(n_runs,dim);
    best_pos16=zeros(n_runs,dim);
    % - - - - - - - - - - - - - %
    conv_curve1=zeros(n_runs,max_iters);
    conv_curve2=zeros(n_runs,max_iters);
    conv_curve3=zeros(n_runs,max_iters);
    conv_curve4=zeros(n_runs,max_iters);
    conv_curve5=zeros(n_runs,max_iters);
    conv_curve6=zeros(n_runs,max_iters);
    conv_curve7=zeros(n_runs,max_iters);
    conv_curve8=zeros(n_runs,max_iters);
    conv_curve9=zeros(n_runs,max_iters);
    conv_curve10=zeros(n_runs,FunctionEvals);
    conv_curve11=zeros(n_runs,FunctionEvals);
    conv_curve12=zeros(n_runs,FunctionEvals);
    conv_curve13=zeros(n_runs,FunctionEvals);
    conv_curve14=zeros(n_runs,FunctionEvals);
    conv_curve15=zeros(n_runs,FunctionEvals);
    conv_curve16=zeros(n_runs,FunctionEvals);
    % - - - - - - - - - - - - - %
    time_c1=zeros(n_runs,1);
    time_c2=zeros(n_runs,1);
    time_c3=zeros(n_runs,1);
    time_c4=zeros(n_runs,1);
    time_c5=zeros(n_runs,1);
    time_c6=zeros(n_runs,1);
    time_c7=zeros(n_runs,1);
    time_c8=zeros(n_runs,1);
    time_c9=zeros(n_runs,1);
    time_c10=zeros(n_runs,1);
    time_c11=zeros(n_runs,1);
    time_c12=zeros(n_runs,1);
    time_c13=zeros(n_runs,1);
    time_c14=zeros(n_runs,1);
    time_c15=zeros(n_runs,1);
    time_c16=zeros(n_runs,1);
    % - - - - - - - - - - - - - %
    storeDB16=cell(n_runs,1);
    % - - - - - - - - - - - - - %
    % Initialization (Initial Search Space Positions)
    parfor i=1:n_runs
        % Initialization (Initial Search Space Positions)
        %         Positions=lb+(ub-lb).*rand(SearchAgents_no,dim);
        Positions=lb+(ub-lb).*lhsdesign(SearchAgents_no,dim);
        initial_fitness=zeros(SearchAgents_no,1);
        for j=1:SearchAgents_no
            initial_fitness(j)=feval(fobj,Positions(j,:)); %Function evaluation
        end
        % Call the Evolutionary Population based Algorithms
        %_______________________________________________________________________________________________________%
        %-> 1) PSO com inertia weight modified new random per particle /without surrogate assistance
        % Shared Parameters
        c1=2.05;
        c2=2.05;
        w_inertia=[0.4,0.9]; %w_inertia=[w_min,w_max] & if w_max=w_min=constant ->omega is um valor fixo
        [Best_score1(i),best_pos1(i,:),conv_curve1(i,:),time_c1(i)]=...
            PSO_inertia_mod1(c1,c2,w_inertia,max_iters,SearchAgents_no,lb,ub,dim,fobj,Positions);
        %_______________________________________________________________________________________________________%
        %-> 2) PSO com constriction factor modified new random per particle /without surrogate assistance
        [Best_score2(i),best_pos2(i,:),conv_curve2(i,:),time_c2(i)]=...
            PSO_constricton_mod1(c1,c2,max_iters,SearchAgents_no,lb,ub,dim,fobj,Positions);
        %_______________________________________________________________________________________________________%
        %-> 3) WOA Original
        [Best_score3(i),best_pos3(i,:),conv_curve3(i,:),time_c3(i)]=...
            WOA_orig(SearchAgents_no,max_iters,lb,ub,dim,fobj,Positions);
        %_______________________________________________________________________________________________________%
        %-> 4) GWO corrected for matching the conv curve 
        [Best_score4(i),best_pos4(i,:),conv_curve4(i,:),time_c4(i)]=...
            GWO_orig_corr(SearchAgents_no,max_iters,lb,ub,dim,fobj,Positions,initial_fitness);
        %_______________________________________________________________________________________________________%
        %-> 5) GSA Original
        [Best_score5(i),best_pos5(i,:),conv_curve5(i,:),time_c5(i)]=...
            GSA_orig(SearchAgents_no,max_iters,lb,ub,dim,fobj,Positions);
        %_______________________________________________________________________________________________________%
        %-> 6) FPA corrected for matching the conv curve 
        [Best_score6(i),best_pos6(i,:),conv_curve6(i,:),time_c6(i)]=...
            FPA_orig_corr(SearchAgents_no,max_iters,lb,ub,dim,fobj,Positions,initial_fitness);
        %_______________________________________________________________________________________________________%
        %-> 7) BA corrected for matching the conv curve 
        [Best_score7(i),best_pos7(i,:),conv_curve7(i,:),time_c7(i)]=...
            BA_orig_corr(SearchAgents_no,max_iters,lb,ub,dim,fobj,Positions,initial_fitness);
        %_______________________________________________________________________________________________________%
        %-> 8) GSK corrected for matching the conv curve 
        [Best_score8(i),best_pos8(i,:),conv_curve8(i,:),time_c8(i)]=...
            GSK_orig_corr(SearchAgents_no,max_iters,lb,ub,dim,fobj,Positions,initial_fitness);
        %_______________________________________________________________________________________________________%
        %-> 9) SMA Original /without surrogate assistance
        [Best_score9(i),best_pos9(i,:),conv_curve9(i,:),time_c9(i)]=...
            SMA_origY(SearchAgents_no,max_iters,lb,ub,dim,fobj,Positions);
        %_______________________________________________________________________________________________________%
        %-> 10) CALSAPSO (with original parameters)
        if (dim<=50)
            [Best_score10(i),best_pos10(i,:),conv_curve10(i,:),time_c10(i)]=...
            CALSAPSO_origfPB(lb,ub,FunctionEvals,fobj,Positions,initial_fitness);
        end
        %__________________________________________________________________
        %-> 11) GORS_SSLPSO (with original parameters)
        [Best_score11(i),best_pos11(i,:),conv_curve11(i,:),time_c11(i)]=...
            GORS_SSLPSO_origfPB(lb,ub,FunctionEvals,dim,SearchAgents_no,fobj,Positions,initial_fitness);
        %__________________________________________________________________
        %-> 12) SAEA_RFS (with sligthly tweeked parameters)
        [Best_score12(i),best_pos12(i,:),conv_curve12(i,:),time_c12(i)]=...
            SAEA_RFS_origfPB(lb,ub,dim,SearchAgents_no,FunctionEvals,fobj,Positions,initial_fitness);
        %__________________________________________________________________
        %-> 13) SHPSO (with original parameters)
        [Best_score13(i),best_pos13(i,:),conv_curve13(i,:),time_c13(i)]=...
            SHPSO_origfPB(dim,SearchAgents_no,lb,ub,FunctionEvals,fobj,Positions,initial_fitness);
        %__________________________________________________________________
        %-> 14) TL_SSLPSO (with original parameters)
        [Best_score14(i),best_pos14(i,:),conv_curve14(i,:),time_c14(i)]=...
            TL_SSLPSO_origfPB(lb,ub,FunctionEvals,dim,SearchAgents_no,fobj,Positions,initial_fitness);
        %_______________________________________________________________________________________________________%
        %-> 15) TLSAPSO (with original parameters)
        [Best_score15(i),best_pos15(i,:),conv_curve15(i,:),time_c15(i)]=...
            TLSAPSO_origfPB(SearchAgents_no,dim,FunctionEvals,lb,ub,fobj,Positions,initial_fitness);
        %_______________________________________________________________________________________________________%
        %-> 16) SMA by PB v3_f2_4b (with Xtemp e DB=500, limit of 5*pop_size positions to include in the DB, goal dec 0.1->0.01, subspace alpha_i=0.305+0.01, gama=-0.0015)
        [Best_score16(i),best_pos16(i,:),conv_curve16(i,:),time_c16(i),storeDB16{i}]=...
            SurrAssistedSMAv3_f2_4b_corr7(FunctionEvals,SearchAgents_no,lb,ub,dim,...
            fobj,Positions,initial_fitness,DB_size);
        %_______________________________________________________________________________________________________%
    end
    % Results %
    % - - - - - - - - - - - - - %
    Best_score=[Best_score1,Best_score2,Best_score3,Best_score4,...
        Best_score5,Best_score6,Best_score7,Best_score8,...
        Best_score9,Best_score10,Best_score11,Best_score12,...
        Best_score13,Best_score14,Best_score15,Best_score16];
    Best_score_perFunc{funcs}=Best_score;
    Best_pos_perFunc{funcs,1}=best_pos1;
    Best_pos_perFunc{funcs,2}=best_pos2;
    Best_pos_perFunc{funcs,3}=best_pos3;
    Best_pos_perFunc{funcs,4}=best_pos4;
    Best_pos_perFunc{funcs,5}=best_pos5;
    Best_pos_perFunc{funcs,6}=best_pos6;
    Best_pos_perFunc{funcs,7}=best_pos7;
    Best_pos_perFunc{funcs,8}=best_pos8;
    Best_pos_perFunc{funcs,9}=best_pos9;
    Best_pos_perFunc{funcs,10}=best_pos10;
    Best_pos_perFunc{funcs,11}=best_pos11;
    Best_pos_perFunc{funcs,12}=best_pos12;
    Best_pos_perFunc{funcs,13}=best_pos13;
    Best_pos_perFunc{funcs,14}=best_pos14;
    Best_pos_perFunc{funcs,15}=best_pos15;
    Best_pos_perFunc{funcs,16}=best_pos16;
    Convergence_curve_perFunc{funcs,1}=repelem(conv_curve1,1,SearchAgents_no); %Repeat copies of array elements SearchAgents_no times
    Convergence_curve_perFunc{funcs,2}=repelem(conv_curve2,1,SearchAgents_no); % transforms classic conv_curve(iter)->conv_curve(FEs)
    Convergence_curve_perFunc{funcs,3}=repelem(conv_curve3,1,SearchAgents_no);
    Convergence_curve_perFunc{funcs,4}=repelem(conv_curve4,1,SearchAgents_no);
    Convergence_curve_perFunc{funcs,5}=repelem(conv_curve5,1,SearchAgents_no);
    Convergence_curve_perFunc{funcs,6}=repelem(conv_curve6,1,SearchAgents_no);
    Convergence_curve_perFunc{funcs,7}=repelem(conv_curve7,1,SearchAgents_no);
    Convergence_curve_perFunc{funcs,8}=repelem(conv_curve8,1,SearchAgents_no);
    Convergence_curve_perFunc{funcs,9}=repelem(conv_curve9,1,SearchAgents_no);
    Convergence_curve_perFunc{funcs,10}=conv_curve10;
    Convergence_curve_perFunc{funcs,11}=conv_curve11;
    Convergence_curve_perFunc{funcs,12}=conv_curve12;
    Convergence_curve_perFunc{funcs,13}=conv_curve13;
    Convergence_curve_perFunc{funcs,14}=conv_curve14;
    Convergence_curve_perFunc{funcs,15}=conv_curve15;
    Convergence_curve_perFunc{funcs,16}=conv_curve16;
    time_c_perFunc{funcs}=[time_c1,time_c2,time_c3,time_c4,...
        time_c5,time_c6,time_c7,time_c8,time_c9,time_c10,...
        time_c11,time_c12,time_c13,time_c14,time_c15,...
        time_c16];
    DBsperfunction{funcs}=storeDB16;
    %Results stats for each implementation tested in this function (all the runs)
    mean_errors(funcs,:)=mean(Best_score,1);
    std_errors(funcs,:)=std(Best_score,[],1);
    % - - - - - - - - - - - - - %
end
% - - - - - - - - - - - - - %
save_str=strcat('finalresults_SASMAb_IDBmanag_sz=',num2str(DB_size),'_npop=',num2str(SearchAgents_no),'_SMAv3_surrvf4_corr7_dim=',num2str(dim),'_allFuncs','.mat');
save(save_str,'mean_errors','std_errors','Best_score_perFunc',...
    'Best_pos_perFunc','Convergence_curve_perFunc','time_c_perFunc','DBsperfunction','n_runs','max_iters','dim',...
    'SearchAgents_no','num_testfunctions','num_algs2test')
elapsed_hours=toc/3600
delete(myPool)
%_______________________________________________________________________________________________________________________________%
% by Pedro Bento November 2023
% When using please cite and refer this code and its author!