% DE - Diferencial evolution
clear all; close all; clc; 
backup=true;
if (backup)
    clear all; close all; clc;
    try
        %Absolutni cesta k backup souboru
        % Nacteni adresare
        addpath('../files/');
        run('files/backup.m');
    catch
        disp('Nebylo mozno nacist skript backup.m...');
        disp('Bud neexistuje nebo je zadana spatna cesta...');
        return;
    end
else
    %optimizedFunctionName = 'antenaCST';
    %optimizedFunctionName = 'RosenbrockValley';
    optimizedFunctionName = 'MojeFn';
    additionalParameters = 0;


    %nastaveni vsech peti natavenych predmetu
    bounds(1,:) = [30 70]; %hranice parametru 1 30,70
    bounds(2,:) = [25 55]; %hranice parametru 2 25,55
    bounds(3,:) = [1 12]; %hranice parametru 1 30,70
    bounds(4,:) = [1 2]; %hranice parametru 2 25,55

    %zadany parametr
    findValue = 80;
    %findValue = 1.8e+009;

    % Nastaveni diferencialni evoluce
    D = 4;                  % Pocet dimenzi(parametu)
    NP = 10*D;              % Velikost populace <2D,100D>
    Generations = 100;     % Pocet kol slechteni
    F = 0.8;                % Mutacni konstanta <0,2>
    CR = 0.5;               % Prah krizeni <0,1>
    min = 99e+15;

    % vytvoreni funkce ze stringu
    costFunctionHandle = str2func(optimizedFunctionName);

    % generovani populace
    individuals = zeros(NP,D);
    costValues = zeros(NP,1);

    for i=1:NP

        %vygenerovani nahodnych parametru ( jedincu ) ze zadanych nastavenych hranic
        individuals(i,1)=bounds(1,1)+(bounds(1,2)-bounds(1,1))*rand;
        individuals(i,2)=bounds(2,1)+(bounds(2,2)-bounds(2,1))*rand;
        individuals(i,3)=bounds(3,1)+(bounds(3,2)-bounds(3,1))*rand;
        individuals(i,4)=bounds(4,1)+(bounds(4,2)-bounds(4,1))*rand;

        % vycisleni funkce ze zadanych vygenerovanych parametru ( jedincu )
        costValues(i) = feval(costFunctionHandle,individuals(i,:), additionalParameters);
    end

    % kriterialni funkce
    for i = 1:NP
        costValues(i)=sqrt(((findValue-costValues(i))^2)+((findValue-costValues(i))^2));
    end

    % naalokovani promenych v pameti
    tmpindividuals = zeros(NP,D);
    tmpcostValues = zeros(1,NP);
    globalErrorHistory = zeros(Generations,1);
    l = 1;
end

%--------------------------------------------------------------------------
while (l < Generations)
  
    %evoluce
    for i=1:NP

        % vygenerovani tri nahodnych jedincu z velikosti populace
        podminka = 1;
        while (podminka)
            V1=ceil(NP.*rand(1,1));
            V2=ceil(NP.*rand(1,1));
            V3=ceil(NP.*rand(1,1));
            if (V1==V2 || V1==V3 || V2==V3 || V1==i || V2==i || V3==i)
                podminka = 0;
            else
                podminka = 1;
            end
        end
        
        %vytvoreni diferencniho vektoru pomoci tri nahodne vygenerovanych
        %jedincu podle podminky rand < CR
        for j=1:D
            if (rand < CR)
                tmpindividuals(i,j) = (F * (individuals(V1,j) - individuals(V2,j)) + individuals(V3,j));
            else
                tmpindividuals(i,j) = individuals(i,j);
            end
        end
        
        % kontrola presahnuti nastavenych hranic
            for j=1:D
                if tmpindividuals(i,j)<bounds(j,1)||tmpindividuals(i,j)>bounds(j,2)
                    tmpindividuals(i,j) = bounds(j,1)+(bounds(j,2)-bounds(j,1))*rand; 
                end
            end
            
            % nalezeni hodnoty funkce ze zadanych parametru
            tmpcostValues(i) = feval(costFunctionHandle,tmpindividuals(i,:), additionalParameters);
            
            % vycisleni kriterialni hodnoty ze zadanych vygenerovanych
            % parametru
            tmpcostValues(i) = sqrt(((findValue-tmpcostValues(i))^2)+((findValue-tmpcostValues(i))^2));
            
            % nejlepsi jedinci do nove generace
            % ulozeni lepsi pozice a hodnoty funkce
            if tmpcostValues(1,i)<costValues(i,1)
                costValues(i) = tmpcostValues(:,i);
                individuals(i,:) = tmpindividuals(i,:);
            end
    end

    % nalezeni nejlepsiho jedince ze vsech( jedninec s nejnizsi hodnotou funkce )
    for i = 1:NP
        if costValues(i)<min
            min = costValues(i);
            indexOfBest = i;
        end
    end
    
    % vektor zmen k priblizovani se ke globalnimu minimu
    globalErrorHistory(l) = costValues(indexOfBest);
    
    % vypis do COMMAND WINDOW pocet generaci
    if round(l/10) == l/10
        disp(sprintf('generation = %i of %i',l,Generations));
    end
    l = l + 1;
    
    % Ukladani zaloznich informaci
    val = 0;
    while val ~= 1
        % Nacteni adresare
        addpath('../files/');
        % Otevreni souboru
        fid = fopen('files/backup.m', 'wt');
        val=DEBACKUPFILE(fid,CR,D,F,Generations,NP,V1,V2,V3,additionalParameters,func2str(costFunctionHandle),bounds,costValues,findValue,globalErrorHistory,i,indexOfBest,individuals,j,l,min,optimizedFunctionName,tmpcostValues,tmpindividuals);
        fclose(fid);
    end
    pause;
end 

globalErrorHistory4Saving = zeros(Generations,1);

% ulozeni do souboru
for i=1:Generations
    globalErrorHistory4Saving(i) = globalErrorHistory(i);
end

try
    save c:/tmp_moravec/matlabea/VYSLEDKY/de_history.txt globalErrorHistory4Saving -ASCII -TABS
%     save c:/de_temp/de_history.txt globalErrorHistory4Saving -ASCII -TABS

    temp = costValues(indexOfBest); %/dim;
%     save c:/wqz/prog/matlab/soma_leader_cv.txt temp -ASCII -TABS
    save c:/tmp_moravec/matlabea/VYSLEDKY/de_indexofBest.txt temp -ASCII -TABS

    temp = individuals(indexOfBest,:);
%     save c:/wqz/prog/matlab/soma_leader.txt temp -ASCII -TABS
    save c:/tmp_moravec/matlabea/VYSLEDKY/de_best_position.txt temp -ASCII -TABS
catch
    disp('Varovani! Nastavena cesta k ulozeni DER1B.m je spatne nastavena.');
end
fclose('all');
% vracene hodnoty
retVal.min = min;
retVal.indexOfBest = indexOfBest;
retVal.bestPosition = individuals(indexOfBest,:);
retVal.costVal = feval(costFunctionHandle,individuals(indexOfBest,:), additionalParameters);
retVal.history = globalErrorHistory4Saving;

% vykresleni do grafu
plot(1:length(retVal.history), retVal.history,'b:');

retVal



