function [BEST,FuncBEST] = Symbiotic_Organism_Search (Func_name,N,Lower,Upper,Maxiter)

fobj = TestFunctions (Func_name); 
D=length(Lower);
X=zeros(N,D);
BEST=zeros(1,D);
XNEW1=zeros(1,D);
XNEW2=zeros(1,D);
MUTUAL=zeros(1,D);
PARASITE=zeros(1,D);
fitness=zeros(1,N);

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

iter=1;

while(iter <= Maxiter)

    for i=1:N
      [minval, mindex]=min(fitness);
       BEST=X(mindex);
       k1=ceil(N*rand);
       while(i==k1)
          k1=ceil(N*rand);
       end
       MUTUAL=mean([X(i,:);X(k1,:)]);
       BF1=round(1+rand);BF2=round(1+rand);
       XNEW1=X(i,:)+rand(1,D).*(BEST-BF1.*MUTUAL); 
       XNEW2=X(i,:)+rand(1,D).*(BEST-BF2.*MUTUAL);
       for j=1:D
         if((XNEW1(j)<Lower(j))||(XNEW1(j)>Upper(j)))
            XNEW1(j)=Lower(j)+(Upper(j)-Lower(j))*rand;
         end 
         if((XNEW2(j)<Lower(j))||(XNEW2(j)>Upper(j)))
            XNEW2(j)=Lower(j)+(Upper(j)-Lower(j))*rand;
         end   
       end
       fit1=fobj(XNEW1);
       fit2=fobj(XNEW2);
       
       if (fit1<fitness(i))
         fitness(i)=fit1;
         X(i,:)=XNEW1;
       end
       
       if (fit2<fitness(i))
         fitness(i)=fit2;
         X(i,:)=XNEW2;
       end
       
       k2=ceil(N*rand);
       while(i==k2)
          k2=ceil(N*rand);
       end
       
       XNEW1=X(i,:)+(rand(1,D).*2-1).*(BEST-X(k2,:));
       for j=1:D
         if((XNEW1(j)<Lower(j))||(XNEW1(j)>Upper(j)))
            XNEW1(j)=Lower(j)+(Upper(j)-Lower(j))*rand;
         end 
       end
       
       fit1=fobj(XNEW1);
       
       if (fit1<fitness(i))
         fitness(i)=fit1;
         X(i,:)=XNEW1;
       end
       
       
       k3=ceil(N*rand);
       while(i==k3)
          k3=ceil(N*rand);
       end
       
       PARASITE=X(i,:);
       seed=randperm(D);           
       pick=seed(1:ceil(rand*D));  % select random dimension
       PARASITE(:,pick)=rand(1,length(pick)).*(Upper(pick)-Lower(pick))+Lower(pick);
       fitPar=fobj(PARASITE);
       
       if(fitPar< fitness(k3))
          fitness(k3)=fitPar;
          X(k3,:)=PARASITE;
       end
    end
  
    [minval2,mindex2]=min(fitness);
    BEST=X(mindex2,:);
    FuncBEST=minval2;  
       
    iter=iter+1; 
    end   

   

endfunction
