function [Wmin,Error,ErrorMin]=mlpEP(netp,X,d,Xv,dv,Xt,dt);

%
% Evolutionary Programing for training MLP-NNs (Porto-Fogel Approach).
%
% Inputs:    netp - A vector [m,n], where m is the number of hidden units and n is the number of output units;  
%               X - Training samples. Each pattern is a column of X;
%               d - Target or Desired System output (row vector);
% (Optional):  Xv - Validation set;
%              dv - Validation Target;
%              Xt - Input test samples;
%              dt - Target test;
%
% Output: W - Cell with the synaptic weight vectors;
%     Error - Vector with the MSE by epoch;
%

[N,K]=size(X);

J=netp(1); L=netp(2); 
if length(netp)>2
  itmax=netp(3);
else
  itmax=10*K;
end 
clear netp;

% Population Size...
mu=50;
lambda=1;

% Initialization;
for i=1:mu
  W{i,1}=(3/sqrt(N+1))*(2*rand(J,N+1)-1);
  W{i,2}=(3/sqrt(J+1))*(2*rand(L,J+1)-1);
end

Kv=0; Kt=0;
ErrorMin=inf;
if nargin>3
  X=[X,Xv];
  Kv=size(Xv,2);
  clear Xv;
  ErrorMin=ones(2,1)*inf;
  if nargin>5
    X=[X,Xt];
    Kt=size(Xt,2);
    clear Xt;
    ErrorMin=ones(3,1)*inf;
  end
end

it=0; Terminate=0;

% Fitness Evaluation...
for i=1:mu
  clear Waux; Waux{1}=W{i,1}; Waux{2}=W{i,2};
  E(i,1)=sum(abs(ceil(d)-ceil(0.9*mlpnn(Waux,X(:,1:K)))))/K;
end

while (it<=itmax)&(~Terminate)
  % Iteration Counter...
  it=it+1;
   
  % For each individual...
  for i=1:mu
    % Reproduction...
    for f=1:lambda
      W{i+f*mu,1}=W{i,1}+(E(i,1)/10)*randn(J,N+1);
      W{i+f*mu,2}=W{i,2}+(E(i,1)/10)*randn(L,J+1);
      % Fitness Evaluation of the new individuals...
      clear Waux; Waux{1}=W{i+f*mu,1}; Waux{2}=W{i+mu,2};
      E(i+f*mu,it)=sum(abs(ceil(d)-ceil(0.9*mlpnn(Waux,X(:,1:K)))))/K;
    end
  end
  
  % Selection...
  %[aux,ind]=sort(E(:,it),1,'ascend');
  
  clear Waux;
  % Binary Tournament;
  for i=1:mu
    ind=ceil(2*mu*rand(2,1));
    if E(ind(1),it)<=E(ind(2),it)
      Waux{i,1}=W{ind(1),1};
      Waux{i,2}=W{ind(1),2};
      E(i,it+1)=E(ind(1),it);
    else
      Waux{i,1}=W{ind(2),1};
      Waux{i,2}=W{ind(2),2};
      E(i,it+1)=E(ind(2),it);
    end
  end
  
  clear W; W=Waux;
  
  % Evaluation of the Samples...
  clear Waux; Waux{1}=W{1,1}; Waux{2}=W{1,2};
  Y=mlpnn(Waux,X);
  %Error(it,1)=100*sum(abs(ceil(d)-ceil(0.9*Y(:,1:K))))/K;
  Error(it,1)=norm(d-Y(:,1:K));
  if nargin>3
    Error(it,2)=100*sum(abs(ceil(dv)-ceil(0.9*Y(:,K+1:K+Kv))))/Kv;
    if nargin>5
      Error(it,3)=100*sum(abs(ceil(dt)-ceil(0.9*Y(:,K+Kv+1:K+Kv+Kt))))/Kt;
      disp(sprintf('It.: %d, Training: %2.1f, Validation: %2.1f (%2.1f), Test: %2.1f (%2.1f)', it, Error(it,1), Error(it,2), ErrorMin(2), Error(it,3), ErrorMin(3) ))
    else
      disp(sprintf('It.: %d, Training: %2.1f, Validation: %2.1f (%2.4f)', it, Error(it,1), Error(it,2), ErrorMin(2)))
    end
    if Error(it,2)<ErrorMin(2)
      ErrorMin=Error(it,:);
      Wmin=Waux;
      itmin=it;
      disp('---------------------------------------------------------------------')
    end
  else
     disp(sprintf('Iteration: %d, Training Error = %2.4f (%2.4f)', it, Error(it,1), sum(abs(ceil(d)-ceil(Y(:,1:K))))))
     if Error(it,1)<ErrorMin(1)
      ErrorMin=Error(it,:);
      Wmin=Waux;
      itmin=it;
      %disp('---------------------------------------------------------------------')
    end
  end 
  
  %if Error(it,1)<1.e-4
  %  Terminate=1;
  %end
end

%figure(1)
%plot([min(E(:,1:itmax-1));mean(E(:,1:itmax-1));max(E(:,1:itmax-1))]')
%legend('Min','Mean','Max')
%pause