function [BEST, BestFit] = Chaos_Game_Optimizer (Func_name,N,Lower,Upper,Maxiter)
fobj = TestFunctions (Func_name); 
D=length(Lower);
Seed=zeros(N,D);
NewSeed=zeros(4,D);
Enhanced_Seed=zeros(N+4,D);
fitness=zeros(1,N);
fitnessnew=zeros(1,4);
Enhanced_fit=zeros(1,N+4);
BEST=zeros(1,D);

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

iter=1;

while (iter <= Maxiter)
  
   for i=1:N
      [minval,mindex]=min(fitness);
      BEST=Seed(mindex,:);
      R1=randi([1,2],1,6);
      R2=randi([0,1],1,6);
      RndGrNum=randperm(N,1);
      RandGr=randperm(N,RndGrNum);
      if length(RandGr)~=1
        MeanGr=mean(Seed(RandGr,:));
      elseif length(RandGr)==1
        MeanGr=mean(Seed(RandGr(1,1),:));
      end
      alpha(1,:)=rand(1,D);
      alpha(2,:)=2.*rand(1,D)-1;
      alpha(3,:)=R2(1)*rand(1,D)+1;
      alpha(4,:)=R2(2)*rand(1,D)+(~R2(2));
      triallpha=randi([1,4],1,3);
      randalpha=alpha(triallpha,:);
      NewSeed(1,:)=Seed(i,:)+randalpha(1,:).*(R1(1).*BEST-R2(2).*MeanGr);
      NewSeed(2,:)=BEST+randalpha(2,:).*(R1(3).*MeanGr-R2(4).*Seed(i,:));
      NewSeed(3,:)=MeanGr+randalpha(3,:).*(R1(5).*MeanGr-R2(6).*Seed(i,:));
      NewSeed(4,:)=Lower+(Upper-Lower).*rand(1,D);
  end

  for i=1:4
    for j=1:D
      if ((NewSeed(i,j)<Lower(j))||(NewSeed(i,j)>Upper(j)))
        NewSeed(i,j)=Lower(j)+(Upper(j)-Lower(j))*rand;
      end
    end
  end  
      
  for i=1:4
     fitnessnew(i)=fobj(NewSeed(i,:));
  end

  Enhanced_Seed(1:N,1:D)=Seed(1:N,1:D);
  Enhanced_Seed(N+1:N+4,1:D)=NewSeed(1:4,1:D);
  Enhanced_fit(1:N)=fitness(1:N);
  Enhanced_fit(N+1:N+4)=fitnessnew(1:4);
  
  [Enhanced_fit,sorted_fit]=sort(Enhanced_fit);
   Enhanced_Seed=Enhanced_Seed(sorted_fit,:);
  [BestFit, mindex2]=min(Enhanced_fit);
   BEST=Enhanced_Seed(mindex2,:);
   Seed=Enhanced_Seed(1:N,1:D);
   fitness=Enhanced_fit(1:N);
   
   iter=iter+1;
end



endfunction
