CAPÍTULO 2. CARACTERÍSTICAS E IMPLEMENTACIÓN DE LOS
2.9 Operadores genéticos
2.9.3 Mutación
En la Evolución, una mutación es un suceso bastante poco común (sucede aproximadamente una de cada mil replicaciones), como ya se ha visto anteriormente. En la mayoría de los casos las mutaciones son letales, pero en promedio, contribuyen a la diversidad genética de la especie.
La mutación se considera un operador básico, que proporciona un pequeño elemento de aleatoriedad en la vecindad (entorno) de los individuos de la población. Si bien se admite que el operador de cruce es el responsable de efectuar la búsqueda a lo largo del espacio de posibles soluciones, también parece desprenderse de los experimentos efectuados por varios investigadores que el operador de mutación va ganando en importancia a medida que la población de individuos va convergiendo.
Cuando la representación genética consiste en una cadena de bits, el operador de mutación simplemente altera un bit, es decir, lo cambia de 0 a 1 o viceversa. La probabilidad de que un bit sea alterado depende de un parámetro: la probabilidad o tasa de mutación. La cual después de una vez establecida, por ejemplo, uno por mil, se pasa a examinar cada bit de cada cadena cuando se vaya a crear la nueva criatura a partir de sus padres (normalmente se hace de forma simultánea al crossover). Si un número generado aleatoriamente está por debajo de esa probabilidad, se cambiará el bit (es decir, de 0 a 1 o de 1 a 0). Si no, se dejará como está. Dependiendo del número de individuos que haya y del número de bits por individuo, puede resultar que las mutaciones sean extremadamente raras en una sola generación.
Al igual que el cruce, la mutación se maneja como un porcentaje que indica con qué frecuencia se efectuará (probabilidad de mutación), aunque se distingue de la primera por ocurrir mucho más esporádicamente (el porcentaje de cruce, normalmente es de más de 60% mientras que el de mutación es frecuente no supere 5%). Este bajo por ciento en la probabilidad de mutación evita oscilaciones en el promedio de los valores objetivos de la población. Siempre es más conveniente usar otros mecanismos de generación de diversidad, como aumentar el tamaño de la población, o garantizar la aleatoriedad de la población inicial.
En general, la idea detrás de un operador de mutación es la de realizar una alteración o perturbación pequeña al genotipo, para generar un individuo ligeramente distinto pero relacionado con el progenitor, por otro lado, no hace falta decir que no conviene abusar de la mutación. Es cierto que es un mecanismo generador de diversidad, y, por tanto, la solución cuando un algoritmo genético está estancado, pero también es cierto que reduce el algoritmo genético a una búsqueda aleatoria.
Figura 2.2. Mutación de un individuo.
Implementación de la función de Mutación
Aquí en particular el código es una modificación de la función
(mutationadaptfeasible). Esto permite aprovechar las constantes y variables de los algoritmos del MATLAB. La parte de mayor interés se muestra a continuación.
if(strcmpi(options.PopulationType,'bitString')) mutationRate = 0.01; % default mutation rate
for i=1:length(parents)
child = thisPopulation(parents(i),:); Co_Tree_Child = find(child==0);
mutationPoints = find(rand(1,length(Co_Tree_Child)) < mutationRate); for ii=1:length(mutationPoints)
Closed_Branch = Co_Tree_Child(mutationPoints(ii)); branch_data = ga_mpc.branch;
branch_data(:,11) = 1;%First Close All lines
branch_data(Co_Tree_Child,11) = 0; %Open lines of Co-Tree Child
Radial_Net = child; % Child to mutate
[B] = GetBranchsInLoop(Closed_Branch, Radial_Net, branch_data); loop_branch = B;
open_branch = loop_branch(ceil(length(loop_branch).*rand(1,1))); Co_Tree_Child(mutationPoints(ii)) = open_branch;
child(Closed_Branch) = 1;% Toggle state
child(open_branch) = 0;% Toggle state
end; %for ii
mutationChildren(i,:) = child; end
return;
end
Figura 2.3. Fragmento de código para el cruzamiento
El proceso de mutación tiene lugar en la información genética de los padres y estas mutaciones serán luego transmitidas a los hijos. La probabilidad de que se efectué una mutación se toma en cuenta con la variable mutationRate. Los individuos mutados se almacenan en mutationChildren, variable que es devuelta por la función que implementa el operador de cruzamiento.
Para obtener los individuos mutados hace un recorrido por todos los padres (parents) de la iteración en curso del algoritmo genético. Se toma la información genética del padre ‘i’, y
se almacena en la variable ‘child’. A esta información se le halla el co-árbol
correspondiente que se conforma con los elementos que están desconectados en el grafo de la red reconfigurada.
Los puntos de mutación (mutationPoints) se obtienen formando un vector aleatorio de tamaño igual a los elementos del co-árbol. Los puntos de mutación serán los elementos del co-árbol de las posiciones del vector aleatorio que sobrepasen la probabilidad de mutación (mutationRate). Si en este proceso no aparece ningún punto de mutación, no se afecta la información genética y se procede a analizar la información del individuo siguiente.
Cuando se crean puntos de mutación se hace un recorrido mediante otro ciclo for para cada uno de ellos y se efectúan los pasos siguientes.
1. El punto de mutación ‘ii’ dentro del co-árbol se guarda en Closed_Branch.
2. Se encuentran todas las ramas del ciclo que se forma al cerrar Closed_Branch y se almacenan en loop_branch.
3. Se toma aleatoriamente en open_branch una las ramas de loop_branch.
4. Se abre open_branch y se cierra Closed_Branch, afectando la información genética del individuo que está siendo mutado.
El proceso termina cuando se ha recorrido la información genética de todos los padres. Es posible o probable que en todo este recorrido no se afecte ningún individuo. Una tasa de mutación alta o baja afecta el proceso mediante la creación o no de puntos de mutación.