Algoritmo Genético Simple (AGs) en Matlab

En días pasados en mi «tuiter» iba publicando líneas de código quizá no entendibles para la gran mayoría, pero digamos que eran mis notas mentales (ni tan mentales al final de cuentas) sobre los códigos en Matlab que iba implementando ya que Matlab nunca me ha gustado pero pues tuve que programar este Algoritmo en Matlab para la materia de Temas Avanzados de Computo Inteligente de MC. Carolina Rocío Sánches Pérez, vayamos con los pasos y el código.

• Pedir al usuario
o Número de Generaciones
o Tamaño del individuo
o Tamaño de la población
o Probabilidad de cruce (en escala de 1 a 9)
o Probabilidad de mutación (en escala de 1 a 9)
• Se genera una población aleatoria de unos y ceros
• Se obtiene el valor de x este puede ser entero o decimal (de acuerdo a la función.
o Para obtener el valor entero sólo se hace la conversión del sistema binario al decimal.
o Para obtener el valor decimal se eleva el valor acumulado a la potencia negativa de acuerdo a la posición que ocupe el número 1 (activo) de derecha a izquierda.
• Se obtiene el valor de la función de X para este caso f(x)=x^2;
• Luego se obtiene la Probabilidad de Selección y ésta se obtiene al dividir cada elemento de f(x) entre la suma total de todos los elementos de f(x).
• Después se obtiene la probabilidad acumulada que es ir sumando los valores de la probabilidad de selección entre si.
• Generamos n números aleatorios en un rango entre 1 y 0, donde n es el tamaño de la población. (R).
• Generamos la población Intermedia esto es, si la función f(x) en la posición (i) es mayor al número (i) generado en R se selecciona el individuo de la población de la posición (i) si no se busca otro.
• Generamos un número aleatorio entre 0 y 1 para la probabilidad de cruce en cada interacción, seleccionamos por parejas (1 y 2, 3 y 4, 5 y 6,…, etc.) si el número aleatorio es menor a la probabilidad de cruce asignada por el usuario entonces cruzamos.
o Generamos un número aleatorio entre 1 y n-1, donde n es igual al tamaño del individuo.
o Cruzamos desde 1 hasta el punto de cruce del primer individuo y concatenamos Sustituimos) con los elementos del segundo elemento desde el punto de cruce hasta n, donde n es el tamaño del individuo.
o Si tenemos números impar en la población el último elemento lo pasamos directamente a la siguiente generación.
• Generamos un número aleatorio entre 0 y 1 si es menor a la probabilidad de mutación entonces cambiamos el elemento de la posición de ese individuo, en caso contrario se deja sin alteraciones.
• Graficamos los puntos de todas las generaciones
o En color rojo y con el símbolo de ‘+’ los puntos de la primera generación
o En color verde y con el símbolo ‘o’ los puntos de las demás generaciones.
• Obtenemos el mejor elemento de la última generación.

Y el código me quedo algo así:
[code lang=»java»]
%Algoritmo Genetico Simple
%Desarrollado por Luigi Pérez Calzada
%28/08/2012
%Download from: hrrp://puraslineas.com

clc;
clear all;

gen=input(‘Da el número de generaciones que deseas manejar: ‘);
n=input(‘Da el tamaño del individuo: ‘);
pob=input(‘Da el tamaño de la población: ‘);
pc_2=input(‘Da la probabilidad de cruce en escala de 1 a 9: (n*0.1)’);
pc=pc_2*0.1;
probMut_2=input(‘Da la probabilidad de mutación en escala de 1 a 9: (n*0.01) ‘);
probMut=probMut_2*0.01;

A=[];
for i=1:pob
for j=1:n
A(i,j)=round(rand); %generamos número aletorios para definir la población matriz de pob*n
end
end

hold on;
%iniciamos generaciones de evolución
for g=1:gen
fprintf(‘Generación %d\n’,g);
fprintf(‘Pob. Inicial\n’);disp(A);

%generamos arreglo con enteros X
X=[];
for i=1:pob
X(i)=bin2dec(num2str(A(i,:)));%convertimos vector numerico a cadena y éste de binario a sistema decimal
end
fprintf(‘X= ‘);disp(X);

%evaluamos x; f(x)=x^2 y obtenemos la sumatoria
fX=[]; sumatoria=0;
for i=1:pob
fX(i)=X(i)^2;
sumatoria=sumatoria+fX(i);
end
fprintf(‘fX= ‘);disp(fX);

%graficamos
if g==1
plot(X,fX,’+r’);
else
plot(X,fX,’og’);
end

%Obtenemos la probabilidad de selección
%Algoritmo Genetico Simple
%Desarrollado por Luigi Pérez Calzada
%28/08/2012
%Download from: hrrp://puraslineas.com
probSel=[];
for i=1:pob
probSel(i)=fX(i)/sumatoria;
end
fprintf(‘Prob. Sel.= ‘);disp(probSel);

%obtenemos la probabilidad acumulada
probAcum=[]; probAcum(1)=probSel(1);
for i=2:pob
probAcum(i)=probAcum(i-1)+probSel(i);
end
fprintf(‘Prob. Acu.= ‘);disp(probAcum);

%obtenemos los valores aleatorios de r
R=[];
for i=1:pob
R(i)=rand;
end
fprintf(‘R= ‘);disp(R);

%obtenemos población intermedia
pobInt=[];
for i=1:pob
for j=1:pob
if probAcum(j)>R(i) %si prob.Acum(j)>r(i) tomamos al ind. si no incrementamos j
pobInt(i,:)=A(j,:); %asignamos en la posicion i (de r) al nuevo individuo de la pos. j
break;
end%end if
end %end for j
end%end for i
fprintf(‘Población Intermedia \n’);disp(pobInt);

%Obtenemos prob. de cruza si es menor cruzamos, además de obtener el punto
%Algoritmo Genetico Simple
%Desarrollado por Luigi Pérez Calzada
%28/08/2012
%Download from: hrrp://puraslineas.com
%de cruza y obtenemos generacion cruzada
pobCruz=[];
if (mod(pob,2)~=0)%si es impar la poblacion
pobCruz(pob,:)=pobInt(pob,:); %asignamos el ultimo elemento directamente
end
for i=1:2:pob
probCruz=rand; %obtenemos la probabilidad de cruce
fprintf(‘probCruce=%f — %f\n’,probCruz,pc);
if(probCruz<pc) %si es menor cruzamos
ptoC=round(rand*n); %obtenemos el punto de cruce de forma aleatoria >1 & <n
while ptoC>n-1 || ptoC<1
ptoC=round(rand*n);
end%end while
fprintf(‘P.C.=%d\n’,ptoC);
for j=1:n
if j>ptoC
pobCruz(i,j)=pobInt(i+1,j);
pobCruz(i+1,j)=pobInt(i,j);
else
pobCruz(i,j)=pobInt(i,j);
pobCruz(i+1,j)=pobInt(i+1,j);
end
end%end for
else
pobCruz(i,:)=pobInt(i,:);
pobCruz(i+1,:)=pobInt(i+1,:);
end%end probCruz < pc
if (mod(pob,2)~=0)
if i==pob-2 %si es impar la poblacion y estamos en el penultimo elemento (de 2 en 2) rompemos
break;
end
end %end if mod
end
fprintf(‘Población Cruza\n’);disp(pobCruz);

%obtenemos mutación
probMut=0.06;
pobMut=[];
for i=1:pob
for j=1:n
mutacion=rand;
if(mutacion<probMut)
fprintf(‘Si hay mutacion en la iter i=%d,j=%d; mutacion fue=%f\n’,i,j,mutacion);
pobMut(i,j)=(pobCruz(i,j)-1)^2;%obtenemos el contrario del binario 0=1 y 1=0
else
pobMut(i,j)=pobCruz(i,j);%si no pasamos como tal
end
end
end
fprintf(‘Población Mutada\n’);disp(pobMut);
A=pobMut;

%generamos arreglo con enteros X
X=[];
for i=1:pob
X(i)=bin2dec(num2str(A(i,:)));%convertimos vector numerico a cadena y éste de binario a sistema decimal
end
fprintf(‘X= ‘);disp(X);

%evaluamos x; f(x)=x^2 y obtenemos la sumatoria
fX=[]; sumatoria=0;
for i=1:pob
fX(i)=X(i)^2;
sumatoria=sumatoria+fX(i);
end
fprintf(‘fX= ‘);disp(fX);

end %end for generaciones
hold off;

%Algoritmo Genetico Simple
%Desarrollado por Luigi Pérez Calzada
%28/08/2012
%Download from: hrrp://puraslineas.com
%obtener el mejor de la última generación
mayor=0;
for i=1:pob
if fX(i)>=mayor
mayor=fX(i);
end
end
fprintf(‘El mejor de la última generación es: %f’,mayor);
[/code]