function [prediction, index, lastValue, accuracyValue] = generateEnsemble_Opt( actual, hPredictions )
    
    function [ePrediction] = finalHypotesis(prediction)
        class = categories(actual);
        predictedClassCount = countcats(prediction,2);
        [~, I] = max(predictedClassCount,[],2);
        ePrediction = class(I(1:end));
    end
    
    lastValue = 0;
    [~, b] = size(hPredictions);
    index = zeros(1, b);
    accuracyValue = zeros(1, b);    
    %% OPTİMİZASYON
    % Optimizasyon sınırı belirleniyor
    waitCount = 0;
    cycle = log(b);
    
    for i=1 : b
        res = -1;
        t = 0;
        for j=1 : b
            if (sum(index == j) > 0)
                continue;
            end
            t = t + 1;
            prediction = finalHypotesis([hPredictions(:, index(1:(i-1))) hPredictions(:, j)]);
            acc =  sum(prediction == actual);
            if (res < acc)
                res = acc;
                accuracyValue(i) = acc;
                index(i) = j;
            end
        end
        lastValue = lastValue + t;
        
        %% OPTİMİZASYON
        % Optimizasyon Kodları
        if (max(accuracyValue) > accuracyValue(i))
            waitCount = waitCount + 1;
            if (waitCount > cycle)
                break;
            end
        else
            waitCount = 0;
        end
    end
    
    [~, ind] = max(accuracyValue);
    index = index(1:ind);
    prediction = categorical(finalHypotesis(hPredictions(:, index)));
end