1. Algoritmos Genéticos
Los problemas que pretenden optimizar una función objetivo pueden escribirse de la forma:
min 𝑓(𝑥)
𝑥∈Ω
Donde 𝑥 es un vector de 𝑛 variables y Ω un dominio dónde las variables deben tomar valores.
Los valores de que cumplen 𝑥 ∈ Ω los llamaremos valores válidos. Consideramos que la función
objetivo ℎ es una expresión que devuelve valores reales.
16. Algoritmos iterativos de aproximación 2
Dónde 𝑥, 𝑎, 𝑏 son vectores de valores. Las primeras son restricciones de desigualdad, las
segundas de igualdad y las últimas de rango.
Un problema multiobjetivo puede ser convertido en otro uniobjetivo combinando los diferentes
objetivos:
min 𝑓(𝑥) 𝑟 𝑠
𝑥
𝑔𝑖 (𝑥) ≤ 0, 𝑖 = 1, … , 𝑟 ≡ max( −𝑓(𝑥) − 𝐾(∑(𝑐(𝑔𝑖 (𝑥)))2 − ∑(ℎ𝑗 (𝑥))2 ))
𝑥
ℎ𝑗 (𝑥) = 0, 𝑗 = 1, … , 𝑠 𝑖=1 𝑗=1
𝑎≤𝑥≤𝑏 𝑎≤𝑥≤𝑏
max 𝑓(𝑥) 𝑟 𝑠
𝑥
𝑔𝑖 (𝑥) ≤ 0, 𝑖 = 1, … , 𝑟 ≡ max( 𝑓(𝑥) − 𝐾(∑(𝑐(𝑔𝑖 (𝑥)))2 − ∑(ℎ𝑗 (𝑥))2 ))
𝑥
ℎ𝑗 (𝑥) = 0, 𝑗 = 1, … , 𝑠 𝑖=1 𝑗=1
𝑎≤𝑥≤𝑏 𝑎≤𝑥≤𝑏
0, 𝑧≤0
𝑐(𝑧) = max(0, 𝑧) = {
𝑧, 𝑧>0
Los algoritmos genéticos (GA) son algoritmos iterativos generales de optimización combinatoria.
Son algoritmos probabilísticos cuyo diseño está inspirado en los mecanismos evolutivos que se
encuentran en la naturaleza. Estos algoritmos tienen muchas similitudes, pero también poseen
características distintivas, principalmente en sus estrategias para buscar en el espacio de
soluciones.
𝑆 = {𝑥: 𝑇|Ω(𝑥)}
min 𝑔(𝑥)
𝑥:𝑆
Dónde 𝑇 es el tipo de las soluciones del problema. Al conjunto 𝑆 se le suele llamar espacio de
soluciones del problema. En los algoritmos genéticos que vamos a considerar además un espacio
de valores 𝑉 y una función de transformación 𝑡(𝑣) que toma un valor en 𝑉 y devuelve otro en
𝑇. Cada valor 𝑥 de tipo 𝑇 puede ser obtenido de un valor 𝑣 en 𝑉 tras la aplicación de la función
𝑡. El espacio 𝑉 se escoge para que sus valores se puedan generar fácilmente usando uno de los
cromosomas disponibles.
Un cromosoma es un objeto que tiene un estado interno y una propiedad visible desde el
exterior que produce los valores del espacio de valores asociado al cromosoma. Llamamos
decodificar a la operación consistente en obtener la representación exterior de un cromosoma
a partir de su estado interno.
Para emular la selección natural los algoritmos genéticos usan un conjunto de cromosomas que
llamaremos de forma similar población. Una población va evolucionando a través de tres
operaciones: mutación, cruce y selección.
Por último, definiremos la función de fitness de un cromosoma como una propiedad que toma
un valor real y que define lo bueno que es un cromosoma dentro de la población en la que se
encuentra.
16. Algoritmos iterativos de aproximación 4
Con los anteriores elementos un algoritmo genético evoluciona partiendo de una población
inicial escogida aleatoriamente y de un tamaño fijado. A cada nueva población se le llama
generación. A esta población le aplica operadores de selección, cruce y mutación siguiendo el
esquema:
1. Se escogen los mejores individuos de una población según una tasa de elitismo y se
pasan a la siguiente generación sin modificación.
2. Se repiten los siguientes pasos hasta que la nueva población alcanza el tamaño
prefijado.
a. Con la política de selección escogida se escogen dos cromosomas para pasar a
la siguiente generación. En un porcentaje establecido dado por la tasa de cruce
se aplica el operador de cruce y en ese caso los hijos sustituyen a los padres. Si
no hay cruce los cromosomas escogidos pasan sin modificación a la siguiente
generación.
b. A cada individuo de los dos anteriores se le aplica en un porcentaje establecido
por la tasa de mutación el operador de mutación fijado.
• Número de generaciones
• Tiempo transcurrido
• Que existan en la población un número de cromosomas con las condiciones
especificadas.
Una política de selección muy usada es la denominada elección por torneo. Consiste en
seleccionar sin reemplazamiento un grupo de 𝑛 individuos al azar y de entre ellos escoger el
mejor par. El tamaño del grupo se denomina aridad del Torneo. Una aridad alta implica que los
individuos peores casi nunca son escogidos.
𝑆 = {𝑥: 𝑇|Ω(𝑥)}
min 𝑔(𝑥)
𝑥:𝑆
max 𝑓(𝑡(𝑣))
𝑣:𝑉
𝑥 = 𝑡(𝑣)
16. Algoritmos iterativos de aproximación 5
Donde 𝑓(𝑥) se obtiene a partir de 𝑔(𝑥) incluyendo las restricciones relevantes en la función
objetivo, tal como vimos arriba, y poniendo el problema de optimización en forma de
maximización. Cada cromosoma tiene asociado un valor 𝑣. A partir de ese valor podemos
calcular 𝑓(𝑡(𝑣)). A este valor le llamamos la adecuación del cromosoma. Su fitness.
Hay una amplia gama de problemas combinatorios que pueden ser abordados partiendo de un
catálogo de cromosomas cuyos operadores de cruce y mutación son conocidos y pueden ser
reutilizados. Veamos los tipos adecuados para ser usados en los Algoritmos Genéticos.
Partimos del tipo genérico para construir los espacios de valores que llamaremos
Chromosome<V>:
2.1 ValuesInRangeChromosome<E>
Representa una lista de valores de tipo E que están en un rango. Dispondremos de 3 subtipos:
BinaryChromosome, RangeChromosome y DoubleChromosome. Los detalles específicos para
cada uno de estos cromosomas se indicarán en una implementación del tipo
ValuesInRangeProblemAG<E,S>. Dónde E es el tipo de los elementos del cromosoma y S el tipo
de la solución del problema.
E getMin(Integer i);
Integer getVariableNumber();
S getSolucion(ValuesInRangeChromosome<E> cr)
}
Restricciones:
• n = getVariableNumber();
• d = decode();
• d = decode.size();
• getMin()<= d[i] <= getMax(), i:0..n-1;
2.1.1 BinaryChromosome
Este cromosoma es un caso particular del anterior donde los valores son enteros de mínimo 0 y
máximo 1. Es un cromosoma básico a partir del cual se pueden construir otros más complejos.
Los operadores de mutación son muy conocidos y consisten fundamentalmente en permutar el
valor binario de una casilla escogida al azar.
Usos:
Este cromosoma es adecuado para modelar un amplio abanico de situaciones. Puede ser
considerado el cromosoma básico a partir del cual construir otros. Con él podemos modelar
todos los problemas de Programación Lineal Entera con variables binarias.
En este problema tenemos una lista de agentes 𝐿 y una lista de tareas 𝑇 ambas del mismo
tamaño 𝑛. El coste de que el agente 𝑖 realice la tarea 𝑗 sea 𝑐𝑖𝑗 . Se pretende asignar a cada agente
una tarea y sólo una de tal forma que se ejecuten todas las tareas con el coste mínimo.
Una primera versión del problema es hacer una implementación de la solución propuesta más
arriba mediante la técnica de la Programación Lineal Entera. En la solución asumimos las
variables binarias xij toman valor 1 si el agente i ejecuta la tarea j y cero si no la ejecuta. Decimos
que hemos codificado el problema mediante las variables binarias xij . La solución en
Programación Lineal Entera fue:
16. Algoritmos iterativos de aproximación 7
𝑛−1,𝑛−1
∑ 𝑥𝑖𝑗 = 1, 𝑖 ∈ [0, 𝑛 − 1]
𝑗=0
𝑛−1
∑ 𝑥𝑖𝑗 = 1, 𝑗 ∈ [0, 𝑛 − 1]
𝑖=0
𝑏𝑖𝑛 𝑥𝑖𝑗 , 𝑖 ∈ [0, 𝑛 − 1], 𝑗 ∈ [0, 𝑛 − 1]
Hay otra forma mejor de resolver este problema como veremos más adelante con un
cromosoma de otro tipo.
La razón es que el porcentaje de valores de cromosomas que no son válidos (que no cumplen
las restricciones) es muy alto. En efecto el número total variables es 𝑛2 y de valores posibles es
2
2𝑛 . Dadas las restricciones de igualdad el número de variables libres es 𝑛2 − 2𝑛 y el total de
2
valores válidos, que cumplen lass restricciones, es 2𝑛 −2𝑛. El cociente nos da la probabilidad de
encontrar un valor válido al azar y es:
2 −2𝑛 2
2𝑛 2𝑛 1
2 = 2 =
2𝑛 22𝑛 2𝑛 22𝑛
Una ciudad se compone de 𝑛 barrios. Cada barrio es vecino de otros barrios y la relación de
vecindad se puede representar mediante un grafo no dirigido cuyos vértices representan los
barrios y existe una arista entre dos barrios si son vecinos. Queremos ubicar una estación de
bomberos en algunos barrios con la restricción que en cada barrio o en uno de sus vecinos haya
una estación de bomberos. El objetivo es minimizar el número de estaciones de bomberos. Si
las varaibles binarias 𝑥𝑗 indican si un barrio tendrá estación de bomberos o no y 𝑁(𝑗) los
vecinos del barrio 𝑗, el problema de Programación Lineal Entera era:
16. Algoritmos iterativos de aproximación 8
𝑚−1
min ∑ 𝑥𝑗
𝑗=0
(∑ 𝑥𝑗 ) ≥ 1, 𝑖 ∈ [0, 𝑚)
𝑗:𝑁(𝑖)
𝑏𝑖𝑛 𝑥𝑗 , 𝑗 ∈ [0, 𝑚)
𝑚−1 𝑚−1
𝑓 = − ( ∑ 𝑥𝑗 ) − 𝐾 ∑ 𝜑 (( ∑ 𝑥𝑗 ) − 1)
𝑗=0 𝑖=0 𝑗:𝑁(𝑖)
−𝑢, 𝑥<0
𝜑(𝑢) = {
0, 𝑥≥0
2.1.2 RangeChromosome
Usos:
Es un cromosoma adecuado para resolver problemas cuya solución es un Multiset formado con
elementos de un conjunto dado u otros problemas en los que aparecen variables enteras en un
rango.
Ya lo hemos explicado arriba. Ahora las casillas de la lista decodificada es el número de unidaes
escogido de cada objeto. Si 𝑑 es la lista decodificada entonces la función de fitness es:
𝑛−1 𝑠−1
2.1.3 RealChromosome
Usos:
16. Algoritmos iterativos de aproximación 9
Este cromosoma es adecuado para modelar funciones de varias variables reales del tipo
𝑓(𝑥0 , 𝑥1 , … , 𝑥𝑛−1 ) de las que se quiere obtener el máximo o el mínimo en un dominio.
2.2 IndexChromosome
Sus valores son listas de Integer que se pueden construir a partir de una secuencia normal y
pueden ser usados como índices en una lista de objetos. Dispondremos de 3 subtipos:
• IndexSubListChromosome,
• IndexPermutationChromosome,
• IndexPermutationSubListChromosome.
Los detalles específicos para cada uno de estos cromosomas se indicarán en una
implementación del tipo IndexProblemAG<S>. Dónde S el tipo de la solución del problema.
Restricciones y notación:
• n = getObjectsNumber();
• r = getNormalSequence().size();
• d = decode();
• s = d.size();
• n<=s<=r;
• m(i) = getMax(i);
Cada cromosoma de este tipo tiene asociada una secuencia normal. Esta secuencia está formada
por la concatenación de n sublistas L(i). Cada L(i) se compone de getMaxMultiplicity (i) copias
del entero i, con i en el rango 0..n-1.
2.2.1 IndexSubListChromosome
Usos:
16. Algoritmos iterativos de aproximación 10
Es un cromosoma adecuado para resolver problemas cuya solución es un Multiset formado con
elementos de un conjunto dado.
Se parte de 𝐿, una lista de objetos de tamaño 𝑛, y 𝑚 una lista de enteros del mismo tamaño
dónde 𝑚(𝑖) indica el número de repeticiones posibles del objeto en la posición 𝑖. A su vez cada
objeto 𝑜𝑏𝑖 de la lista es de la forma 𝑜𝑏𝑖 = (𝑤(𝑖), 𝑣(𝑖)) dónde 𝑤(𝑖), 𝑣(𝑖) son, respectivamente,
su peso y su valor unitario. Además la mochila tiene una capacidad 𝐶. El problema busca ubicar
en la mochila el máximo número unidades, siempre que no superen las máximas permitidas
para cada tipo de objeto, que quepan en la mochila para que el valor de los mismos sea máximo.
𝑠−1 𝑠−1
Hemos de tener en cuenta que 𝑑 es un vector cuyas casillas son índices a la lista 𝐿 que se repiten
un máximo indicado en el problema.
2.2.2 IndexPermutationChromosome
Es un subtipo de IndexChromosome cuyos valores son listas de enteros que son permutaciones
de la secuencia normal. Cada entero es un índice a la lista de objetos proporcionada.
Usos:
Como ya vimos en este problema tenemos una lista de agentes 𝐿 y una lista de tareas 𝑇 ambas
del mismo tamaño 𝑛. El coste de que el agente 𝑖 realice la tarea 𝑗 sea 𝑐𝑖𝑗 . Se pretende asignar a
cada agente una tarea y sólo una de tal forma que se ejecuten todas las tareas con el coste
mínimo.
Si asumimos que 𝑑[𝑖] es la tarea asignada al agente 𝑖 la función de fitness se puede escribir
como:
16. Algoritmos iterativos de aproximación 11
𝑛−1
𝑓 = − ∑ 𝑐𝑖𝑑[𝑖]
𝑖=0
Si comparamos esta solución con la que usaba el BinaryChromosome podemos ver sus ventajas.
Aquí todos los valores son válidos y la función de fitness y mucho más simple de escribir.
2.2.3 IndexPermutationSubListChromosome
Es un subtipo de IndexChromosome cuyos valores son listas de enteros que son subconjuntos
de permutacionaciones de la secuencia normal. Cada entero es un índice a la lista de objetos
proporcionada.
Usos:
𝑠−1 𝑠−1
𝑏 𝑡(𝑑[𝑖])
𝑓 = ∑( + 𝑐) − 𝐾𝜑(∑ 𝑡(𝑑[𝑖]) − 𝑇)
𝑖+1
𝑖=0 𝑖=0
0, 𝑥≤0
𝜑(𝑥) = {
𝑥, 𝑥>0
Se parte de 𝐿, una lista de objetos de tamaño 𝑛, y 𝑚 una lista de enteros del mismo tamaño
dónde 𝑚(𝑖) indica el número de repeticiones posibles del objeto en la posición 𝑖. A su vez cada
16. Algoritmos iterativos de aproximación 12
objeto 𝑜𝑏𝑖 de la lista es de la forma 𝑜𝑏𝑖 = (𝑤(𝑖), 𝑣(𝑖)) dónde 𝑤(𝑖), 𝑣(𝑖) son, respectivamente,
su peso y su valor unitario. Además, la mochila tiene una capacidad 𝐶. El problema busca ubicar
en la mochila el máximo número unidades, siempre que no superen las máximas permitidas
para cada tipo de objeto, que quepan en la mochila para que el valor de estos sea máximo.
𝑠−1 𝑠−1
Hemos de tener en cuenta que 𝑑 es un vector cuyas casillas son índices a la lista 𝐿 que se repiten
un máximo indicado en el problema.
𝑛−1 𝑠−1
𝑠−1 𝑠−1
𝑏 𝑡(𝑑[𝑖])
𝑓 = ∑( + 𝑐) − 𝐾𝜑(∑ 𝑡(𝑑[𝑖]) − 𝑇)
𝑖+1
𝑖=0 𝑖=0
0, 𝑥≤0
𝜑(𝑥) = {
𝑥, 𝑥>0
16. Algoritmos iterativos de aproximación 13
El problema puede ser ampliado para tener en cuenta otras restricciones como por ejemplo
que existan anuncios
Dada una función en un rango y con unas restricciones encontrar su mínimo o su máximo.
max ℎ(𝑥)
𝑎≤𝑥≤𝑏, 𝑥∈Ω
𝑓 = ℎ(𝑑) − 𝐾 ∗ 𝑅(𝑑)