• No se han encontrado resultados

2.2 Introducción a los algoritmos genéticos

2.2.1 Codificación de la solución

El proceso de codificación permite la representación de las diferentes soluciones del problema real en individuos que participan en el algoritmo. Cada individuo se representa en forma de un vector numérico (generalmente se utiliza números binarios, pero también pueden ser números enteros o reales dependiendo de las características del problema). El vector de números que define un individuo se denomina cromosoma, mientras que cada elemento que lo compone se le asigna el nombre de alelo. Se llama gen a un conjunto de alelos que codifican una misma característica o parámetro de la solución. La Figura 2.3 muestra un ejemplo de codificación binaria, donde el

cromosoma (10011011) representa a la solución {x= 9;y = 11}. El cromosoma está compuesto

por dos genes (el gen (1001) hace referencia a la variable x y la segunda mitad del cromosoma

o gen (1011) se corresponde con la variable y). Cada bit que compone un gen es un alelo. El

cromosoma (10011011) tiene por tanto ocho alelos.

Se define genotipo (Genotype o Genotipic space) al espacio de individuos, mientras que el

fenotipo (Fenotype oFenotipic space) es el espacio de soluciones al problema real. En el ejemplo

de la Figura 2.3, el vector (10011011) corresponde al genotipo, mientras que la solución {x =

24 Capítulo 2. Estado del arte !"#$%&'" ("#$%&'" ) * * ) ) * ) ) &+)) ,+- ."#"/)/ ."#"/0/ 122"2"3/

Figura 2.3: Ejemplo de codificación binaria. La codificación de la solución se conoce como genotipo. El individuo o cromosoma se compone de un número determinado de genes. El fenotipo se corres- ponde con la solución que representa el cromosoma.

Habitualmente, los genes de un cromosoma son independientes entre sí en el sentido en que el valor que puede tomar un gen no depende de los valores que adquieren otros genes. Sin embargo, existen casos en los que sí se evidencian este tipo restricciones, como por ejemplo en problemas en los que la solución es precisamente el cómo ordenar un conjunto de elementos (cada permutación de genes en el cromosoma es una solución diferente) como es el caso del clásico problema del

viajante (Travelling Salesman Problem). Para asegurar el cumplimiento de estas dependencias

puede ser necesario reparar aquellos individuos que no cumplan las condiciones de dependencia y transformarlos en otros muy similares que además respeten las restricciones impuestas.

Diferenciamos dos tipos de codificación: directa e indirecta. Un algoritmo utiliza una codifi- cación directa cuando cada individuo representa una solución en la realidad de forma inmediata y sin necesidad de realizar transformación alguna. El individuo contiene en sí mismo toda la información necesaria para implementar la solución. Si se requiere de un proceso de conversión para pasar del vector solución (genotipo) a la solución en la realidad (fenotipo), se dice que la codificación es de tipo indirecto. Generalmente, la codificación indirecta es computacionalmente más costosa por el proceso de traducción, conversión o acceso a tablas de datos externos. Si bien es más efectiva porque permite tener mayor conocimiento del problema. Un ejemplo de codificación indirecta es el problema del viajante manejando datos externos como la información sobre las ciudades en cuanto a su posición, ciudades vecinas, distancias entre las mismas, etc.

Existe otra clasificación para la codificación de un algoritmo, dependiendo si el orden en el que aparecen los valores para los genes define unívocamente a una solución o no:

• Codificaciones basadas en el orden, donde el orden en el que aparecen las variables es muy

importante para identificar cada solución. Entre éstas se encuentra la codificación por permutaciones, como es el caso del problema del viajante, y otras codificaciones empleadas por ejemplo, para la resolución de sudokus.

• Codificaciones no basadas en el orden: el orden de las variables no es importante para la

solución en sí misma, que queda identificada por el valor de cada gen. Existen cuatro tipos de codificaciones no basadas en el orden:

– Codificación binaria. Puede tratarse bien de la codificación binaria común (las va-

riables son binarias y por lo tanto adoptan uno de dos valores posibles) o bien de codificación binaria de Gray en el que dos valores sucesivos para una variable difieren únicamente en un dígito. Por ejemplo, un código Gray de dos bits define un conjunto

2.2. Introducción a los algoritmos genéticos 25

– Codificación con valores enteros, el contenido de los genes pertenece al conjunto de

números enteros.

– Codificación con valores reales, análogo al anterior pero las variables solo pueden

tomar valores enR.

– Codificación con valores finitos, donde las variables pueden tomar solo valores perte-

necientes a un conjunto limitado de valores, como puede ser un conjunto de colores

predefinidos, un conjunto cerrado de posiciones en un tablero o un conjunto T de

elementos que definen el tipo de equipos a utilizar.

La elección de una u otra codificación se encuentra muy ligada al tipo de problema sobre el que se desea aplicar. Antes de determinar la forma de representación de las soluciones es conveniente tener en cuenta las características que comentamos a continuación:

• Todas las posibles soluciones al problema deben tener representación en el conjunto de

individuos. Resultaría inaceptable de otra manera, la totalidad de las soluciones posibles deben poderse codificar.

• Todos los individuos posibles deben corresponderse con soluciones factibles. A veces esto

no sucede y aparecen individuos que no representan soluciones viables o válidas. En estas ocasiones se realiza un proceso de reparación del individuo para transformarlo en otro individuo similar pero que sí represente a una solución factible del problema. Es importante considerar que la operación de reparación, en caso de ser necesaria, se realizaría un gran número de ocasiones en cada generación. Por lo tanto, en cuanto a tiempo de ejecución del algoritmo, resulta mucho más ventajoso elegir una codificación que no requiera reparaciones de individuos frente a otra codificación que sí las precise.

• En general, la parte computacionalmente más costosa de un algoritmo genético es el cálculo

de la función de evaluación. Este cálculo se realizará como mínimon veces por generación,

dondenes el número de nuevos individuos. Para calcular el valor defitness de un individuo

es necesario realizar la transformación del mismo a la solución que éste represente. La elección de uno u otro tipo de codificación puede resultar clave para que el cálculo de la función de evaluación sea sencillo, rápido y directo, o por el contrario, resulte tedioso y costoso en términos de computación.

• De la misma manera, el operador de selección de individuos es otra de las partes más

costosas en tiempo de computación. La razón fundamental es que este proceso está basado

en la comparación de los valores defitness.

• La codificación debiera facilitar en lo posible las operaciones de cruce y mutación. Si bien

suelen ser operadores más simples que la selección, también se ejecutan un número muy elevado de veces en cada generación. De modo que, cuanto más sencillas y rápidas sean éstas, más veloz resultará el algoritmo.

• Por último y como se menciona en [82], el método de codificación elegido para un algo-

ritmo genético influye en gran medida en la capacidad del dicho algoritmo para encontrar soluciones de alta calidad. Especialmente afecta sobre el parámetro denominado localidad. El nivel de localidad está muy relacionado con el modo en que una solución (fenotipo) es alterada al aplicar pequeños cambios sobre su cromosoma (genotipo). Mayor nivel de loca- lidad implica menor grado de modificación de la solución tras los cambios realizados sobre el individuo. En general se considera que mayor nivel de localidad favorece la búsqueda de

26 Capítulo 2. Estado del arte

soluciones de más alta calidad porque de forma intuitiva, significa que el algoritmo busca en los alrededores muy próximos a una solución sobre el espacio de soluciones.