You are on page 1of 5

Algoritmo gentico para problema de reinas en tablero de ajedrez

Se ha realizado las siguientes mejoras. Se clonan siempre 3 individuos. La operacin


crossover empieza en una posicin aleatoria de 1 a 5 y siempre combina 4 genes.

Los programas que se usan son


ATAQT
BORRARUNO
COMBINEX
CROSSOVER_N
ELIMINAR
GENETICO
GENPOBLA
GENTAB
MUTAR
MUTARUNO
NPADRESX
ORDENAR
ORDENAUNO
CLONAR

% Funcion que determina el numero de ataques que se producen en un tablero de


% ajedrez dada la posicion de las 8 reinas
function y = ataqt(A,fila,columna)
% fila es un vector que contiene las filas donde se ubican las reinas
% columna es un vector que contiene las columnas donde se ubican las reinas
% A es la matriz que representa el tablero de 8*8 donde una reina
% se representa por un 1
% x = numero de ataques en el tablero
% y es la funcionde costo de la posicion actual
% Am es una matriz espejo de A para contabilizar ataques diagonal izquierdos
% nr es el numero de reinas o dimesniones del tablero
[nr,nr] = size(A);
j=1:nr;
Am(:,j)= A(:,nr-j+1);
ataqd=zeros(nr,nr);
ataq=zeros(nr,nr);
ataqiz=zeros(nr,nr);

for k = 1: nr ; % k es el contador de las reinas


i = fila(k);
j = columna(k);
A(i,j)=0;% se borra la reina para contabilizar los ataques de las otras
Am(i,nr-j+1)=0;
diagd=j-i; % determina la diagonal donde se encuentra el casillero
diagiz = (nr-j+1)-i;
sumdiag=sum(diag(A,diagd));
sumdiagiz = sum(diag(Am,diagiz));

ataqiz(i,j)=sumdiagiz;
ataqd(i,j)=sumdiag;
ataq(i,j) = sum(A(i,:))+sum(A(:,j)');
% pause

end

x= ataqd+ataqiz+ataq;
y =sum(sum(x));

% programa que elimina individuos segun el indice que ingresa como


dato

function [an,filan,columnan]=borrauno(a,fila,columna,indice)
[xx,yy,pob]=size(a);
i = indice;
if i ==1
an= a(:,:,i+1:pob);filan=fila(i+1:pob,:);columnan=columna(i+1:pob,:);
end
if i == pob
an= a(:,:,1:pob-1);filan=fila(1:pob-1,:);columnan=columna(1:pob-1,:);
end
if i<pob & i >1
for j=1:i-1
an(:,:,j) = a(:,:,j);filan(j,:)=fila(j,:);columnan(j,:)=columna(j,:);
end
for j = i+1:pob
an(:,:,j-1) = a(:,:,j);filan(j-1,:)=fila(j,:);columnan(j-1,:)=columna(j,:);
end
end

% funcion que realiza las distintas combinaciones de los n padres

function [ahij,fhij,chij] = combinex(apad,fila,columna,ind)


disp('procreando individuos')
% n es el numero de individuos a combinarse
% ahij es la pobalcion de hijos
% apad es la poblacion de padres
k =0; % k es el contador de hijos
[nr,yy,np]=size(apad); % nr es la dimension del tablero
[xx,n] = size(ind);
if n == 1
% disp('no hay combinaciones')
ahij= [];fhij=[];chij=[];
else
% disp('si hay combinaciones')
for i = 1:n-1
for j = i+1:n
ap=apad(:,:,ind(i));%selecciona al padre con indice i
bp=apad(:,:,ind(j));
fap=fila(ind(i),:);
fbp=fila(ind(j),:);
cap=columna(ind(i),:);
cbp=columna(ind(j),:);
pos=1+floor(rand*(nr/2));
num=floor(nr/2);
[ah,bh,fah,fbh,cah,cbh]=crossover_n(ap,bp,fap,fbp,cap,cbp,pos,num);
% se comprueba si el hijo tiene todos los 8 genes para dejarlo vivo
if sum(sum(ah))== nr
k=k+1;
ahij(:,:,k)=ah;
fhij(k,:) = fah;
chij(k,:) = cah;
[fhij(k,:),chij(k,:)]=ordenuno(fhij(k,:),chij(k,:));
end
if sum(sum(bh))==nr
k=k+1;

ahij(:,:,k)=bh;
fhij(k,:) = fbh;
chij(k,:) = cbh;
[fhij(k,:),chij(k,:)]=ordenuno(fhij(k,:),chij(k,:));
end

end
end

end

% eliminar individuos que tienen iguales genes


function [a,fila,columna]=eliminar(a,fila,columna)
[xx,yy,pob] = size(a);
% disp('eliminar de poblacion :');
pob;
indb=[];
for i = 1:pob-1
for j = i+1:pob
if a(:,:,i)== a(:,:,j)
vive=0;
break
else
vive=1;
end
end
if vive==0
indb=[indb;i];

end
end

% salen repetidos los indices de borrado y se debe dejar solo uno


% aqui se quedo el programa
% domingo 15 de dic 2002
%
% for i = 1:size(indb)
% for j = i+1:size(indb)-1
% if a(:,:,i)==a(:,:,j)
% indb=[indb;i]
% pause
% end
% end
% end
% indb
[n,xx]=size(indb);
% disp('estos individuos se borraran');

if n >= 1
% disp('n fue mayor que 1');

for j = size(indb):-1:1

[a,fila,columna]=borrauno(a,fila,columna,indb(j));
[xx,yy,pob]=size(a);

end
end

genetico

%algoritmo genetico
% genero la poblacion inicial de 8 individuos (individuo es tablero con reinas
dispuestas)
clear all
clc
fcmax=22;
pobmax = 50; % es la poblacion maxima
pobini = 20; % es el numero de individuos en la pobalcion inicial

% generar una poblacion inicial de n individuos e indicar la


% funcion de costo de cada individuo

% la poblacion inicial que escojo la selecciono inicialmente para partir de un punto


favorable
nr =7; % nr es la dimension del problema
[a,fila,columna,fc] = genpobla(1000,nr);
[a,fila,columna,fc] = ordenar(a,fila,columna,fc);
disp('ha generado poblacion de 1000 individuos')
a=a(:,:,1:pobini);fila =fila(1:pobini,:);columna=columna(1:pobini,:);fc=fc(:,1:pobini)
% fc es la funcion de costo de cada individuo. Indica el numeo de ataques presentes en
tablero

disp('ha generado poblacion inicial')


s=1
count=0
while s % lazo indefinido
clc
a(:,:,1)
count=1+count

fadap = fcmax - fc; % es la funcion de adaptacion del individuo

prep= fadap/sum(fadap);% es la probabilidad de reproduccion


pmut= 1-prep;% es la probabilidad de mutacion
% prep = ones(size(fadap))
% pmut = zeros(size(fadap))

% pause

[ind,indm] = npadresx(prep); %npadres es una funcion que escoge a los padres de


% acuerdo a la probabilidad de reproduccion. En ind se obtiene los indices de
% cada individuo a ser usado en crossover. En indm en cambio
% se obtienen los indices de los individuos a ser mutados
%clc
%disp('individuos padres')
ind;
[xx,sind]=size(ind);
%disp('individuos mutantes');
indm;
%disp('cantidad de individuos padres')
%sind
%disp('funcion de costo actual')
fc(1:10)
% pause
if sind==1
ahij=[];fhij=[];chij=[];
nhijos =0;
else

[ahij,fhij,chij] = combinex(a,fila,columna,ind);
% se eliminan individuos iguales
[ahij,fhij,chij]=eliminar(ahij,fhij,chij);

[q,w,nhijos]= size(ahij);
% nhijos
% pause
end

[amut,fmut,cmut]= mutar(a,fila,columna,indm,pmut);
[q,w,nmut]=size(amut);
disp('numero de individuos que han mutado')
nmut;
indc=[1 2 3]
[aclon,fclon,cclon]= clonar(a,fila,columna,indc);
nclones=3

% pause
% disp('filas y columnas de hijos')
% fhij
% chij
% disp('filas y columnas de mutantes')
% fmut
% cmut

% actualizacion de la poblacion usando los hijos y los mutantes


% hijos ....

if nhijos > 1 % si no hay hijos no se actualiza poblacion con hijos sino solo con
mutantes
for i=1:nhijos
a(:,:,i)=ahij(:,:,i);fila(i,:)=fhij(i,:);columna(i,:)=chij(i,:);
fc(i)=ataqt(ahij(:,:,i),fhij(i,:),chij(i,:)); % evaluo el funcional de costo
end
end
% mutantes
for i= 1:nmut

a(:,:,i+nhijos)=amut(:,:,i);fila(i+nhijos,:)=fmut(i,:);columna(i+nhijos,:)=cmut(i,:);
fc(i+nhijos)=ataqt(a(:,:,i+nhijos),fila(i+nhijos,:),columna(i+nhijos,:)); % evaluo
el funcional de costo
end

for i= 1:nclones

a(:,:,i+nhijos+nmut)=aclon(:,:,i);fila(i+nhijos+nmut,:)=fclon(i,:);columna(i+nhijos+nmut
,:)=cclon(i,:);

fc(i+nhijos+nmut)=ataqt(a(:,:,i+nhijos+nmut),fila(i+nhijos+nmut,:),columna(i+nhijos+nmut
,:)); % evaluo el funcional de costo
end
% ordenar por la funcion de costo
[a,fila,columna,fc]=ordenar(a,fila,columna,fc);
[xx,dim]=size(fc);
% recortar la poblacion al valor pobmax
if dim > pobmax
a=a(:,:,1:pobmax);fila =fila(1:pobmax,:);columna=columna(1:pobmax,:);fc=fc(:,1:pobmax);
end
% disp('funcion de costo luego de operar geneticamente')

fcmin = min(fc);
% pause
if fcmin==0
break
end

end

You might also like