Manual JGAP & Algoritmos Geneticos

March 16, 2018 | Author: Jorge Tene | Category: Genetic Algorithm, Computer Programming, Software, Computing, Technology


Comments



Description

UNIVERSIDAD NACIONAL DE LOJAÁREA DE LA ENERGIA LAS INDUSTRIAS Y LOS RECURSOS NATURALES NO RENOVABLES Carrera Ingeniería En Sistemas MODULO X “A” Algoritmos Genéticos JGAP Alumno: Jorge Tene Docente: Ing. Luis Chamba LOJA – ECUADOR 2011 CONTENIDOS 1. Introducción 2. Instalación y configuración del entorno 2.1 Generalidades 2.2 Descarga e instalación de JGAP 2.3 Agregar las librerías a la aplicación Netbeans 3. Algoritmos Genéticos 4. Ejemplo de aplicación 5. Implementación de ejemplo Función Aptitud 6. ANEXO II: Licencia Introducción JGAP son las siglas de Java Genetic Algorithms Package (paquete de algoritmos genéticos para Java). Es un componente de programación de algoritmos genéticos que se utiliza como un framework. Los algoritmos genéticos se basan en la teoría de la evolución de Charles Darwin. Se tiene una población, donde cada individuo posee diferentes características. Esas características se muestran favorables o no frente a un método de selección al que se enfrentan todos los individuos. Así se van identificando los que poseen las mejores características. Las características de los individuos están dadas por sus cromosomas. Un cromosoma es un conjunto de genes. Cada gen es responsable de indicar el tipo de una sola característica del individuo. El valor que toma el gen se llama alelo. ¿QUÉ OFRECE JGAP? JGAP tiene clases e interfaces para representar: Genes (Gene), cromosomas (Chromosome), individuos (IChromosome), la población (Genotype), la función de ajuste (FitnessFunction) y operadores genéticos. Se trata de una solución genérica, sin relación alguna con un problema particular. Por esa razón se deben crear nuevas clases que heredan o implementan las clases e interfaces mencionadas. Así se adapta JGAP al problema específico que se quiere solucionar. MOTOR GENÉTICO JGAP también se encarga de la simulación de un ambiente para que se desarrolle y sobreviva la mejor solución. El “motor genético” crea varias soluciones (individuos) aleatoriamente con el método randomInitialGenotype(). Aplica operadores genéticos (mutación y combinación) para que surjan nuevas soluciones con el método evolve(). Pone a prueba cada solución con la función de ajuste evaluate(). Y por último retorna el cromosoma del individuo mejor adaptado con getFittestChromosome(). LICENCIA JGAP es software libre y se puede distribuir bajo la GNU Lesser Public License 2.1 o posterior. Las aplicaciones comerciales que no publiquen su código fuente deben distribuirse bajo la Mozilla Public License. En ese caso deben donarse 50 Euros al proyecto.Laboratorio de AG con JGAPAlgoritmos-geneticos. 2. Instalación y configuración del entorno. 2.1 Generalidades. En primer lugar debe disponerse de una herramienta de desarrollo de aplicaciones java. Luego es necesario descargar las librerías JGAP y agregarlas a una aplicación. - Descarga e instalación de la máquina virtual de java. Antes de empezar a programar en un IDE de programación como Eclipse o Netbeans es necesario disponer de la máquina virtual de java para poder compilar las aplicaciones. Se puede obtener en este sitio o en el http://java.sun.com/javase/downloads/index.jsp 2.2 Descarga e instalación de JGAP Se deben descargar las librerías de JGAP desde el sitio oficial hay un link a la última versión. Hasta el día de hoy es 3.5. Las librerías las pueden descargar de la siguiente dirección: http://sourceforge.net/projects/jgap/files/ El archivo se llama jgap_3.5_full.zip. Para que no existan errores de instalación se recomienda descargar el instalador completo para que no estén en la necesidad de compilar el código. Procedemos a descomprimir el archivo mencionado anteriormente en un cualquier directorio que a usted le parezca más conveniente. Lo que haremos a continuación es incluir el archivo jgap.jar como una biblioteca para hacer uso de todas las clases del JGAP. 2.3 Agregar las librerías a la aplicación Netbeans Una vez tengamos nuestro proyecto abierto con Netbeans lo que hacemos es hacer clic derecho en el proyecto y nos dirigimos en propiedades y en la opción Libaries agregamos la libreria jgap.jar haciendo clic en Add Jar/folder. 3. Algoritmos Genéticos Los Algoritmos Géticos (AGs) son métodos adaptativos que pueden usarse para resolver problemas de búsqueda y optimización. Están basados en el proceso genético de los organismos vivos. A lo largo de las generaciones, las poblaciones evolucionan en la naturaleza de acorde con los principios de la selección natural y la supervivencia de los mas fuertes, postulados por Darwin (1859). Por imitación de este proceso, los Algoritmos Genéticos son capaces de ir creando soluciones para problemas del mundo real. La evolución de dichas soluciones hacia valores óptimos del problema depende en buena medida de una adecuada coeducación de las mismas. Los Algoritmos Genéticos usan una analogía directa con el comportamiento natural. Trabajan con una población de individuos, cada uno de los cuales representa una solución factible a un problema dado. A cada individuo se le asigna un valor o puntuación, relacionado con la bondad de dicha solución. En la naturaleza esto equivaldría al grado de efectividad de un organismo para competir por unos determinados recursos. Cuanto mayor sea la adaptación de un individuo al problema, mayor sera la probabilidad de que el mismo sea seleccionado para reproducirse, cruzando su material genético con otro individuo seleccionado de igual forma. Este cruce producira nuevos individuos descendientes de los anteriores los cuales comparten algunas de las características de sus padres. Cuanto menor sea la adaptación de un individuo, menor sera la probabilidad de que dicho individuo sea seleccionado para la reproducción, y por tanto de que su material genético se propague en sucesivas generaciones. De esta manera se produce una nueva población de posibles soluciones, la cual reemplaza a la anterior y verifica la interesante propiedad de que contiene una mayor proporción de buenas características en comparación con la población anterior. Así a lo largo de las generaciones las buenas características se propagan a través de la población. Favoreciendo el cruce de los individuos mejor adaptados, van siendo exploradas las áreas más prometedoras del espacio de búsqueda. Si el Algoritmo Genético ha sido bien diseñado, la población convergería hacia una solución óptima del problema. El poder de los Algoritmos Genéticos proviene del hecho de que se trata de una técnica robusta, y pueden tratar con éxito una gran variedad de problemas provenientes de diferentes áreas, incluyendo aquellos en los que otros métodos encuentran dificultades. Si bien no se garantiza que el Algoritmo Genético encuentre la solución óptima del problema, existe evidencia empírica de que se encuentran soluciones de un nivel aceptable, en un tiempo competitivo con el resto de algoritmos de optimización combinatoria. En el caso de que existan técnicas especializadas para resolver un determinado problema, lo más probable es que superen al Algoritmo Genético, tanto en rapidez como en eficacia. El gran campo de aplicación de los Algoritmos Genéticos se relaciona con aquellos problemas para los cuales no existen técnicas especializadas. Incluso en el caso en que dichas técnicas existan, y funcionen bien, pueden efectuarse mejoras de las mismas hibridándolas con los Algoritmos Genéticos. 4. Ejemplo de aplicación Una vez ya instalado las librerías en nuestro proyecto ejecutamos la aplicación y nos debe de dar los siguientes resultados. Cuando insertamos un total de 800 centavos el programa nos arroja como resultado lo siguiente: Donde notamos que la suma de todas las 12 monedas en centavos nos da como resultado 800 centavos en total. 5. Codigo Fuente Esta código es de la clase CambioMInimo.java package practica1; import import import import import import import import java.io.File; org.jgap.Chromosome; org.jgap.Configuration; org.jgap.FitnessFunction; org.jgap.Gene; org.jgap.Genotype; org.jgap.IChromosome; org.jgap.data.DataTreeBuilder; import import import import import import org.jgap.data.IDataCreators; org.jgap.impl.DefaultConfiguration; org.jgap.impl.IntegerGene; org.jgap.xml.XMLDocumentBuilder; org.jgap.xml.XMLManager; org.w3c.dom.Document; public class CambioMinimo { /** * The total number of times we'll let the population evolve. */ private static final int MAX_EVOLUCIONES_PERMITIDAS = 2200; /** * Calcula utilizando algoritmos geneticos la solución al problema y la * imprime por pantalla * * @param Monto * Monto que se desea descomponer en la menor cantidad de monedas * posibles * @throws Exception * */ public static void calcularCambioMinimo(int Monto)throws Exception { // Se crea una configuracion con valores predeterminados. // -----------------------------------------------------------Configuration conf = new DefaultConfiguration(); // Se indica en la configuracion que el elemento mas apto siempre pase a // la proxima generacion // -----------------------------------------------------------conf.setPreservFittestIndividual(true); // Se Crea la funcion de aptitud y se setea en la configuracion // -------------------------------------------------------FitnessFunction myFunc = new CambioMinimoFuncionAptitud(Monto); conf.setFitnessFunction(myFunc); // Ahora se debe indicar a la configuracion como seran los cromosomas: en // este caso tendran 8 genes (uno para cada tipo de moneda) con un valor // entero (cantidad de monedas de ese tipo). // Se debe crear un cromosoma de ejemplo y cargarlo en la configuracion // Cada gen tendra un valor maximo y minimo que debe setearse. // ------------------------------------------------------------Gene[] sampleGenes = new Gene[6]; sampleGenes[0] = new IntegerGene(conf, 0, Math.round(CambioMinimoFuncionAptitud.MAX_MONTO/100)); // Moneda 1 dolar sampleGenes[1] = new IntegerGene(conf, 0, 10); // Moneda 50 centimos sampleGenes[2] = new IntegerGene(conf, 0, 10); // Moneda 25 centavos sampleGenes[3] = new IntegerGene(conf, 0, 10); // Moneda 10 centavos sampleGenes[4] = new IntegerGene(conf, 0, 10); // Moneda 5 centavos sampleGenes[5] = new IntegerGene(conf, 0, 10); // Moneda 1 centavos IChromosome sampleChromosome = new Chromosome(conf, sampleGenes); conf.setSampleChromosome(sampleChromosome); // Por ultimo se debe indicar el tamaño de la poblacion en la // configuracion // ----------------------------------------------------------conf.setPopulationSize(200); Genotype Poblacion; // El framework permite obtener la poblacion inicial de archivos xml // pero para este caso particular resulta mejor crear una poblacion // aleatoria, para ello se utiliza el metodo randomInitialGenotype que // devuelve la poblacion random creada Poblacion = Genotype.randomInitialGenotype(conf); // La Poblacion debe evolucionar para obtener resultados mas aptos // -------------------------------------------------------------long TiempoComienzo = System.currentTimeMillis(); for (int i = 0; i < MAX_EVOLUCIONES_PERMITIDAS; i++) { Poblacion.evolve(); } long TiempoFin = System.currentTimeMillis(); System.out.println("Tiempo total de evolucion: " + (TiempoFin - TiempoComienzo) + " ms"); guardarPoblacion(Poblacion); // Una vez que la poblacion evoluciono es necesario obtener el cromosoma // mas apto para mostrarlo como solucion al problema planteado para ello // se utiliza el metodo getFittestChromosome IChromosome cromosomaMasApto = Poblacion.getFittestChromosome(); System.out.println("El cromosoma mas apto encontrado tiene un valor de aptitud de: " + cromosomaMasApto.getFitnessValue()); System.out.println("Y esta formado por la siguiente distribucion de monedas: "); System.out.println("\t" + CambioMinimoFuncionAptitud.getNumeroDeComendasDeGen(cromosomaMasAp to, 0) + " Moneda 1 dolar"); System.out.println("\t" + CambioMinimoFuncionAptitud.getNumeroDeComendasDeGen(cromosomaMasAp to, 1) + " Moneda 50 centavos"); System.out.println("\t" + CambioMinimoFuncionAptitud.getNumeroDeComendasDeGen(cromosomaMasAp to, 2) + " Moneda 25 centavos"); System.out.println("\t" + CambioMinimoFuncionAptitud.getNumeroDeComendasDeGen(cromosomaMasAp to, 3) + " Moneda 10 centavos"); System.out.println("\t" + CambioMinimoFuncionAptitud.getNumeroDeComendasDeGen(cromosomaMasAp to, 4) + " Moneda 5 centavos"); System.out.println("\t" + CambioMinimoFuncionAptitud.getNumeroDeComendasDeGen(cromosomaMasAp to, 5) + " Moneda 1 centavo"); System.out.println("Para un total de "+ CambioMinimoFuncionAptitud.montoCambioMoneda(cromosomaMasApto) + " centavos en " + CambioMinimoFuncionAptitud.getNumeroTotalMonedas(cromosomaMasApto) + " monedas."); } /** * Metodo principal: Recibe el monto en dinero por parametro para determinar * la cantidad minima de monedas necesarias para formarlo * * @param args * Monto de dinero * @throws Exception * */ public static void main(String[] args) throws Exception { int amount = 800; try { //amount = Integer.parseInt(args[0]); } catch (NumberFormatException e) { System.out.println("El (Monto de dinero) debe ser un numero entero valido"); System.exit(1); } if (amount < 1 || amount >= CambioMinimoFuncionAptitud.MAX_MONTO) { System.out.println("El monto de dinero debe estar entre 1 y "+ (CambioMinimoFuncionAptitud.MAX_MONTO - 1)+ "."); } else { calcularCambioMinimo(amount); } } // -------------------------------------------------------------------// Este metodo permite guardar en un xml la ultima poblacion calculada // -------------------------------------------------------------------public static void guardarPoblacion(Genotype Poblacion) throws Exception { DataTreeBuilder builder = DataTreeBuilder.getInstance(); IDataCreators doc2 = builder.representGenotypeAsDocument(Poblacion); // create XML document from generated tree XMLDocumentBuilder docbuilder = new XMLDocumentBuilder(); Document xmlDoc = (Document) docbuilder.buildDocument(doc2); XMLManager.writeFile(xmlDoc, new File("PoblacionCambioMinimo.xml")); } } Este es el código de la siguiente clase de nombre CambioMinimoFuncionAptitud.java package practica1; import org.jgap.*; /** * Funcion de Aptitud para Cambio Minimo * */ public class CambioMinimoFuncionAptitud extends FitnessFunction{ private final int montoObjetivo; // Maximo monto posible 1000 Centimos = 10 Euros public static final int MAX_MONTO = 1000; // Maxima cantidad de monedas posibles. Es igual al Monto maximo en // centimos, ya que si se utilizan monedas de un centimo se llegaria al // monton con la mayor cantidad posible de monedas public static final int MAX_CANT_MONEDAS = MAX_MONTO; // El constructor de la funcion de aptitud debe recibir el monto objetivo // del problema y almacenarlo en un atributo. Si el monto es invalido arroja // una excepcion public CambioMinimoFuncionAptitud(int monto) { if (monto < 1 || monto >= MAX_MONTO) { throw new IllegalArgumentException("El monto debe ser un numero entre 1 y " + MAX_MONTO + " centavos"); } montoObjetivo = monto; } /** * El metodo evaluate es el metodo que se debe sobrecargar para que devuelva * el valor de aptitud asociado al cromosoma que se recibe por parametro. * * * @param cromosoma * El cromosoma a evaluar * * @return El valor de aptitud de ese cromosoma * @author Gabriel Veloso, Ruben Arce */ public double evaluate(IChromosome cromosoma) { // Se debe tener en cuenta el evaluador que se esta usando. El evaluador // estandar le asigna un valor mas apto a los valores mas altos de // aptitud. Tambien hay otros evaluadores que asignan mejor aptitud a // los valores mas bajos. // Es por esto que se chequea si 2 es mas apto que 1. Si esto es asi // entonces el valor mas apto sera el mayor y el menos apto el 0 boolean evaluadorEstandard = cromosoma.getConfiguration().getFitnessEvaluator().isFitter(2, 1); int montoCambioMonedas = montoCambioMoneda(cromosoma); int totalMonedas = getNumeroTotalMonedas(cromosoma); int diferenciaMonto = Math.abs(montoObjetivo montoCambioMonedas); // El primer paso es asignar la menor aptitud a aquellos cromosomas cuyo // monto no sea el monto objetivo. Es decir una descomposicion en // monedas que no sea del monto ingresado if (evaluadorEstandard) { if (diferenciaMonto != 0) return 0.0d; } else { if (diferenciaMonto != 0) return MAX_CANT_MONEDAS; } // luego se debe asignar mas aptitud a aquellos cromosomas que posean // menor cantidad de monedas. if (evaluadorEstandard) { // Se debe asegurar devolver un valor de aptitud positivo siempre. // Si el valor es negativo se devuelve MAX_CANT_MONEDAS ( elemento // menos apto ) return Math.max(0.0d, MAX_CANT_MONEDAS totalMonedas); } else { // Se debe asgurar devolver un valor de aptitud positivo siempre. // Si el valor es negativo se devuelve 0 ( elemento menos apto ) return Math.max(0.0d, totalMonedas); } } /** * Calcula el monto total que suman todas las monedas de un cromosoma * * * @param cromosoma * El cromosoma a evaluar * @return Retorna el monto en centimos compuesto por la suma de las monedas * de ese cromosoma * * @author Gabriel Veloso, Ruben Arce * */ public static int montoCambioMoneda(IChromosome cromosoma) { int Moneda1Dolar = getNumeroDeComendasDeGen(cromosoma, 0); int Moneda50Centavos = getNumeroDeComendasDeGen(cromosoma, 1); int Moneda25Centavos = getNumeroDeComendasDeGen(cromosoma, 2); int Moneda10Centavos = getNumeroDeComendasDeGen(cromosoma, 3); int Moneda5Centavos = getNumeroDeComendasDeGen(cromosoma, 4); int Moneda1Centavo = getNumeroDeComendasDeGen(cromosoma, 5); return ((Moneda1Dolar * 100) + (Moneda50Centavos * 50) + (Moneda25Centavos * 25) + (Moneda10Centavos * 10) + (Moneda5Centavos * 5) + Moneda1Centavo); } /** * Calcula la cantidad de monedas de determinado tipo (gen) de un cromosoma * Ejemplo. Cantidad de monedas de 20 centimos de es cromosoma * * @param cromosoma * El cromosoma a evaluar * @param numeroGen * El numero gen (tipo de moneda) de que se desea averiguar la * cantidad * @return Devuelve la cantidad de monedas de ese tipo de ese cromosoma * * g */ public static int getNumeroDeComendasDeGen(IChromosome cromosoma,int numeroGen) { Integer numMonedas = (Integer) cromosoma.getGene(numeroGen).getAllele(); return numMonedas.intValue(); } /** * Calcula el total de monedas que tiene esa solucion. Este valor se utiliza * para calcular la aptitud del cromosoma ya que el objetivo es minimizar la * cantidad de monedas de la solucion * * * @param cromosoma * El cromosoma a evaluar * @return El total de monedas que tiene esa solucion * */ public static int getNumeroTotalMonedas(IChromosome cromosoma) { int totalMonedas = 0; int numberOfGenes = cromosoma.size(); for (int i = 0; i < numberOfGenes; i++) { totalMonedas += getNumeroDeComendasDeGen(cromosoma, i); } return totalMonedas; } } 6. Implementación de ejemplo Funcion Aptitud La clase que implementará la función aptitud debe heredar de Fitness Function y redefinir el método: Public doublé evaluate(IChromosomecromosoma) Este método le permite al framework determinar que cromosoma es más apto que otro. El valor devuelto debe ser un doublé positivo. Por defecto, se entiende que un valor más alto devuelto corresponde a un crosoma más apto pero este no puede ser así, depende del evaluador que se haya utilizado. 7. ANEXO II: Licencia JGAP es software libre, puede redistribuirlo y / o modificarlo bajo los términos de la GNU Public License publicada por la Free Software Foundation, ya sea la versión 2.1 de la Licencia, o (a su elección) cualquier versión posterior. En su lugar, podría optar por utilizar la Licencia Pública de Mozilla para el uso en aplicaciones comerciales JGAP sin la necesidad de publicar el código fuente o que sea contrario ingeniosa (como es necesaria con la licencia GNU). Para el uso de la MPL tiene que donar al menos 20 De euros para JGAP. Tal vez le gustaría a la información sobre el uso el navegador más JGAP comercialmente.
Copyright © 2024 DOKUMEN.SITE Inc.