tic

echo on
clear
%    Informações sobre o arquivo de entrada
methodsNo    = 3;     % Número de métodos
propNo       = 7;     % Número de propriedades
errorRatesNo = 2;     % Número de taxas de erro
patternsNo   = 438;   % Número de padrões
columnsNo = propNo + errorRatesNo * methodsNo;

%   Informações sobre o treinamento (Valores a serem variados em busca da
%   melhor configuração
learnRate = [0.001, 0.01, 0.1];
learnRateCount = 3;

qntHidNeur1 = [3, 4, 5];
qntHidNeurCount1 = 3;

qntHidNeur2 = [2, 3, 4];
qntHidNeurCount2 = 3;

learnAlg = {'traingdm';'trainlm';'trainoss'};
learnAlgCount = 3;

iterationsNo = 1000;

% Informações sobre o experimento
inputNeurNo = 6;
outputNeurNo = 1; 
columnsQnt = inputNeurNo + outputNeurNo;

echo off

%   Normalização
inputFile = fopen('file_6saidas.txt');
data = fscanf(inputFile,'%f',[columnsNo, patternsNo]);

for i = 1 : propNo
    maxValue = max(data(i,:));
    minValue = min(data(i,:));
    for j = 1: patternsNo
        data(i, j) = (data(i, j) - minValue)/(maxValue - minValue);
    end
end

fclose(inputFile);

resultado = fopen('Resultado.txt', 'w+t');

%combos = combntns(1:7,6);
combos = [1, 2, 3, 4, 5, 6; 1, 2, 3, 4, 5, 7; 1, 2, 3, 4, 6, 7; 1, 2, 3, 5, 6, 7; 1, 2, 4, 5, 6, 7; 1, 3, 4, 5, 6, 7; 2, 3, 4, 5, 6, 7];

for i = 1:7
    for o = 1 : 6            
        fprintf('\nTreinando combo %s saída %s\n', int2str(i),int2str(o));
        fprintf('\n');

        patterns = [data(combos(i,:), :); data(o + propNo, :)];

        %   Particionamento dos dados
        trainingPatternsNo = 0.5 * patternsNo;
        validationPatternsNo = 0.25 * patternsNo;
        testPatternsNo = 0.25 * patternsNo;

        trainingPatterns = patterns(1:columnsQnt, 1:trainingPatternsNo);
        trainingInputs = trainingPatterns(1:inputNeurNo, 1:trainingPatternsNo);
        trainingOutputs = trainingPatterns((inputNeurNo + 1):columnsQnt, 1:trainingPatternsNo);

        validationPatterns = patterns(1:columnsQnt, (trainingPatternsNo + 1):(trainingPatternsNo + validationPatternsNo));
        validationInputs = validationPatterns(1:inputNeurNo, 1:validationPatternsNo);
        validationOutputs = validationPatterns((inputNeurNo + 1):columnsQnt, 1:validationPatternsNo);

        testPatterns = patterns(1:columnsQnt, (trainingPatternsNo + validationPatternsNo + 1):patternsNo);
        testInputs = testPatterns(1:inputNeurNo, 1:testPatternsNo);
        testOutputs = testPatterns((inputNeurNo + 1):columnsQnt, 1:testPatternsNo);

        lessErrorTest = 100000;

        for iLR = 1:learnRateCount
            lr = learnRate(iLR);

            for iQHN1 = 1:qntHidNeurCount1
                qhn1 = qntHidNeur1(iQHN1);

                for iQHN2 = 1:qntHidNeurCount2
                    qhn2 = qntHidNeur2(iQHN2);

                    for iLA = 1:learnAlgCount
                        str2 = cellstr(learnAlg);
                        la = char(str2(iLA));

                        info = sprintf('%1.3f\t%d\t%d\t%s', lr, qhn1, qhn2, la);              

                        network = newff(trainingInputs, trainingOutputs, [qhn1, qhn2],{'tansig','tansig'},la,'learngd','mse');

                        % Inicializa os pesos da rede criada
                        network = init(network);

                        %   Parametros do treinamento
                        rede.trainParam.epochs   = iterationsNo;    % Maximo numero de iteracoes
                        rede.trainParam.lr       = lr;              % Taxa de aprendizado
                        rede.trainParam.goal     = 0;               % Criterio de minimo erro de treinamento
                        rede.trainParam.max_fail = 5;               % Criterio de quantidade maxima de falhas na validacao
                        rede.trainParam.min_grad = 0;               % Criterio de gradiente minimo
                        rede.trainParam.show     = NaN;             % Iteracoes entre exibicoes na tela (preenchendo com 'NaN', nao exibe na tela)
                        rede.trainParam.time     = inf;             % Tempo maximo (em segundos) para o treinamento

                        validationSet.P = validationInputs;    % Entradas da validacao
                        validationSet.T = validationOutputs;   % Saidas desejadas da validacao

                        %   Treinando a rede
                        [newNetwork,performance,outputs,errors] = train(network,trainingInputs,trainingOutputs,[],[],validationSet);

                        %    Testando a rede
                        [testOutput,Pf,Af,testErrors,testPerformance] = sim(newNetwork,testInputs,[],[],testOutputs);

                        if testPerformance < lessErrorTest
                            lessErrorTest = testPerformance;
                            bestConfiguration = info;
                        end

                        close all hidden
                    end

                end
            end
        end
        fprintf(resultado, '%s\t%6.10f\n', bestConfiguration, lessErrorTest);
        fprintf('\nMelhor Config Combo %s Saída %s: %s\n', int2str(i), int2str(o), bestConfiguration);
    end
    fclose(resultado);
end
toc
