Está en la página 1de 19

Trabajo Práctico N°6

Link de Scripts: Código TP6

1. Estudio de operadores binarios mono-progenitor.


Considerar una población inicial (aleatoria) P0 de un algoritmo genético. Tal población está
constituida por 50 individuos de 10 bits cada uno, cuyo equivalente decimal se encuentre
entre [-400 ; +400]:

Ix(P0) = [ bsigno , b9 , b8 , b7 , b6 , b5 , b4 , b3 , b2 , b1] (2,10)CS (genérico)

Escribir los scripts que modifiquen la población P0 durante 100 iteraciones aplicando:
> Un operador de mutación en un solo bit con Pm = 10%.
> Un operador de inversión en 2 bits aleatorios con PI = 10%.
> Un tercer operador, diseñado por el usuario, a partir de un solo progenitor y un solo
descendiente, con una probabilidad Px = 10%.

Requerimientos:
Hacer un estudio por separado para cada operador. En todos los casos utilizar la misma
población aleatoria inicial.
Para cada aplicación de cada operador, y para mantener fija la cantidad de la población, se
elimina al progenitor. No hay control del individuo generado, que pasa directamente a la
siguiente población.
Determinar, en cada generación (iteraciones) y para cada operador:

Cuántos individuos salieron del espacio de datos.


a) Mostrar en gráfico de barras.
b) Cuántos individuos cambiaron de signo. Mostrar en gráfico de barras.
c) El valor máximo positivo, máximo negativo y promedio de los individuos. Mostrar en
gráfico de líneas, simultáneos. En este caso excluir a los individuos que salieron del
espacio de datos.
d) Verificar cómo se comporta cada operador y emitir conclusiones.

Nota 1: se recomienda generar la población en una matriz de 50 x 10, para puede estar
contenida en un vector columna.
Nota 2: La función randi(Vmin,Vmáx,m,n) de Matlab® genera una matriz m n de valores
enteros aleatorios que se encuentran en el rango [Vmin , Vmáx]; ¡cuidar el signo!.
Nota 3: el mismo algoritmo/script podría usarse para todas las variantes, cambiando el
método de aplicación del operador.

Scripts

p0=randi([0,1],50,10)%poblacion inicial
Pobmut=p0;%poblacion mutada

cont=zeros(1,100);
cont_out=0;
cs=0;
for k=1:100
v=zeros(50,1);
Pmut=rand(50,1);
sprintf('iteracion n° %d',k)
cont_out=0;
cs=0;
for i=1:50
if Pmut(i)<=0.1
cont(k)=cont(k)+1;
j=randi([1,10],1,1);
Pobmut(i,j)=~Pobmut(i,j);
if j==1
cs=cs+1;
end
aux=Pobmut(i,2:10);
aux=num2str(aux);
if bin2dec(aux)>400
cont_out=cont_out+1;
end
sprintf('mutado bit %d de individuo %d con Pmut=%3.1f %%',j,i,Pmut(i)*100)
end
end
Y(k)=cont_out;% cantidad de ind. que salieron del espacio
Z(k)=cs;%numeros que cambiaron de signo
for m=1:50
if Pobmut(m,1)==1
v(m)=-1*bin2dec(num2str(Pobmut(m,2:10)));
else
v(m)=bin2dec(num2str(Pobmut(m,2:10)));
end
if v(m)>400 | v(m)<-400
v(m)=0;
end
end
maximos(k)=max(v);
minimos(k)=min(v);
promedio(k)=mean(v);
end
subplot(2,2,1);
bar(Y)
title('individuos que salen del espacio de datos')
subplot(2,2,2);
bar(Z)
title('individuos que cambian de signo')
X=linspace(1,100,100);
subplot(2,2,[3,4]);
plot(X,maximos,X,minimos,X,promedio)
axis ([0 100 -500 500])
disp('Población mutada despues de 100 iteraciones Pmut');
disp(Pobmut);
Scripts

P0=randi([0,1],50,10)% poblacion inicial


Pobmut=P0;%Poblacion mutada
cont=zeros(1,100)
cont_out=0;
cs=0;
for k=1:100
valores=zeros(50,1);
Pmut=rand(50,1);
sprintf('INVERSION EN ITERACION NUMERO %d',k)
cont_out=0;
cs=0;
for i=1:50
if Pmut(i)<=0.1
cont(k)=cont(k)+1;
p1=randi([1,10],1,1);
p2=randi([1,10],1,1);
aux=Pobmut(i,p1);
Pobmut(i,p1)=Pobmut(i,p2);
Pobmut(i,p2)=Pobmut(i,p1);
if p1==1 | p2==1
cs=cs+1;
end
aux=Pobmut(i,2:10);
aux=num2str(aux);
if bin2dec(aux)>400
cont_out=cont_out+1;
end
sprintf('invertido bit %d con bit %d de individuo %d con Pmut=%3.1f %
%',p1,p2,i,Pmut(i)*100)
end
end
Y(k)=cont_out;%cantidad de ind. que salieron del espacio
Z(k)=cs;%individuos que cambiaron de signo
for m=1:50
if Pobmut(m,1)==1
valores(m)=-1*bin2dec(num2str(Pobmut(m,2:10)));
else
valores(m)=bin2dec(num2str(Pobmut(m,2:10)));
end
if valores(m)>400 | valores(m)<-400
valores(m)=0;
end
end
maximos(k)=max(valores);
minimos(k)=min(valores);
promedio(k)=mean(valores);
end
subplot(2,2,1);
bar(Y)
title('ind. que salen del espacio de datos')
subplot(2,2,2);
bar(Z)
title('ind. que cambian de signo')
X=linspace(1,100,100);
subplot(2,2,[3,4]);
plot(X,maximos,X,minimos,X,promedio)
axis ([0 100 -500 500])
disp('Población P0');
disp(P0);
disp('Población mutada ');
disp(Pobmut);
Scripts

p0=randi([0,1],50,10)%poblacion inicial
Pobmut=p0;%poblacion mutada
cont=zeros(1,100)
cont_out=0;
cs=0;
for k=1:100
valores=zeros(50,1);
Pmut=rand(50,1); %PROBABILIDAD DE CONJUNCION
sprintf('CONJUNCION EN ITERACION NUMERO %d',k)
cont_out=0;
cs=0;
for i=1:50
if Pmut(i)<=0.1
cont(k)=cont(k)+1; % individuos mutados en la gen K
p1=randi([1,10],1,1);
p2=randi([1,10],1,1);
p3=randi([1,10],1,1);
aux=and(Pobmut(i,p1),Pobmut(i,p2));
Pobmut(i,p3)=aux;
if p1==1 | p2==1
cs=cs+1;
end
aux=Pobmut(i,2:10);
aux=num2str(aux);
if bin2dec(aux)>400
cont_out=cont_out+1;
end
sprintf('conjuncion de bit %d operado con bit %d y bit %d de individuo %d con
Pmut=%3.1f %%',p3,p1,p2,i,Pmut(i)*100)
end
end
Y(k)=cont_out; %cantidad de ind. que salieron del espacio
Z(k)=cs; %de los individuos que cambiaron de signo
for m=1:50
if Pobmut(m,1)==1
valores(m)=-1*bin2dec(num2str(Pobmut(m,2:10)));
else
valores(m)=bin2dec(num2str(Pobmut(m,2:10)));
end
if valores(m)>400 | valores(m)<-400
valores(m)=0;
end
end
maximos(k)=max(valores);
minimos(k)=min(valores);
promedio(k)=mean(valores);
end
subplot(2,2,1);
bar(Y)
title('individuos que salen del espacio de datos')
subplot(2,2,2);
bar(Z)
title('individuos que cambian de signo')
X=linspace(1,100,100);
subplot(2,2,[3,4]);
plot(X,maximos,X,minimos,X,promedio)
axis ([0 100 -500 500])
disp('Población inicial P0');
disp(p0);
disp('Población mutada');
disp(Pobmut);

2. Estudio de operador
Considerar un espacio de datos sobre un plano X-Y, en el entorno
-5555 ≤ X,Y ≤ +5555

Generar una población aleatoria de 100 individuos decimales, configurados en un sistema


numérico (10,5)CS, que representarán las coordenadas de puntos en un plano
bidimensional:
Ix = (X,Y); (por ej. I1 = (14095, 03954) ← (negativo, positivo); I2 = (03278, 16245) ← fuera de
rango). Almacenar esta primera población aleatoria para ser utilizada en todas las variantes que se
proponen para el algoritmo de cruza.
Considerar el operador genético (OG) de cruza para cromosomas decimales, en las
variantes media aritmética, media geométrica y extensión (Gestal, pg. 24). Redefinir (a
criterio propio) la cruza de los primeros alelos para preservar que el bit de signo no salga del
entorno correspondiente.
Sobre un script de Matlab, estudiar como afecta la diversidad de la población las diferentes
variantes del operador de cruza (por separado), bajo las siguientes condiciones:

> Generar 25 iteraciones para cada variante del OG, partiendo en cada caso de la misma
población inicial.
> Utilizar para cada variante del OG de cruza, la selección aleatoria sobre toda la población,
generando 50 parejas en cada iteración.
> Para cada aplicación del OG de cruza aplicar una probabilidad de cruza monopunto entre
el 75% y el 95%, elegida por el usuario y que se mantendrá fija para todo el estudio y todas
las variantes. El punto de cruce debe cambiar aleatoriamente en cada iteración.
> Los individuos que salgan del espacio de datos, luego de cada aplicación del OG, deben
ser reemplazados por el progenitor que presente el menor valor absoluto.

El estudio consiste en:


> Determinar cómo se ha diversificado la población con cada variante del OG de cruza,
luego de las 25 iteraciones. Considerando que el objetivo es alcanzar el origen del plano,
los mejores individuos son los que estén mas cerca de (0,0).
> Graficar sobre un plano, por separado, la primera, intermedia y última generación.
Comentar al respecto.
> En cada iteración, calcular la distancia máxima, mínima y promedio al origen y graficar.
> En cada iteración determinar cuántos individuos salen del espacio de datos, antes de ser
reemplazados. Graficar.
> Emitir conclusiones respecto del funcionamiento de cada OG.

Nota 1: se recomienda generar la población en una matriz de 100 x 10 para trabajar sin
perder información. Para trabajar con números completos, debe recordarse que el cero a la
izquierda (signo) no se preserva; en tal caso se puede redefinir el signo a la derecha.
Nota 2: la función randi(Vmin,Vmax,m,n) de Matlab® genera una matriz m n de valores
enteros aleatorios que se encuentran en el rango [Vmin , Vmax]; ¡cuidar el signo!.
Nota 3: el mismo algoritmo/script puede usarse para todas las variantes, cambiando el
método de cálculo de la cruza.

Creación de la población

Función

function [pob] = crear_poblacion(cp)


u = randi([0 9],cp,1);
d = randi([0 9],cp,1);
c = randi([0 9],cp,1);
um = randi([0 4],cp,1);
sig = randi([0 1],cp,1);
pob = [sig,um,c,d,u];
end

Selección de los cromosomas aleatoriamente:

Función

function [ps,x] = seleccion_alet(x)

seleccionados = randperm (100,50);


seleccionados = sort(seleccionados,'descend');
for i=1:50
ps(i,:) = x(seleccionados(i),:);
x(seleccionados(i),:) = [];
end
end

Operador genético (OG) de cruza para cromosomas decimales por extensión

Función

function [pm] = cruza_ex(x,y,probabilidad)


[m,n] = size(x);
%CREACION DE UN VECTOR CON PROBABILIDADES PARA CADA INDIVIDUO
p = rand(1,50);

for i=1:m
%SI ES MAYOR A LA PROBABILIDAD ARROJADA SE CRUZA
if p(i)>= probabilidad
for j=1:n
maximo = max(x(i,j),y(i,j));
pm(i,j)= x(i,j)-y(i,j)+ maximo ;
end
%SI NO LO ES CONSERVA EL LOS ALELOS DEL PADRE
pm(i,:)=x(i,:);
else

end
end
end

Operador genético (OG) de cruza para cromosomas decimales por media geométrica

Función

function [pob_mut] = cruza_mg(x,y,prob)


[m,n] = size(x);
%CREACION DE UN VECTOR CON PROBABILIDADES PARA CADA INDIVIDUO
p = rand(1,50);
for i=1:m
%SI ES MAYOR A LA PROBABILIDAD ARROJADA SE CRUZA
if p(i)>= prob
for j=1:n
pob_mut(i,j)=int16((x(i,j)*y(i,j))^0.5);
end
else
%SI NO LO ES CONSERVA EL LOS ALELOS DEL PADRE
pob_mut(i,:)=x(i,:);
end
end
end
Operador genético (OG) de cruza para cromosomas decimales por media aritmética

Función

function [pob_mut] = cruza_ma(x,y,prob)


[m,n] = size(x);
%CREACION DE UN VECTOR CON PROBABILIDADES PARA CADA INDIVIDUO
p = rand(1,50);
for i=1:m
%SI ES MAYOR A LA PROBABILIDAD ARROJADA SE CRUZA
if p(i)>= prob
for j=1:n
pob_mut(i,j)=int16((x(i,j)+y(i,j))/2);
end
else
%SI NO LO ES CONSERVA EL LOS ALELOS DEL PADRE
pob_mut(i,:)=x(i,:);
end
end
end

Función que solicita el factor de probabilidad de cruza, utilizando la función de cruza


utilizando el operador de media aritmética

Función

% SOLICITAR FACTOR DE PROBABILIDAD DE CRUZA


Pc=input('Ingrese la Probabilidad de Cruza [0.7,0.95]% : ');
if Pc>=0.7 && Pc<=0.95
else
error('Debe ingresar una Probabilidad de Cruza entre [60,90]%');
end

% POBLACION INICIAL FIJA SE LE ASIGNA UN X QUE SERA QUIEN VA A MUTAR


x = pobx ;
% POBLACION INICIAL FIJA SE LE ASIGNA UN Y QUE SERA QUIEN VA A MUTAR
y = poby ;

for i=1:25
% SELECCION ALEATORIA POBLACION A MUTAR Y LA POBLACION NO
SELECCIONADA X
[selx,resultx] = seleccion_alet(x);
% SELECCION ALEATORIA POBLACION A MUTAR Y LA POBLACION NO
SELECCIONADA Y
[sely,resulty] = seleccion_alet(y);
% OPERADOR DE CRUZA POBLACION SELECCIONADA X y Y - PROBABILIDAD
mutados = cruza_ma(selx,sely,Pc);
% LOS MUTADOS SE INTEGRAN A LA POBLACION NO SELECCIONADA
resultx(51:100,:)= mutados;
resulty(51:100,:)= mutados;
% SE ELIMINA POBLACION GENERACION PASADA
x = resultx ;
y = resulty ;
end

Función que solicita el factor de probabilidad de cruza, utilizando la función de cruza


utilizando el operador de media geométrica.

Función

% SOLICITAR FACTOR DE PROBABILIDAD DE CRUZA


Pc=input('Ingrese la Probabilidad de Cruza [0.7,0.95]% : ');
if Pc>=0.7 && Pc<=0.95
else
error('Debe ingresar una Probabilidad de Cruza entre [60,90]%');
end

x = pobx ;
y = poby ;

for i=1:25
[selx,resultx] = seleccion_alet(x);
[sely,resulty] = seleccion_alet(y);
mutados = cruza_mg(selx,sely,Pc);
resultx(51:100,:)= mutados;
resulty(51:100,:)= mutados;
x = resultx ;
y = resulty ;
end

Función que solicita el factor de probabilidad de cruza, utilizando la función de cruza


utilizando el operador por extensión:

Función

% SOLICITAR FACTOR DE PROBABILIDAD DE CRUZA


Pc=input('Ingrese la Probabilidad de Cruza [0.7,0.95]% : ');
if Pc>=0.7 && Pc<=0.95
else
error('Debe ingresar una Probabilidad de Cruza entre [60,90]%');
end

% POBLACION INICIAL FIJA SE LE ASIGNA UN X QUE SERA QUIEN VA A MUTAR


x = pobx ;
% POBLACION INICIAL FIJA SE LE ASIGNA UN Y QUE SERA QUIEN VA A MUTAR
y = poby ;

for i=1:25
% SELECCION ALEATORIA POBLACION A MUTAR Y LA POBLACION NO
SELECCIONADA X
[selx,resultx] = seleccion_alet(x);
% SELECCION ALEATORIA POBLACION A MUTAR Y LA POBLACION NO
SELECCIONADA Y
[sely,resulty] = seleccion_alet(y);
% OPERADOR DE CRUZA POBLACION SELECCIONADA X y Y - PROBABILIDAD
mutados = cruza_ex(selx,sely,Pc);
% LOS MUTADOS SE INTEGRAN A LA POBLACION NO SELECCIONADA
resultx(51:100,:)= mutados;
resulty(51:100,:)= mutados;
% SE ELIMINA POBLACION GENERACION PASADA
x = resultx ;
y = resulty ;
end

> Graficar sobre un plano, por separado, la primera, intermedia y última generación.
Comentar al respecto.

En el gráfico de la primer generación se puede observar cómo los distintos individuos están
dispersos y a medida que se ha diversificado la población, cómo se observa en la
generación intermedia, los individuos están más próximos al valor (0 , 0) y más ordenados.
Esto a su vez es más notable en la última generación donde los puntos están más
concentrados .
> Emitir conclusiones respecto del funcionamiento de cada OG.

Debido a que los cromosomas con los que se trabajó en este problema son no binarios (es
decir decimales), se aplicó 3 variantes de operadores de cruza:
Media aritmética , que en este caso está representado por la función cruza_ma, y tiene la
característica de que a partir de dos progenitores se obtiene un descendiente.
Media geométrica: que se basa en el mismo funcionamiento del operador anterior pero en
vez de calcular el promedio entre los genes se calcula la raiz cuadrada.
Operador de cruza por extensión: en donde se restan cada uno de los genes de los
progenitores y a esa expresión se le suma el mayor.
En este problema los 3 operadores arrojaron resultados satisfactorios

3. Mínimo de funciones con AG

a) Desde la línea de comandos de Matlab, encontrar el mínimo de la función (A).

x=linspace(-20,20,100)
y=fn_ajuste(x)
>> [x fval exitflag]=ga(@fn_ajuste,1)

Resultado del Comando


Optimization terminated: average change in the fitness value less than
options.FunctionTolerance.

x=
0.0044

fval =
1.0044

exitflag =
1

b) Escribir un script de Matlab, para encontrar el máximo de la función (B). Incluir allí
los parámetros que se estimen convenientes.

Scrips

x=linspace(-10,10,100);
>> y=((x.^2+x).*cos(x));
>> plot(x,y)

function funcionajuste_b()
op=gaoptimset;
op=gaoptimset(op,'CrossoverFcn',@crossoverheuristic);
op=gaoptimset(op,'CrossoverFraction',0.90);
op=gaoptimset(op,'CreationFcn',{'gacreationuniform'});
op=gaoptimset(op,'Display','off');
op=gaoptimset(op,'EliteCount',3);
op=gaoptimset(op,'Generations',100);
op=gaoptimset(op,'mutationFcn',@mutationuniform);
op=gaoptimset(op,'PopulationSize',30);
op=gaoptimset(op,'PopulationType','doubleVector');
op=gaoptimset(op,'PopInitRange',[-10;10]);
op=gaoptimset(op,'SelectionFcn',@selectiontournament);
op=gaoptimset(op,'Tolfun',1e-12);

[x,f_sal]=ga(@(x)(400-(x.^2+x).*cos(x)),1,op);
fprintf('x: %f\n',x);
fprintf('f_sal: %f\n',f_sal);
end
funcionajuste_b
x: 6.560540
f_sal: 352.294379

c) Con la ayuda del GUI optimtool de Matlab, encontrar el mínimo de la función (C)

x=linspace(0,10,100);
>> y=linspace(0,10,100);
function z = fn_ajuste_c(x)
z=x(1).*sin(4*x(1))+1.1*x(2).*sin(2*x(2));
end
4. Entrenamiento de red Neuronal
Aplicando Algoritmos Genéticos, entrenar la red neuronal feed-forward 2+2+1 (figura), para
realizar la operación XOR. Las funciones de salida de las neuronas ocultas son sigmoides
bivaluadas y para la neurona de salida es función escalón. Orientación: Las variables a
considerar serían los pesos. La función de salida puede ser reemplazada por otra durante el
entrenamiento. Como el proceso minimiza, se puede utilizar la función de error como
función de ajuste.

Scripts

fxy = [0 0 0; 0 1 1; 1 0 1; 1 1 0];%Matriz de entrada/salida [x y F]


etha = 0.5; %factor de aprendizaje
m = 0; % itentos
F_sal(1)=0;
F_sal(2)=0;
F_sal(3)=0;
F_sal(4)=0; %Salida inicial de la red
while (F_sal(1)~= fxy(1,3)) | (F_sal(2)~= fxy(2,3)) | (F_sal(3)~= fxy(3,3)) |
(F_sal(4)~=fxy(4,3))
m = m+1;
b(1:3)= 1; %bias iniciados en 1
w = -1 + 2*rand(6,1); %pesos iniciales
dw1 = 1; dw2 = 1; dw3 = 1; dw4 = 1; dw5 = 1; dw6 = 1;
n = 0;
while (((dw1 ~= 0) | (dw2 ~= 0) | (dw3 ~= 0) | (dw4 ~= 0) | (dw5 ~= 0) | (dw6 ~= 0)) &&(n
< 100))
n = n+1;
for i = 1:4
F_sal_a = (1/1+exp(-(fxy(i,1)*w(1)+fxy(i,2)*w(2)+1)));
F_sal_b = (1/1+exp(-(fxy(i,1)*w(3)+fxy(i,2)*w(4)+1)));
F_sal(i) = heaviside(F_sal_a*w(5)+F_sal_b*w(6)+1);
err_salida = (fxy(i,3)-F_sal(i));
Dw1(i) = etha*fxy(i,1)*err_salida;
Dw2(i) = etha*fxy(i,1)*err_salida;
Dw3(i) = etha*fxy(i,2)*err_salida;
Dw4(i) = etha*fxy(i,2)*err_salida;
Dw5(i) = F_sal_a*err_salida;
Dw6(i) = F_sal_b*err_salida;
end
dw1 = sum(Dw1);
dw2 = sum(Dw2);
dw3 = sum(Dw3);
dw4 = sum(Dw4);
dw5 = sum(Dw5);
dw6 = sum(Dw6);
w(1) = w(1) + dw1;
w(2) = w(2) + dw2;
w(3) = w(3) + dw3;
w(4) = w(4) + dw4;
w(5) = w(5) + dw5;
w(6) = w(6) + dw6;
end
end
sprintf(' Pesos: w1 = %g w2 = %g w3 = %g w4 = %g w5 = %g',w(1),w(2),w(3),w(4),w(5));
sprintf(' Bias: B1 = %g B2 = %g B3 = %g',b(1),b(2),b(3))
sprintf(' Intentos de convergencia = %g Iteraciones en el ultimo intento = %i\n',m,n)
sprintf(' x y XOR(x,y)')
[fxy(1:4,1:2) F_sal(:)]

Resultados del entrenamiento.

También podría gustarte