Applet para Algoritmo Genético

Anuncio
Universidad Autónoma Metropolitana
Unidad Iztapalapa
'
División de Ciencias Básicas e Ingeniería
i
'
Licenciatura en Computación
Applet para Algoritmo Genético
Se implementa un algoritmo genético en un applet que sea capaz de ejecutarse
en un explorador y medir su tiempo de respuesta, así como graficar los
resu1tados.
P e g i n a Inés González Flores
92320586
Para la obtención del grado de Licenciatura en Computación
Asesor :
John Goddard Close
Indice
Introducción...........................................................................
2
Algoritmos Genéticos................................................................
3
Operación del applet..................................................................
8
Un ejemplo: xSen(x) ..................................................................
11
. . de resultados................................................................
Análisis
13
Conclusiones...........................................................................
16
Trabajos Futuros.......................................................................
17
Apéndice A.. ............................................................................
18
Apéndice B.............................................................................
22
Referencias. ...........................................................................
34
Introducción
El avance en la tecnología obliga a que los sistemas computarizados de datos se
desarrollen en plataformas que permitan su ejecución a través de internet mediante
“buscadores”, así surgió la idea de desarrollar un applet de Java que ejecute un
algoritmo genético, para observar el tiempo de ejecución y los resultados gráficos.
En el presente trabajo se ha conjuntado la idea de los Algoritmos Genéticos con la
programación orientada a objetos, y las aplicaciones que se ejecutan en los
exploradores de la internet, que día a día tienen mayor influencia en los métodos de
programación.
En este documento se presenta una introducción a lo que son los Algoritmos
Genéticos, y la explicación de como fue programado el applet que contiene un
ejemplo de Algoritmo Genético.
Este applet esta conformado por 8 clases:
Genotype
GeneticAigorihm
FuncXSinX
GenerationGraph
FunctionGraph
DrawControls
OptionsGA
Prueba
Las 6 primeras clases contienen la operación y gráfica del algoritmo
y la función
xSen(x), las dos Últimas clases (OptionsGA y Prueba) controlan la operación en lo que
corresponde a valores parametrizables dinámicamente y arranque del AG.
Para la ejecución de este applet es necesario tener un archivo de texto gadata.ixt que
contiene el domino en el cual se toman los posible valores para x.
Para los gráficos se han utilizado las librerías awt de java versión 1.2.1.
Al final de este documento en los apéndices A y B se incluye el código del applet.
Aigoritmos Genéticos
Imitación del comportamiento de la naturaleza
Los algoritmos genéticos son métodos adaptables que permiten resolver problemas de
búsqueda y optimización.
L o s AG están basados en una imitación de los procesos naturales, teoría de la
evolución de Charles Darwin.
En la teoría de la evolución, los seres vivos están formados por estructuras de genes
que contienen características de generaciones anteriores a ellos.
De acuerdo con la teoría de la evolución, existe un número limitado de condiciones
que permiten que la evolución ocurra :
0
Las estructuras deben ser capaces de reproducirse
0
Las estructuras de la población deben ser purificadas
0
Deben tener algunos errores en la reproducción para permitir que ocurran cambios
(mutación)
En la teoría de la evolución, para que un ser biológico adquiera las características que
lo representan, debieron pasar muchos años, y muchas generaciones antes de él, es
decir que cada ser biológico es producto de todo un proceso un tanto aleatorio de
generaciones que le preceden.
Imitando estos procesos, los AG son capaces de encontrar soluciones a problemas del
mundo real, si tienen un código óptimo. Por ejemplo pueden ser usados para diseiíar
puentes, para marcar procesos de control tales como hacer balances sobre un sistema
de cómputo de múltiple proceso.
Surgen los Algoritmos Genéticos
3
La primera publicación acerca de los AG es de Hollad en 1962', la estructura
matemática se desarrolla en los 60's y es publicada en uno de sus libros en 1975.
L o s algoritmos genéticos son probados en dos áreas : optimización y aprendizaje
maquinal. En aplicaciones de optimización han sido usados en diversos campos, tales
como funciones de optimización, procesamiento de imágenes, el problema del agente
viajero, sistemas de identificación y control. En aprendizaje maquinal han sido usados
en aprendizaje de sintácticas simples como IF-THEN en ambientes arbitrarios.
Bases de Algontmos Genéticos.
El AG es representado de la siguiente manera :
EMPIEZA
genera población inicial
calculafitness de cada individuo
MIENTRAS NO termina HAZ
EMPIEZA
/* Produce una nueva generación */
PARA tamaiíojoblación HAZ
EMPIEZA
/* Ciclo reproductivo */
selecciona dos individuos de la generación vieja por porcentaje
/* basado en favor de los de mejorfitness */
combina los dos individuos para dar dos hijos
calcula elfitness de los dos hijos
inserta a los hijos en la nueva generación
TERMINA
SI la población ha convergido ENTONCES
termina-erdadero
TERMINA
TERMINA
'pp 382 Capitulo 14 Genetic Algorithms
4
La selección natural es la liga entre los cromosomas y el desarrollo de sus códigos
estructurales. Procesos de selección natural originan que cromosomas con mejores
características se reproduzcan más frecuentemente que otros con peores
características. La reproducción y mutación provocan que los hijos tengan estructuras
diferentes a los padres, y el cruzamiento obliga a su vez a que los hijos contengan
códigos estructurales de ambos padres. Es precisamente con éstas características de la
evolución natural que se desarrollan los AG.
L o s AG manipulan con cadenas de ceros y unos (dígitos binarios) llamados
cromosomas, cada bit del cromosoma es llamado allele, mediante codificación, estos
cromosomas son expuestos a los mecanismos del proceso de evolución natural que
son: selección, cruzamiento y mutación. La única información que otorgan es
mediante la evaluación de una función que representa al problema. Es mediante esta
evaluación que se determina que cromosomas se reproducen más fkecuentemente que
otros.
Los algoritmos genéticos manejan poblaciones de cromosomas, que forman una
generación. Si el AG está bien diseñado, la población converge a una solución óptima
del problema.
L o s AG’s no garantizan encontrar la solución global óptima del problema, pero si
encuentran una solución aceptablemente buena, en un tiempo aceptablemente corto.
Los problemas están representados por un conjunto de parámetros, los AG representan
estos parámetros mediante genes, que son partes del cromosoma. Es decir que si
tenemos una función que depende de 2 parámetros, y representamos cada parámetro
por medio de 10 números binarios cada uno, tendremos cromosomas de tamaiío 20,
con dos genes. Mediante esta representación tenemos oportunidad de representar un
conjunto amplio de problemas que dependen de un numero variable de parámetros,
que irán evolucionando de manera conjunta, y dependiendo unos de otros.
El fitness, es el valor que toma el cromosoma al ser evaluado en la función que
caracteriza al problema. Por ejemplo, en un problema de máximos la función
característica será la suma de cada uno de los parámetros, por lo tanto el fitness será el
resultado de esta suma, y para este caso nos interesará el cromosoma que nos
proporcione el mayor fitness. L o s AG se basan para realizar sus procesos de selección
en el fitness de cada cromosoma, otorgando mayor posibilidad de ser seleccionados a
aquellos que otorguen los mejores fitness.
Para reproducirse los AG emplean métodos de reproducción, cruzamiento y mutación.
La reproducción es un método en el que un cromosoma es seleccionado por su fitness
para formar parte de la nueva población. Uno de los métodos de reproducción
conocidos es el método de la ruleta, que consiste en realizar algo así como una ruleta,
en la cual cada rebanada corresponderá al valor obtenido en el fitness de cada uno de
los cromosomas, de forma tal que los mejores cromosomas tengan mayor posibilidad
de ser seleccionados para reproducirse, sin dejar de tener un valor puramente
probabilístico.
El cruzamiento consiste en seleccionar un par de cromosomas, y en los genes de cada
uno de ellos elegir un punto de cruzamiento aleatorio, separando de esta forma al gene
en dos partes que podemos llamar cabeza y tallo2, intercambiando los tallos de cada
uno de ellos, de esta forma los genes sufien una pequeña deformación, que será
reducida conforme la solución sea mejor. No es conveniente realizar mutación cada
vez en todos los cromosomas de la población, por este motivo la determinación de
efectuar o no la mutación se asocia a una probabilidad que la mayor de las veces
oscila entre 0.6 y 1.
Observemos el siguiente ejemplo
Sean los cromosomas :
(1101011001)y
(0111010011)
y el punto de cruzamiento 6
quedan los cromosomas
(1 10101001 1) y
( O 1 1101 1001)
La mutación es aplicada a cada hijo, después del cruzamiento. La mutación es una
perturbación en el cromosoma que cambia las características de éste. Debido a que no
es recomendable hacer mutación con los genes, pues esto provocaría la perdida de la
información acumulada a lo largo de la evolución, ésta tiene asociada una pequeña
probabilidad, comúnmente 0.001. En este caso se eligen uno o varios puntos de
mutación, o se elige que genes del cromosoma mutarán.
Observemos el siguiente ejemplo :
Sea el cromosoma ( 1 1 O O O 1 O 1 1 O ) con puntos de mutación 5 y 7 , obtenemos
así el cromosoma
(1100111110).
Para el caso de genes sea el cromosoma de dos genes de tamaño 5-bits cada uno
(0110100110)
si mutamos el segundo gene obtenemos :
(0110111001)
Tanto de cruzamiento como de mutación existen diversos métodos, dependiendo del
tipo de datos tratados en los cromosomas.
'Tal como lo hacen Beasley, Bull y Martinen su articulo An overview of Genetic Algorithms
Operación del applet
El applet esta formado por las clases GenerationGraph,FunctionGraph,DrawControls
y OptionsGA, que forman la parte gráfica de la ejecución del algoritmo; y la parte de
la operación lógica del algoritmo está en la clase GeneticAlgorithm y el caso
particular de la operación en la clase FuncXSinX.
BestFitness: 32.891774t BestMember: 32.935303:
MAX GENERATIONS
Applet started.
I
r
POP SIZE
PXOVER
PMUTATION
1.005
-
La estructura genotipo (clase: genotype)
En el programa realizado se define la clase genotype para instanciar objetos que han
de almacenar los resultados de la población actual. Esta estructura fue tomada del
libro de Michalewicz.
La clase tiene los siguientes atributos:
Double
Double
Double
double
double
double
gene [I
fitness
upper [ I
lower [ I
rfitness
cfitness
gene[]
Esta estructura contiene los valores para cada uno de las variables de la función
objetivo, así el arreglo gene tendrá 3 valores si la función objetivo es de 3 variables,
XI, x2, x3.
fitness
En esta variable se guardará el resultado de la evaluación de la función objetivo para
los valores almacenados en gene[].
upper[]
En este arreglo se guardan los valores máximos que podrán tener cada una de las
variables almacenadas en gene[].
lower[]
En este arreglo se guardan los valores mínimos que podrán tener cada una de las
variables almacenadas en gene[].
rfiíness
Esta variable contendrá el porcentaje del valor del fitness de este genotipo con
respecto a los demás fitness del total de la población, este valor será utilizado al
aplicar el método de la ruleta para la selección.
cfitness
Esta variable almacena el valor porcentual acumulado para la selección.
Ejecución
La operación del algoritmo inicia en un objeto tipo Prueba, que hereda de la clase
applet, genera y contiene los objetos:
0
ga que es de la clase FuncXSinX que es el objeto que tiene definido los valores
(genotype) y el comportamiento del Algoritmo Genético (AG);
gg que es de la clase GenerationGraph, hereda de Canvas y es el objeto que dibuja
la gráfica de generaciones;
fg que es de la clase FunctionGraph, hereda de Canvas y es el objeto que dibuja la
gráfica de la función y el punto en el que se localiza el mejor miembro (fitness),
oga que es de la clase OptionsGA que hereda de Panel, panel que muestra los
resultados de “Best Member” y “Best Member”,
dc que es de la clase Drawcontrols hereda de Panel y recibe como parhetros los
objetos gg, fg, ga y oga, este objeto es el que controla la operación del AG, limpia
las gráficas y los genotipos para comenzar una nueva ejecución cada vez que el
botón “start GA” es presionado.
Valores de los parámetros
MAX GENEMTIONS
Este parhetro se utiliza para definir dinámicamente el número de generaciones que
serán ejecutadas.
POP SIZE
Este parámetro sirve para definir el tamaño de la población.
PXOVER
Este parámetro define el factor de cruzamiento.
PMUTATION
Este
parámetro
define
el
factor
de
mutación.
Un ejemplo xSen(x)
Se ha escogido maximizar la función xSen(x) para hacer el applet que ejecute el AG
porque tiene máximos y mínimos locales, lo que hace la convergencia más lenta que
cuando la función tiene un máximo y/o mínimo Único global.
La clase en la que se codifica la función es FuncXSinX que hereda de la clase
GmeticAlgorithm todo el comportamiento del algoritmo e implementa las funciones
evaluate(), getAverage() y keepTheBest().
public void evaluate0
I
double x[] = new double [NVARC+ll;
for (int mem=O; mem<POPSIZE; mem++) {
1
1
for (int i=O; ieNVARS; i++)
x [i+i]=population[meml .gene[il ;
population [mem] .fitness=x111 *Math.sin (x111 1;
En este método se guarda en la variable fitness de cada miembro de la población el
resultado de la evaluación de xSin(x).
public void keepTheBest0
{
int cur-best=O;
for (int mem=O; mem<POPSIZE; mem++){
if (population[mem].fitness>population[POPSIZE] . fitness) {
cur-best=mem;
population[POPSIZE] .fitness=population[mem] .fitness;
1
I
for (int i=O; icNVARS; i++)
population [POPSIZE].gene [i]=population[cur-best1 .gene[il ;
1
En este método se identifica cual es el mejor miembro de la población y se guarda en
el Último genotipo (population [POPSIZE] de la población.
public Double getAverage0
{
double sum=0.0;
Double average
;
for (int mem=O;mem<POPSIZE ;mem++
{
sum = sum
+ population[meml.fitness;
1
average = new Double(sum/POPSIZE);
return (average);
1
Este método regresa el valor promedio de esta generación de la población.
+.
Análisis de resultados
Los parámetros que tienen mayor impacto para la convergencia del máximo valor de
esta función son el número de generaciones y el tamaño de la población.
1O0 generaciones, 1O miembros de población
Digamos por ejemplo que tenemos 100 generaciones con una población de tamaño 10,
un factor de cruzamiento de 0.8 y un factor de mutación de 0.15, en la primera
ejecución esto es lo obtenido:
Best Fitness:
1
MAX GENERATIONS
Ikppiet started.
1100
POP S E
32.9984941 Best fflember:
110
PXOVER
-33.031283
PMUTATION
10.15
1O0 generaciones, 1O0 miembros de la población
Movamos ahora el tamaño de la población, digamos a 100, esto es lo que tenemos:
Best Fitness:
POP SIZE
MAXQENERATIONS
Max.
Pop Size
33.001234t Best Member:
-33.023192
(100
PXOMR (o8PMüTATlON
Best
Best Member
Fitness
Generations
1O0
10
32.9984
-33.03
1O0
100
33.O0123
-33.023
Con el incremento en el tamaño de la población el “Best Fitness” es más cercano al
valor máximo de la función.
10 generaciones, 100 miembros de la población
Cuando disminuimos el número de generaciones, digamos a 10 y dejamos un número
grande en el tamaño de la población 100, este es el resultado que obtenemos:
Max.
Best
Pop Size
Best Member
Fitness
Generations
10
1O0
32.983155
-33.O5 0635
10
1O0
32.915926
32.94483O
10
1O0
33.O013471
-33.022612
10
1O0
33.O00857
-33.024819
10
1O0
33.O00452
-33.O07747
10
100
32.993539
32.9945503
Lo que observamos de estos resultados es que se acerca al máximo, pero no siempre
converge.
1O0 generaciones, 1O miembros de la población
Hagamos el caso contrario generaciones 1O0 y tamaño de la población 1O.
Max.
Pop Size
Best
Best Member
Fitness
Generations
1O0
10
32.9990560
-33.003957
1O0
10
32.998926
-33.O30338
100
10
32.996682
33.034708
1O0
10
32.982286
-33.051406
1O0
10
32.926173
33.0846351
1O0
10
32.9960021
33.035834
Aquí los brincos en los datos son menores, esto se debe a que en este algoritmo se
aplica la función "keep the best" que implica que las generaciones siempre conservan
al mejor miembro de la generación anterior, de esta manera conforme se van dando
nuevas poblaciones, siempre existe al menos el mejor miembro de la generación
anterior.
15
Conclusiones
El algoritmo genético implementado en un applet se ejecuta correctamente, el
problema observado es la manera en como se dibuja, no se hace segmento por
segmento, se dibuja toda al final de la ejecución del algoritmo, este problema puede
ser por haber hecho la gráfica con las librerías awt, se debería hacer otra función con
swing para ver si el problema se resuelve.
Utilizando el método “keep the best” la función converge pronto.
La utilización de clases resuelve de manera sencilla la relación entre el algoritmo
genético y sus gráficas de resultados, tanto la de fitness y average a lo largo de las
generaciones como la de la función y su mejor resultado.
Trabajos fbturos
Hay mucho trabajo por hacer partiendo de la idea de implementar Algoritmos
Genéticos con applets, algunos que identifico son:
0
hacer otras funciones para evaluar el desempeño del AG con otras funciones,
cambiar las funciones que grafican para hacerlas con swing en vez de awt como
están desarrolladas actualmente, con esto se intenta mejorar la manera de graficar
y que sea punto a punto, actualmente se grafican todos los resultados de una sola
vez,
implementar otros tipos de datos para los valores del AG,
implementar más tipos de métodos del AG (cruzamiento, mutación, selección,
etc).
Apéndice A. Estructura de las clases
La aplicación se encuentra distribuida en 7 archivos java:
GeneticA1gorithm.java
FuncXSinX.java
Generati0nGraph.java
Functi0nGraph.java
DrawContro1s.java
0ptionsGA.java
Prueba.java
GeneticAigorithnjava
Clase:
Genotype
Atributos:
double
double
double
double
double
double
Clase:
GeneticAlgorithm
Atributos:
Static int POPSIZE
Static int MAXGENS
Static int W A R S
Static float PXOVER
Static float PMUTATION
Static Genotype population [ I
Static Genotype newPopulation[l
Static Printstream ps
Static FileOutputStream f o s
Int generation
Métodos:
Abstract public void evaluate0
public void initilize0
public void select O
public void crossover0
public void mutate O
public void elitist O
double randval(doub1e
low,double high)
void xover (int one,int two)
void report O
void openReportFile0
void bestResultsReport0
void closeReportFile0
public void runGA0
gene [ I
fitness
upper [ I
lower [ 1
rfitness
cfitness
Genotype
Esta clase contiene la estructura de datos que forman los genotipos.
GeneticAigorithm
Esta clase contiene el comportamiento genérico de los algoritmos genéticos, definidos
en los métodos evaluate, initialize, select, crossover, mutate, elitist y runGA.
FuncXSinX.java
Clase:
FuncXSinX
Métodos
FuncXSinX (
public void evaluate0
public Double getAverage0
public void keepTheBest0
FuncXSinX
Esta clase hereda de GeneticAlgorith, presenta el caso particular de la función
xSen(x), en esta clase se define la función evaluate que es abstract en
GeneticAlgorithm.
Sus métodos son propios de la función.
Generati0nGraph.java
Clase:
GenerationGraph Atributos:
Métodos:
Int xMax
Int yMax
int segMaxSize
Vector 1ineGraph
Vector averageLine
Public GenerationGraph(int
xMax, int yMax)
public void paint(Graphicc g)
private void
drawAxes (Graphics g)
private void
drawGraphic (Graphics g)
GenerationGraph
Esta clase es la que dibuja la gráfica de la evolución de generaciones, para dibujar
utiliza funciones de awt.
FunctionGraph.java
Clase:
GenerationGraph Atributos:
Métodos:
double value
public FunctionGraphO
public void paint(Graphics g)
double f (double x)
FunctionGraph
Esta clase dibuja la gráfica de la función y el comportamiento del mejor resultado.
DrawContro1s.java
Clase:
DrawControls
Atributos:
Métodos:
FuncXSinX ga
GenerationGraph gg
FunctionGraph fg
OptionsGA oga
TextField maxGen
TextField pxOver
TextField pMutation
TextField populationSize
public
DrawControls (GenerationGraph
gg, FunctionGraph fg,
FuncXSinX ga, OptionsGA oga)
public void
actionPerformed(ActionEvent
ev )
public void runGA()
DrawControls
Esta clase es la clase controladora, comienza el AG y guarda los resultados en las
clases GenerationGraph y FunctionGraph para después dibujarlos.
0ptionsGA.java
Clase:
OptionsGA
Atributos:
Label bestFitness
Label bestMember
Métodos:
public OptionsGAO
public void
actionPerformed(ActionEvent
ev )
public void
paintResults (String
labelBestFitness, String
1abelBestMember)
OptionsGA
Esta clase dibuja los valores para "Best Fitness" y "Best Member"
Prueba.java
Clase:
Prueba
Atributos:
GenerationGraph gg
FunctionGraph fg
DrawControls dc
FuncXSinX ga
OptionsGA oga
Métodos:
Public void init0
Public void destroy (1
Prueba
Esta clase es la que distribuye las gráficas en el applet.
Apéndice B. Código
import
import
import
import
java.io.*;
java.util.Date;
java.lang.Math;
java.util.Random;
class Genotype {
double gene [I ;
double fitness;
double upper [ I ;
double lower [I ;
double rfitness;
double cfitness;
1
abstract class GeneticAlgorithm {
static int POPSIZE = 50;
static int MAXGENS = 1000;
static int WARS = 1;
static float PXOVER = (float) 0.8;
static float PMUTATION = (float) 0.15;
static Genotype population[];
static Genotype newPopulation[l;
static Printstream ps;
static Fileoutputstream fos;
int generation = O;
abstract public void evaluate();
public void initilize (1 {
File infile = new File ("GAData.txt");
Double lbound,ubound;
String lineaLeida =
int posseparator = O;
population = new Genotype[POPSIZE+lI;
newPopulation = new Genotype[POPSIZE+lI;
i
i
i
i
;
try {
BufferedReader br = new BufferedReader(new FileReader(infile1);
for (int i=o;icNvARS; i++){
if ((lineaLeida=br.readLineO)!=null)
posseparator = lineaLeida.indexOf(l%');
-lbound
Double.valueOf(lineaLeida.substring(0,posSeparator) 1;
-ubound
Double.valueOf(lineaLeida.substring(posSeparator+l) 1;
for (int j=O;j<=POPSIZE;j++)
{
if (i==O){
population[j] = new Genotype() ;
population [ j1 . lower = new double [31;
population [ jI .upper = new double [31 ;
population [ jI .gene = new double 13 I ;
popuiation[jl .fitness=O;
population[jl .rfitness=O;
population[jl .cfitness=O;
newPopulation [j1 = new Genotype 0 ;
newpopulation [ j1 . lower = new double [31 ;
newPopulation[jl .upper = new double 131 ;
newpopulation [ jI .gene = new double [31 ;
newPopulation[jl.fitness=0;
new~opulation[jl.rfitness=O;
new~opulation[jl.cfitness=O;
1
if (j! =POPSIZE) {
22
population [ j]. lower [i] = lbound .doublevalue (I ;
population [ j].upper[ i] = ubound.doublevalue ( ;
population [ j1 .gene[il
this.randval(population[j] .lower[il ,population[jl .upper[il);
1
1
new~opuiation[j].lower[il = O. O;
newPopulation[jl .upper[il = 0.0;
new~opuiation[j].gene[il = 0.0;
public void select 0 {
double sum=O;
for (int mem=O; memePOPSIZE; mem++)
sum+=population[mem].fitness;
for(int mem=O; memePOPSIZE; mem++)
popu~ation[mem].rfitness=popu~ation[mem].fitness/sum;
population[^] .cfitness=population[0].rfitness;
for(int mem=l;memePOPSIZE;mem++)
population[mem] .cfitness=population[mem11 .cfitness+population[mem] .rfitness;
for (int i=O; iePOPSIZE; i++){
double p;
p = Math.random~)%1000/1000.0;
if (pepopulation[O1 .cfitness)
newpopulation [i]=population[O1 ;
else {
for(int j=O; j<POPSIZE; j++)
if (p>=popuiation[ j] .cfitness&&pepopulation [ j+i] .cfitness)
newpopulation [il=population[ j+11 ;
public void crossover0 {
int one=0;
int first=O;
double x;
for (int mem=O; memePOPSIZE; mem++) {
x=Math.random()%1000/1000.0;
if (xePXOVER) {
++first;
if (first%2==0)
xover (one,mem) ;
else
one=mem;
public void mutate 0 {
double lbound,hbound,x;
for(int i=O;i<POPSIZE;i++)
for(int j=o;jeNvARs; j++) {
x=Math.random()%1000/1000.0;
if (x<PMUTATION){
lbound=population[il .lower[ j1 ;
hbound=population[il .upper[ jI ;
population [ i] .gene [ j] =randVal(lbound,hbound) ;
1
1
1
23
public void elitist 0 {
double best,worst;
int bestmem = O;
int worstmem = O;
worst=best=population[Ol .fitness;
for(int i=O; icPOPSIZE; i++) {
if (population[i] .fitness>population[i+i].fitness) {
if (population[i].fitness>=best) {
best=population[i] .fitness;
bestmem=i;
1
if (population[i+i].fitnessc=worst) {
worst=population[i+il .fitness;
worstmem=i+l;
1
}
else {
if (population[i].fitness<=worst) {
worst=popuiation[i].fitness;
worstmem=i;
1
if (population[i+i].fitness>=best) {
best=population[i+i].fitness;
bestmem=i+l;
if
(best>=population[POPSIZE].fitness) {
for(int i=O; icNVARS; i++)
population [POPSIZE].gene[il=population[bestmeml .gene[il ;
populat~on[POPSIZE].fitness=population[best~mem].f~tness;
1
else {
for(int i=O; icNVARS; i++)
population [worstmem].gene[il=population[POPSIZE].gene [il;
populat~on[worst~mem].f~tness=populat~on[POPSIZE].fitness;
1
1
double randval(doub1e low,double high) {
double val = O;
val = (double)( (Math.random0* (high-low))+low) ;
return (val);
1
void xover (int one,int two) {
int point ;
double temp;
if WARS>^) {
if ( N V A R S = = 2
point=i;
else
point= (int)(Math.random0% ( W A R S - 1 ) +l;
for(int i=O; icpoint; i++) {
/ / *********** SWAP
temp = population [one].gene[il ;
populationlone] .gene[il = population[twol .gene[il ;
population [two].gene[il = temp;
1
\J
1
void report 0 {
double best-val = O;
double avg = O;
double stddev = O ;
double
double
double
String
sum-square = O;
square-sum = O;
sum = O;
reportline;
sum = sum-square=O.O;
for(int i=O; iePOPSIZE; i++){
sum+=popuiation[i] .fitness;
sum~square+=population[i].fitness*population[i].fitness;
I
avg=sum/(double)POPSIZE;
square-sum=avg*avg* (doub1e)POPSIZE;
stddev=Math.sqrt((sums9uare-square-square-sum)/(POPSIZE-l));
best-val=population[POPSIZE] .fitness;
reportLine = generation +
11 + best-val
+ 11
+ avg
s tddev ;
ps.println(reportLine);
ps.flush0;
+
+
1
void openReportFile (1 {
try {
fos = new FileOutputStream(new File ("Resultados.txt"))
ps = new PrintStream(fos1;
;
1
catch (Exception e) {
System.out .println("Exceptiongeneral
I
1
+ e) ;
void bestResultsReport 0 {
ps .println( llSimulation completed");
ps.println("Best member:");
for (int i=O; icNvARS; i++)
ps .println(i + 11=11 + population [POPSIZE].gene[ill ;
ps.println(llBest fitness=I1 + population[POPSIZE] .fitness);
ps.println0;
;
ps .println(llSuccessll)
1
void CloseReportFile (1 {
try {
fos.close0 ;
1
catch (Exception e) {
System.out.println("Exceptiongeneral
1
I
+ e) ;
public void runGA0 {
openReportFile (1 ;
while (generationeMAXGENS) {
generation++;
select 0 ;
crossover(1 ;
mutate 0 ;
report 0 ;
evaluate ( ) ;
elitist ( ) ;
1
1
1
bestResultsReport 0
closeReportFile 0 ;
;
class FuncXSinX extends GeneticAlgorithm {
25
FuncXSinXO {
initilize 0 ;
evaluate 0 ;
keepTheBest(
1
;
public void evaluate 0 {
double x[l = new double [NvARS+lI;
for (int mem=O; memcPOPSIZE; mem++) {
for (int i=o; icNvARs; i++)
x [i+i]=population[meml .gene[il ;
population [mem].fitness=x[ll*Math.sin(x [ll )
;
public Double getAverage0
{
double sum=0.0;
Double average ;
for (int mem=O;memcPOPSIZE ;mem++
{
sum = sum + population[mem].fitness;
1
average = new Double(sum/POPSIZE);
return (average);
1
public void keepTheBest0 {
int curbest=O;
for (int mem=O; memcPOPSIZE; mem++) {
if (population[meml , fitness>population[POPSIZEI.fitness) {
cur-best=mem;
population[POPSIZEl.fitness=population[meml.f~tness;
1
1
1
1
for (int i=o; icNvARS; i++)
population [POPSIZE] .gene[il =population[cur~bestl.gene[i];
import java.awt.*;
import java.awt.Graphics;
import java.uti1.Vector;
public class GenerationGtaph extends Canvas {
int xMax;
int yMax;
int segMaxSize;
Vector 1ineGraph = new Vector();
Vector averageLine = new Vector();
public GenerationGraph(int xMax, int yMax)
{
setsize (400, 400) ;
setBackground(Color.gray) ;
this.xMax = xMax;
this.yMax = yMax;
SegMaxSize = 15;
1
public void paint (Graphics g)
{
drawAxes (9);
drawGraphic (9)
;
private void drawAxes(Graphics g)
{
int valLabel = O;
Font sizedFont;
int xl, x2, yl, y2;
double yFactor = 0.0, yDelta = 0.0;
int len = O, skip = 1, current = 1;
len
=
(int)(getsize().width-40);
-new
sizedFont
g.getFont 0 .getstyle0 , 8 ) ;
g.setFont(sizedFont);
Font (g.getFont ( ) .getName ( 1 ,
/ / Horizontal
g.drawLine(20, getSize().height - 20, getSizeO.width 20, getsize0 .height - 20);
if (xMax e = len)
{
if ( (len/xMax) c segMaxSize)
{
skip = (int)(segMaxSize/(len/xMax) ;
1
for (int i=l;ic=xMax;i++,current++)
{
if (current == skip)
{
.drawLine(((int)(i*(len/xMax) )+20,getSizeO.height
i*(len/xMax)))+20, getsize0 .height - 19);
g .drawstring ( I’ I’ +i ,
i* (len/xMax)) ) +la, getsize (1 .height - 10) ;
current = O;
1
else
{
1
19
I
1
for(int i=20; ie=getSize( ) .width-20; i= i+20)
{
getsize (1.height - 21) ;
g.drawLine(i,
getsize0 .height
valLabel
20)/20)* (flax/( (getsize0 .width-lO)/20)1 ;
g.drawString ( lllv+valLabel,
getsize() .height - 10) ;
1
-
-
19,
i,
(int)( (ii-4,
1
/ / Vertical
g.drawLine(20, 20, 20, getsize0 .height - 20);
yFactor = (getsize0 .height - 40) / 20;
yDelta = yMax / 20;
for (int i=l;ic=2O;i++)
{
xl = 19;
x2 = 21;
y1 = y2 = (int)( (getsize().height-20)- (i*yFactor)
g .~drawLine
(xi, yl, x2, ~ 2 ;)
g.drawString(It1l+(
(int)(i*yDeita)1, 5, y1+3);
;
1
/ / Line description
27
10) ;
g.setFont(sizedFont);
g .setcolor (Color.green) ;
XI = getsize() .width-70;
x2 = getsize (1 .width-60;
y1 = y2 = 12;
g .drawLine (xi, y1 , x2 , y2);
g.setcolor (Color.black) ;
g.drawString(I1Fitnessl1,getsize 0 .width-55, 15);
g.setcolor(Color.yellow);
XI = getsize ( ) .width-70;
x2 = getsize0 .width-60;
y1 = y2 = 22;
g.drawLine (xi, yl, x2 , y21 ;
g.setcolor (Color.black) ;
g.drawString(llAverage”,getsize0 .width-55,25) ;
private void drawGraphic(Graphics g)
{
int len = (int)(getsize0 .width-40);
int current = 1;
double yDelta = 0.0;
yDeita = (getsize0 .height-40)/yMax
;
int skip = 1;
int xl, x2, yl, y2;
x1=2o ;
yl=getSize(1 .height-20;
x2=y2=0;
g .setcolor (Color.green) ;
for (int i=O;iclineGraph.size();i++, current++)
{
if (xMax c= len)
x2 = ((int)( (i+l)* (len/xMax)1 ) +20;
else
{
skip = (int)(xMax/len);
x2 = (int)(20+(i/skip)1 ;
1
(((
(int)( (getsize( ) .height-20)Y2
(Double)1ineGraph.elementAt (i)) .intValue (1 ) *yDelta)) ;
if (current == skip)
{
g.drawLine (xi, yl, x2, y2);
current = O;
I
I
xl=x2;
yl=y2;
/ / average graphic
Xl = 20;
y 1 = getsize ( ) .height-20;
x2 = y2 = o;
current = skip = 1;
g.setColor(Color.yellow);
for (int i=O;i<averageLine size O ;i++, current++ 1
{
if (xMax c= len)
x2 = ( (int)( (i+l)* (len/xMax)1) +20;
else
{
1
( (
skip = (int)(xMax/len);
x2 = (int)(20+(i/skip)1 ;
(int)( (getsize0 .height-20)Y2
( (Double)averageLine.elementAt (i) .intvalue (1 1 delta) i
if (current == skip)
{
g.drawLine (xi, yl, x2 , Y21 ;
current = O;
1
1
1
xl = x2;
y1 = y2;
I
import java.awt.*;
import java.util.Vector;
public class FunctionGraph extends Canvas {
double value = 0.0;
public FunctionGraphO
{
setsize (400, 400) ;
setBackground(Color.gray);
1
public void paint(Graphics g)
{
int xlfx2,yl,y2;
int xFactor = 5;
int yFactor = 5;
Font sizedFont;
double yTemp = 0.0;
sizedFont
g.getFont 0 .getstyle0 , 8 )
g.setFont(sizedFont);
(
new
;
/ / dibuja lineas coordenadas
xl = 10;
x2 = getsize() .width - 10;
y1 = y2 = getSize().height/2;
g.drawLine(x1, yl, x2, ~ 2 ) ;
x l = x2 = getsize 0 .width/2;
y1 = 20;
y2 = getsize0 .height-20;
g.drawLine(x1, yl, x2, y2);
/ / escribe escala
for (int y= (int)-1*( (getsize(1 .height-40)/ (2*yFactor)) ;
yc (getsize( ) .height-40)/ (2*yFactor);y++)
{
if ( (y!=O) && (y%5==0)
{
XI = getsize() .width/2 - 1;
x2 = getsize() .width/2 + 1;
y1 = y2 = (-l*(y*yFactor)) + ( (getsize(1 .height)/2) ;
g .drawLine (xi, y1, x2, y21;
g.drawString(l'l'+y,getsize ( ) .width/2 +lo, (-l* (y*yFactor)
(getsize0 .height)/2)+3) ;
1
1
+
int i=i;
x=-l*( (getsize0 .width(int
for
20)/ (2*xFactor)) ;xc (getsize( ) .width-20)
/ (2*xFactor);x++, i++)
{
if ( (x ! = O) && (x%5==0))
{
/ / Escribe escala
XI = x2 = (x*xFactor) + getsize0 .width/2;
y1 = getsize() .height/2 - 1;
y2 = getsize().height/2 + 1;
g.drawLine (xi, yl, x2 , y21 ;
if (xc0)
+ x, xl - 4 , getsize0 .height/2 + 10 1;
g.drawString(llll
else
+ x, xl - 2, getsize0 .height/2 + 10 1;
g.drawString(llll
1
/ / Dibuja Gráfica
1
xl = (x*xFactor) + getsize() .width/2;
x2 = ( (x+l)*xFactor) + getsize 0 .width/2;
yTemp = f (XI;
if (yTemp >= O)
y1 = (int)(getsize().height/2-(yTemp* yFactor) 1 ;
else
y1 = (int)( ( (yTemp*-1)
*yFactor)+getsize ( ) .height/2);
yTemp = f (x+i);
if (yTemp >= O)
y2 = (int)(getsize0 .height/2-(yTemp* yFactor)1 ;
else
y2 = (int)( ((yTemp*-1)*yFactor)+getSize() .height/2);
g.drawLine (xi, yl, x2 , y21 ;
/ / Dibuja Valor
1
xl = x2 = (int)( (value*xFactor)
y1 = o;
y2 = getsize 0 .height ;
g.setcolor (Color.pink1;
g .drawLine (xi, y1 , x2 , y21 ;
double f (double x)
{
return (x*Math.sin (x))
+ getsize ( ) .width/2);
;
import java.awt.*;
import java.awt.event.*;
class DrawControls extends Panel
implements ActionLietener {
FuncXSinX ga;
GenerationGraph gg;
FunctionGraph fg;
OptionsGA oga;
TextField maxGen, pxOver, pMutation, populationsize;
public DrawControls(GenerationGraph gg, FunctionGraph fg, FuncXSinX
ga, OptionsGA oga)
I
setsize (400, 200) ;
this.gg = gg;
this.ga = ga;
this.fg = fg;
this.oga = oga;
1
add (new Label ( !#MAXGENERATIONS" ;
add (maxGen = new TextField ( t t l O O O r l , 6) ;
add(new Label (IIPOP SIZE")) ;
add (populationSize = new TextField ('15011f 4 ) 1;
add (new Label ( llPXOVER");
add(px0ver = new T e ~ t F i e l d ( ~ ~ 06))
. 8 ~; ~ ~
add (new Label ( rfPMUTATION")
) ;
add(pMutation = new TextField(t10.1511,
6)) ;
Button b = null;
b = new Button("Start GA");
b.addActionListener(this1;
add(b) ;
public void actionPerformed(ActionEvent ev)
{
String label = ev.getActionCommand0;
gg.lineGraph.removeAllElements();
gg.averageLine.removeAllElements();
fg.value = 0.0;
ga .MAXGENS
-gg .xMax
Integer.parseInt(maxGen.getText().trim());
ga.POPSIZE = Integer.parseInt(populationSize.getText() .trim());
-12/09/01
ga .PXOVER
//
Float .parseFloat(pxOver.getText ( ) .trim ( ) ) ;
-12/09/ O 1
ga.PMüTATION
//
Float.parseFloat (pMutation.getText( ) .trim (1 1 ;
ga.generation = O;
ga.initilize (1 ;
ga.evaluate (1 ;
ga .keepTheBest ( ) ;
runGA0 ;
1
public void runGA0
{
while (ga.generation<ga.MGENS)
{
/ / DEBUG RGF
/*
try I
Thread.currentThread ( ) . sleep (50);
1
catch (InterruptedException e) {
1* /
ga.generation++;
ga.select (1 ;
ga .crossover(1 ;
ga .mutate( ) ;
gg.lineGraph.addElement(new
Double (ga.population[ga.POPSIZE] .fitness)) ;
gg.averageLine.addElement(ga.getAverage0 1;
gg.repaint 0 ;
fg.value = ga.population[ga.POPSIZEl .gene[ O 1 ;
fg .repaint ( 1;
ga.evaluate ( 1 ;
ga.elitist 0 ;
1
oga.paintResults (rlll+ga.population
[ga.POPSIZE].fitness,
f~~~+ga.population[ga.POPSIZEl
.gene[ O 1 1;
import java.awt.*;
import java.awt.event.*;
\
'.
class OptionsGA extends Panel
implements ActionListener
{
Label bestFitness, bestMember;
public OptionsGA ( )
{
setsize (400, 200) ;
add (new Label ("Best Fitness : ' I ) ) ;
add(bestFitness = new Label ( n O O O O O O O n )
add(new Label ("Best Member: ' I ) 1 ;
add(bestMember = new Label ( " O O O O O O O n ) )
1
;
;
public void actionPerformed(ActionE3ent ev)
{
1
public
void
paintResults(String
labelBestFitness,
1abelBestMember)
{
bestFitness.setText(labe1BestFitness);
bestMember.setText(labe1BestMember) ;
repaint 0 ;
String
1
1
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class Prueba extends Applet {
GeneratianGraph gg;
FunctionGraph fg;
DrawControls dc;
FuncXSinX ga;
OptionsGA oga;
public void init 0
l
1
setLayout (new BorderLayout (1 ) ;
ga = new FuncXSinXo;
gg = new G e n e r a t i o n G r a p h ( g a . M G E N S , 100);
fg = new FunctionGraphO;
oga = new OptionsGAO ;
dc = new DrawControls (gg, fg, ga, oga) ;
add (oga, BorderLayout .NORTH) ;
add(gg, BorderLayout.WEST);
add(fg, BorderLayout.EAST);
add(dc, BorderLayout.SOUTH);
public void destroy0
{
remove (gg);
remove (fg);
remove (dc ;
32
Referencias
Holland
Genetic Algorithm, 1962
Beasley, Bull y Martin
An overview of Genetic Aigorithms
Bruce Eckel
Thinking in Java, 2ndEdition
Prentince Hall mid-Jun2000
33
Descargar