generation_n = 30;	% Number of generations
popuSize = 20;		% Population size
xover_rate = 0.6;	% Crossover rate
mutate_rate = 0.05;	% Mutation rate
% lb edit
bit_n = 16;		    % Bit number for each input variable
% end lb edit
global OPT_METHOD	% optimization method.
OPT_METHOD = 'ga';	% This is used for display in peaksfcn
figure;
blackbg;

%obj_fcn = 'peaksfcn';	% Objective function: 'peaksfcn' or 'wavefcn'
obj_fcn = 'banana_function';	% Objective function: 'peaksfcn' or 'wavefcn'
fitness_fcn = 'banana_fitness_function';	% Objective function: 'peaksfcn' or 'wavefcn'

if strcmp(obj_fcn, 'banana_function'),	% objective function is 'peaksfcn'
	var_n = 2;		% Number of input variables
	range = [-2, 2; -1, 3];	% Range of the input variables

    % plot banana function
    
point_n = 25;
x=linspace(-2, 2, point_n);
y=linspace(-1, 3, point_n);
[xx,yy]=meshgrid(x,y);

zz= 100.*(yy-xx.^2).^2+(1-xx).^2; % real banana function
%zz= 100.*(yy-xx     ).^2+(1-xx).^2; % hw banan function
 
subplot(111);
mesh(xx, yy, zz);
view([-20, 25]); set(gca, 'box', 'on');
axis([-inf inf -inf inf -inf inf]);
xlabel('X'); ylabel('Y'); zlabel('E(X,Y)');
title('(a) Banana function');
end

% Initial random population
popu = rand(popuSize, bit_n*var_n) > 0.5; 

upper = zeros(generation_n, 1);
average = zeros(generation_n, 1);
lower = zeros(generation_n, 1);

% Main loop of GA
for i = 1:generation_n;

	% delete unnecessary objects
	delete(findobj(0, 'tag', 'member'));
	delete(findobj(0, 'tag', 'individual'));
	delete(findobj(0, 'tag', 'count'));

	% Evaluate objective function for each individual
	fcn_value = evalpopu(popu, bit_n, range, fitness_fcn);
%	if (i==1),
%		fprintf('Initial population.\n');
%		fprintf('Press any key to continue...\n');
%		pause;
%	end

	% Fill objective function matrices
	upper(i) = max(fcn_value);
	average(i) = mean(fcn_value);
	lower(i) = min(fcn_value);

	% display current best
	[best, index] = max(fcn_value);
	fprintf('Generation %i: ', i);
	if strcmp(obj_fcn, 'banana_function'),	% obj. function is 'banana_function'
		fprintf('  fitness (5000-banana_fn) :(%f, %f)=%f\n', ...
			bit2num(popu(index, 1:bit_n), range(1,:)), ...
			bit2num(popu(index, bit_n+1:2*bit_n), range(2,:)), ...
			best);        
        %lb
         input(1) = bit2num(popu(index, 1:bit_n), range(1,:));
         input(2) = bit2num(popu(index, bit_n+1:2*bit_n), range(2,:));
         %	fprintf('    banana_fn :               (%f, %f)=%f\n');
    fprintf('                banana_fn :               (%f, %f)=%f\n', ...
        input(1) , ...
        input(2) , ...
        feval(obj_fcn, input));
	end
	% generate next population via selection, crossover and mutation
	popu = nextpopu(popu, fcn_value, xover_rate, mutate_rate);
	if (i==5),
		fprintf('Population after the 5th generation.\n');
        
        %%%%%%%% My Generation Print Out
        for alpha_male = 1:popuSize,
            
	        fprintf('Entity %i:', alpha_male);
    
        	fprintf('  fitness (5000-banana_fn) :(%f, %f)=%f\n', ...
			bit2num(popu(alpha_male, 1:bit_n), range(1,:)), ...
			bit2num(popu(alpha_male, bit_n+1:2*bit_n), range(2,:)), ...
			feval(fitness_fcn, [ bit2num(popu(alpha_male, 1:bit_n), range(1,:)) bit2num(popu(alpha_male, bit_n+1:2*bit_n), range(2,:)) ]) );        
   
            input(1) = bit2num(popu(alpha_male, 1:bit_n), range(1,:));
            input(2) = bit2num(popu(alpha_male, bit_n+1:2*bit_n), range(2,:));
         	%fprintf('banana_fn: ');
            fprintf('            banana_fn :               (%f, %f)=%f\n', ...
            input(1) , ...
            input(2) , ...
            feval(obj_fcn, input));
        end

        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
				fprintf('Press any key to continue...\n');
		pause;
    end
	if (i==10),
		fprintf('Population after the 10th generation.\n');
        
        %%%%%%%% My Generation Print Out
        for alpha_male = 1:popuSize,
            
	        fprintf('Entity %i:', alpha_male);
    
        	fprintf('  fitness (5000-banana_fn) :(%f, %f)=%f\n', ...
			bit2num(popu(alpha_male, 1:bit_n), range(1,:)), ...
			bit2num(popu(alpha_male, bit_n+1:2*bit_n), range(2,:)), ...
			feval(fitness_fcn, [ bit2num(popu(alpha_male, 1:bit_n), range(1,:)) bit2num(popu(alpha_male, bit_n+1:2*bit_n), range(2,:)) ]) );        
   
            input(1) = bit2num(popu(alpha_male, 1:bit_n), range(1,:));
            input(2) = bit2num(popu(alpha_male, bit_n+1:2*bit_n), range(2,:));
         	%fprintf('banana_fn: ');
            fprintf('            banana_fn :               (%f, %f)=%f\n', ...
            input(1) , ...
            input(2) , ...
            feval(obj_fcn, input));
        end

        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		fprintf('Press any key to continue...\n');
		pause;
    end
end

figure;
title('GA Fitness Function (5000-banana_fn) ');
blackbg;
x = (1:generation_n)';
plot(x, upper, 'o', x, average, 'x', x, lower, '*');
hold on;
plot(x, [upper average lower]);
hold off;
legend('Best', 'Average', 'Poorest');
xlabel('Generations'); ylabel('Fitness (5000-banana fn) ');
title('GA Fitness Function (5000-banana fn) ');