function [BEST,BESTCOST]   = Runge_Kutta_Optimization (Func_name,N,Lower,Upper,Maxiter)
  
 
fobj = TestFunctions (Func_name); 
D=length(Lower);
X=zeros(N,D);
XNEW=zeros(1,D);
XNEW1=zeros(1,D);
XNEW2=zeros(1,D);
XAVER=zeros(1,D);
fitness=zeros(1,N);
SF=zeros(1,N);
GAMMA=zeros(1,D);
DELX=zeros(1,D);
BEST=zeros(1,D);
BESTL=zeros(1,D);
STP=zeros(1,D);
XB=zeros(1,D);
XW=zeros(1,D);
XC=zeros(1,D);
XM=zeros(1,D);
SM=zeros(1,D);
w=zeros(1,D);
BETA=zeros(1,D);
L=zeros(1,D);
rr=zeros(1,D);
u=zeros(1,D);
mu=zeros(1,D);
  

for i=1:N
  for j=1:D
    X(i,j)=Lower(j)+(Upper(j)-Lower(j))*rand;
  end
  fitness(i)=fobj(X(i,:));
end

[minval,mindex]=min(fitness);
BEST=X(mindex,:);
BESTCOST=fobj(BEST);

iter=1;

while(iter<=Maxiter)
   f=20*exp(-12.0*(iter/Maxiter));
   XAVER=mean(X);
   for i=1:N
     SF(i)=2.0*(0.5-rand)*f;
     fitness(i)=fobj(X(i,:));
   end
   
   for i=1:N
      [minval1,mindex1]=min(fitness);
      BESTL=X(mindex1,:);
        
       k1=ceil(N*rand);
       k2=ceil(N*rand);
       k3=ceil(N*rand);
   
             while(i==k1)
                  k1=ceil(N*rand);
             end
             while((k1==k2)||(i==k2))
                 k2=ceil(N*rand);
             end    
             while((k2==k3)||(k1==k3)||(i==k3))
                 k3=ceil(N*rand);
             end
             
             fit1=fobj(X(k1,:));
             fit2=fobj(X(k2,:));
             fit3=fobj(X(k3,:));
             all=[fit1,fit2,fit3];
             [minval2,mindex2]=min(all);
             
             GAMMA=rand.*(X(i,:)-rand.*(Upper-Lower)).*exp(-4.0.*iter./Maxiter);
             STP=rand.*((BEST-rand.*XAVER)+GAMMA);
             DELX=2.*rand.*abs(STP);
             
             if(fitness(i)<fitness(mindex2))
                XB=X(i,:);
                XW=X(mindex2,:);
             elseif
                XB=X(mindex2,:);
                XW=X(i,:);
             end
             
             SM=RungeKutta(XB,XW,DELX);
             
             for j=1:D
               if(rand<0.5)
                 L(j)=0;
                 rr(j)=-1.0;
               else
                 L(j)=1;
                 rr(j)=1.0;
               end  
             end
             
             XC=L.*X(i,:)+(1-L).*X(k1,:);
             XM=L.*BEST+(1-L).*BESTL;
             
             g=2.*rand;
             mu=0.5+0.1.*rand;

             if(rand<0.5)
               XNEW=(XC+rr.*SF(i).*g.*XC)+SF(i).*SM+mu.*(XM-XC); 
             else
               XNEW=(XM+rr.*SF(i).*g.*XM)+SF(i).*SM+mu.*(X(k1,:)-X(k2,:));
             end  
    
             for j=1:D
               if((XNEW(j)<Lower(j))||(XNEW(j)>Upper(j)))
                  XNEW(j)=Lower(j)+(Upper(j)-Lower(j))*rand;
               end   
             end
             
             COSTNEW=fobj(XNEW);
             if(COSTNEW<fitness(i))
                X(i,:)=XNEW;
                fitness(i)=COSTNEW;
             end
             
             if(rand<0.5)
                     
                     EXP1=exp(-5.0.*rand.*iter./Maxiter);
                     r1=floor(Unifrnd(-1.0,2.0));
                     for j=1:D
                         u(j)=2*rand;
                         w(j)=Unifrnd(0,2).*EXP1;
                     end
                     
                     k1=ceil(N*rand);
                     k2=ceil(N*rand);
                     k3=ceil(N*rand);
   
                     while(i==k1)
                         k1=ceil(N*rand);
                     end
                     while((k1==k2)||(i==k2))
                         k2=ceil(N*rand);
                     end    
                     while((k2==k3)||(k1==k3)||(i==k3))
                          k3=ceil(N*rand);
                     end
                     
                     XAVER=(X(k1,:)+X(k2,:)+X(k3,:))./3.0;   
                     BETA=rand(1,D);
                     XNEW1=BETA.*BEST+(1-BETA).*XAVER;
                 
                     for j=1:D
                       if(w(j)<1.0)
                         XNEW2(j)=XNEW1(j)+r1*w(j)*abs((XNEW1(j)-XAVER(j))+randn);
                       else
                         XNEW2(j)=(XNEW1(j)-XAVER(j))+r1*w(j)*abs((u(j)*XNEW1(j)-XAVER(j))+randn); 
                       end
                     end
                     
                     for j=1:D
                       if((XNEW2(j)<Lower(j))||(XNEW2(j)>Upper(j)))
                           XNEW2(j)=Lower(j)+(Upper(j)-Lower(j))*rand;
                       end   
                     end
                     
                     COSTNEW=fobj(XNEW2);
                     if(COSTNEW<fitness(i))
                         X(i,:)=XNEW2;
                         fitness(i)=COSTNEW;
                     else
                         if(rand<w(randi(D)))
                             SM=RungeKutta(X(i,:),XNEW2,DELX);
                             for j=1:D
                                    XNEW(j) = (XNEW2(j)-rand*XNEW2(j))+SF(i)*(SM(j)+(2*rand*BEST(j)-XNEW2(j)));
                                    if((XNEW(j)<Lower(j))||(XNEW(j)>Upper(j)))
                                        XNEW(j)=Lower(j)+(Upper(j)-Lower(j))*rand;
                                    end 
                             end
                             COSTNEW=fobj(XNEW);
                             if(COSTNEW<fitness(i))
                                X(i,:)=XNEW;
                                fitness(i)=COSTNEW;
                             end
                         end    
                    end         
               
             end
             
             if (fitness(i)<BESTCOST)
                 BEST=X(i,:);
                 BESTCOST=fitness(i); 
             end
 
   end
   
   iter=iter+1;
end  

 


endfunction
