algoritmos genéticos

28
Algoritmos Genéticos (# Reinas) ALGORTIRMOS GENETICOS Los Algoritmos Genéticos (AG's) 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 más 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 codificación de las mismas. LAS 8 REINAS El problema de las ocho reinas es un pasatiempo en el que se colocan ocho reinas sin que se amenacen. Fue propuesto por el ajedrecista alemán Max Bezzel en 1848. En el juego del ajedrez la reina amenaza a aquellas piezas que se encuentren en su misma fila, columna o diagonal. El juego de las 8 reinas consiste en colocar sobre un tablero de ajedrez ocho reinas sin que estas se amenacen entre ellas. import java.util.*; import javax.swing.*; public class Reinas { private static int poblacionIni = 75; // Tamaño de la poblacion private static double probApareamiento = 0.7; // Probabilidad de reproduccion entre dos cromosomas. rango: 0.0 < probMutacion < 1.0 private static double tasaMutacion = 0.001; // Tasa de mutacion. rango: 0.0 < tasaMutacion < 1.0 private static int minSeleccion = 10; // Minimo de padres para la seleccion. private static int maxSeleccion = 50; // Maximo de padres para la seleccion. rango: minSeleccion < maxSeleccion < poblacionIni private static int numDesendencia = 20; // Cantidad desendencia por generacion. rango: 0 < numDesendencia < maxSeleccion. private static int minBaraja = 8; // Rango para generar aleatorios private static int maxBaraja = 20; private static int ptsCruce = 4; // Maximo de puntos de cruce. rango: 0 < ptsCruce < 8 (> 8 isn't good). private static int anchoTablero = 8; // Ancho del tablero. private static int generacion = 0; private static int numHijos = 0;

Upload: percy-alhuay-carrasco

Post on 29-Jan-2016

28 views

Category:

Documents


1 download

DESCRIPTION

algoritmos genticos

TRANSCRIPT

Page 1: Algoritmos Genéticos

Algoritmos Genéticos (# Reinas)

ALGORTIRMOS GENETICOS

Los Algoritmos Genéticos (AG's) 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 más 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 codificación de las mismas. 

LAS 8 REINAS

El problema de las ocho reinas es un pasatiempo en el que se colocan ocho reinas sin que se amenacen. Fue propuesto por el ajedrecista alemán Max Bezzel en 1848. En el juego del ajedrez la reina amenaza a aquellas piezas que se encuentren en su misma fila, columna o diagonal. El juego de las 8 reinas consiste en colocar sobre un tablero de ajedrez ocho reinas sin que estas se amenacen entre ellas.

import java.util.*;import javax.swing.*;

public class Reinas {

private static int poblacionIni = 75; // Tamaño de la poblacion private static double probApareamiento = 0.7; // Probabilidad de reproduccion entre dos cromosomas. rango: 0.0 < probMutacion < 1.0 private static double tasaMutacion = 0.001; // Tasa de mutacion. rango: 0.0 < tasaMutacion < 1.0 private static int minSeleccion = 10; // Minimo de padres para la seleccion. private static int maxSeleccion = 50; // Maximo de padres para la seleccion. rango: minSeleccion < maxSeleccion < poblacionIni private static int numDesendencia = 20; // Cantidad desendencia por generacion. rango: 0 < numDesendencia < maxSeleccion. private static int minBaraja = 8; // Rango para generar aleatorios private static int maxBaraja = 20; private static int ptsCruce = 4; // Maximo de puntos de cruce. rango: 0 < ptsCruce < 8 (> 8 isn't good). private static int anchoTablero = 8; // Ancho del tablero. private static int generacion = 0; private static int numHijos = 0; private static int sigMutacion = 0; // Programa las mutaciones. private static int numMutaciones = 0; private static List<Cromosoma> poblacion = new ArrayList<Cromosoma>();

/** * Metodo que emula un algortimo genetico Simple

Page 2: Algoritmos Genéticos

*/ public static void AlgoritmoGenetico(JTextArea tablero, JTextArea generaciones) {

int tamanioPoblacion = 0; Cromosoma cromosoma = null; boolean terminado = false; GenerarPoblacionInicial(); //Genera población inicial

numMutaciones = 0; sigMutacion = NumeroAleatorio(0, (int) Math.round(1.0 / tasaMutacion));

while (!terminado) { //Mientras no terminada la búsqueda tamanioPoblacion = poblacion.size(); //Tamaño de población for (int i = 0; i < tamanioPoblacion; i++) { cromosoma = poblacion.get(i); if ((cromosoma.getConflictos() == 0)) { terminado = true; } }

Fitness(); //Calcula el fitness dependiendo la cantidad de conflictos

Seleccion(); //Selecciona los padres de la siguiente generación

Reproduccion(); //Realiza el cruce parcial de los padres

PrepararSiguienteGeneracion(); //Selecciona los hijos de la siguiente generación

generacion++; }

tamanioPoblacion = poblacion.size(); for (int i = 0; i < tamanioPoblacion; i++) { cromosoma = poblacion.get(i); if (cromosoma.getConflictos() == 0) { ImprimirSolucion(cromosoma, tablero); } }

generaciones.setText(generaciones.getText() + "Resuelto en " + generacion + " generaciones \nencontrado con " + numMutaciones + " mutaciones \nen el " + numHijos + " cromosoma."); }

/** * Busca la mejor actitud */ private static void Fitness() {

Page 3: Algoritmos Genéticos

// Menor error = 100%, Mayor Error = 0% int tamanioPoblacion = poblacion.size(); Cromosoma cromosoma = null; double mejor = 0; double peor = 0;

// La peor puntuación serÃa el que tiene la mayor energÃa, mejor más bajo. peor = poblacion.get(Maximo()).getConflictos();

// Convertir a un porcentaje ponderado. mejor = peor - poblacion.get(Minimo()).getConflictos();

for (int i = 0; i < tamanioPoblacion; i++) { cromosoma = poblacion.get(i); cromosoma.SetFitness((peor - cromosoma.getConflictos()) * 100.0 / mejor); } }

/** * Seleccion de cromosomas de la generacion */ private static void Seleccion() {

int j = 0; int tamanioPoblacion = poblacion.size(); double genTotal = 0.0; double selTotal = 0.0; int maximoSeleccionar = NumeroAleatorio(minSeleccion, maxSeleccion); double seleccionar = 0.0; Cromosoma cromosoma = null; Cromosoma comosomaAux = null; boolean terminado = false;

for (int i = 0; i < tamanioPoblacion; i++) { cromosoma = poblacion.get(i); genTotal += cromosoma.getFitness(); }

genTotal *= 0.01;

for (int i = 0; i < tamanioPoblacion; i++) { cromosoma = poblacion.get(i); cromosoma.setProbSeleccion(cromosoma.getFitness() / genTotal); }

for (int i = 0; i < maximoSeleccionar; i++) { seleccionar = NumeroAleatorio(0, 99); j = 0; selTotal = 0; terminado = false; while (!terminado) { cromosoma = poblacion.get(j); selTotal += cromosoma.getProbSeleccion();

Page 4: Algoritmos Genéticos

if (selTotal >= seleccionar) { if (j == 0) { comosomaAux = poblacion.get(j); } else if (j >= tamanioPoblacion - 1) { comosomaAux = poblacion.get(tamanioPoblacion - 1); } else { comosomaAux = poblacion.get(j - 1); } comosomaAux.setSeleccionado(true); terminado = true; } else { j++; } } } }

/** * Produce una nueva generacion */ private static void Reproduccion() { int getRand = 0; int padreA = 0; int padreB = 0; int newIndex1 = 0; int newIndex2 = 0; Cromosoma newChromo1 = null; Cromosoma newChromo2 = null;

for (int i = 0; i < numDesendencia; i++) { padreA = SeleccionarPadre(); // Probabilidad de prueba de reproduccion. getRand = NumeroAleatorio(0, 100); if (getRand <= probApareamiento * 100) { padreB = SeleccionarPadre(padreA); newChromo1 = new Cromosoma(anchoTablero); newChromo2 = new Cromosoma(anchoTablero); poblacion.add(newChromo1); newIndex1 = poblacion.indexOf(newChromo1); poblacion.add(newChromo2); newIndex2 = poblacion.indexOf(newChromo2);

// Elige uno o ambos de los siguientes: CruceParcial(padreA, padreB, newIndex1, newIndex2);

if (numHijos - 1 == sigMutacion) { IntercambiarMutacion(newIndex1, 1); } else if (numHijos == sigMutacion) { IntercambiarMutacion(newIndex2, 1); }

poblacion.get(newIndex1).CalcularConflictos(); poblacion.get(newIndex2).CalcularConflictos();

numHijos += 2;

Page 5: Algoritmos Genéticos

// Programa la siguiente mutacion. if (numHijos % (int) Math.round(1.0 / tasaMutacion) == 0) { sigMutacion = numHijos + NumeroAleatorio(0, (int) Math.round(1.0 / tasaMutacion)); } } } // i }

/** * Cruza con probabilidad dos individuos obteniendo dos decendientes * * @param chromA * @param chromB * @param hijo1 * @param hijo2 */ private static void CruceParcial(int chromA, int chromB, int hijo1, int hijo2) { int j = 0; int item1 = 0; int item2 = 0; int pos1 = 0; int pos2 = 0; Cromosoma cromosoma = poblacion.get(chromA); Cromosoma comosomaAux = poblacion.get(chromB); Cromosoma newChromo1 = poblacion.get(hijo1); Cromosoma newChromo2 = poblacion.get(hijo2); int crossPoint1 = NumeroAleatorio(0, anchoTablero - 1); int crossPoint2 = NumeroAleatorioExclusivo(anchoTablero - 1, crossPoint1);

if (crossPoint2 < crossPoint1) { j = crossPoint1; crossPoint1 = crossPoint2; crossPoint2 = j; }

// Copia los genes de padres a hijos. for (int i = 0; i < anchoTablero; i++) { newChromo1.getGenes(i, cromosoma.setGenes(i)); newChromo2.getGenes(i, comosomaAux.setGenes(i)); }

for (int i = crossPoint1; i <= crossPoint2; i++) { // Obtener los dos elementos que intercambian. item1 = cromosoma.setGenes(i); item2 = comosomaAux.setGenes(i);

// Obtiene los items, posiciones en la descendencia. for (j = 0; j < anchoTablero; j++) { if (newChromo1.setGenes(j) == item1) { pos1 = j; } else if (newChromo1.setGenes(j) == item2) { pos2 = j; }

Page 6: Algoritmos Genéticos

} // j

// Intercambiar. if (item1 != item2) { newChromo1.getGenes(pos1, item2); newChromo1.getGenes(pos2, item1); }

// Obtiene los items, posiciones en la descendencia. for (j = 0; j < anchoTablero; j++) { if (newChromo2.setGenes(j) == item2) { pos1 = j; } else if (newChromo2.setGenes(j) == item1) { pos2 = j; } } // j

// Intercambiar. if (item1 != item2) { newChromo2.getGenes(pos1, item1); newChromo2.getGenes(pos2, item2); }

} // i }

/** * Cruza con probabilidad dos individuos obteniendo dos decendientes * * @param chromA * @param chromB * @param hijo1 * @param hijo2 */ private static void CrucePorPosicion(int chromA, int chromB, int hijo1, int hijo2) { int k = 0; int numPoints = 0; int tempArray1[] = new int[anchoTablero]; int tempArray2[] = new int[anchoTablero]; boolean matchFound = false; Cromosoma cromosoma = poblacion.get(chromA); Cromosoma comosomaAux = poblacion.get(chromB); Cromosoma newChromo1 = poblacion.get(hijo1); Cromosoma newChromo2 = poblacion.get(hijo2);

// Elegir y ordenar los puntos de cruce. numPoints = NumeroAleatorio(0, ptsCruce); int crossPoints[] = new int[numPoints]; for (int i = 0; i < numPoints; i++) { crossPoints[i] = NumeroAleatorio(0, anchoTablero - 1, crossPoints); } // i

// Obtenga no elegidos de los padres 2 k = 0; for (int i = 0; i < anchoTablero; i++) {

Page 7: Algoritmos Genéticos

matchFound = false; for (int j = 0; j < numPoints; j++) { if (comosomaAux.setGenes(i) == cromosoma.setGenes(crossPoints[j])) { matchFound = true; } } // j if (matchFound == false) { tempArray1[k] = comosomaAux.setGenes(i); k++; } } // i

// Insertar elegido al hijo 1. for (int i = 0; i < numPoints; i++) { newChromo1.getGenes(crossPoints[i], cromosoma.setGenes(crossPoints[i])); }

// Rellene no elegidos para hijos 1. k = 0; for (int i = 0; i < anchoTablero; i++) { matchFound = false; for (int j = 0; j < numPoints; j++) { if (i == crossPoints[j]) { matchFound = true; } } // j if (matchFound == false) { newChromo1.getGenes(i, tempArray1[k]); k++; } } // i

// Obtenga no elegidos de los padres 1 k = 0; for (int i = 0; i < anchoTablero; i++) { matchFound = false; for (int j = 0; j < numPoints; j++) { if (cromosoma.setGenes(i) == comosomaAux.setGenes(crossPoints[j])) { matchFound = true; } } // j if (matchFound == false) { tempArray2[k] = cromosoma.setGenes(i); k++; } } // i

// Inserte elegido en hijos 2. for (int i = 0; i < numPoints; i++) { newChromo2.getGenes(crossPoints[i], comosomaAux.setGenes(crossPoints[i])); }

// Rellene no elegidos para hijos 2.

Page 8: Algoritmos Genéticos

k = 0; for (int i = 0; i < anchoTablero; i++) { matchFound = false; for (int j = 0; j < numPoints; j++) { if (i == crossPoints[j]) { matchFound = true; } } // j if (matchFound == false) { newChromo2.getGenes(i, tempArray2[k]); k++; } } // i }

/** * Intercambia los genes, realiza la mutacion * * @param indice * @param intercambio */ private static void IntercambiarMutacion(int indice, int intercambio) { int i = 0; int tempData = 0; Cromosoma cromosoma = null; int gene1 = 0; int gene2 = 0; boolean terminado = false;

cromosoma = poblacion.get(indice);

while (!terminado) { gene1 = NumeroAleatorio(0, anchoTablero - 1); gene2 = NumeroAleatorioExclusivo(anchoTablero - 1, gene1);

// Cambia los genes seleccionados. tempData = cromosoma.setGenes(gene1); cromosoma.getGenes(gene1, cromosoma.setGenes(gene2)); cromosoma.getGenes(gene2, tempData);

if (i == intercambio) { terminado = true; } i++; } numMutaciones++; }

/** * Seleccionar los padres para la reproduccion * * @return */ private static int SeleccionarPadre() { // Función sobrecargada, consulta "choosepadre (ByVal Parenta As Integer)".

Page 9: Algoritmos Genéticos

int padre = 0; Cromosoma cromosoma = null; boolean terminado = false;

while (!terminado) { // Elige al azar un padre elegible. padre = NumeroAleatorio(0, poblacion.size() - 1); cromosoma = poblacion.get(padre); if (cromosoma.getSeleccionado() == true) { terminado = true; } }

return padre; }

/** * Seleccionar los padres para la reproduccion, diferente al seleccionado * * @return int */ private static int SeleccionarPadre(int padreA) { // Función sobrecargada, consulta "choosepadre()". int padre = 0; Cromosoma cromosoma = null; boolean terminado = false;

while (!terminado) { // Elige al azar un padre elegible. padre = NumeroAleatorio(0, poblacion.size() - 1); if (padre != padreA) { cromosoma = poblacion.get(padre); if (cromosoma.getSeleccionado() == true) { terminado = true; } } }

return padre; }

/** * Prepara la poblacion de la siguiente generacion */ private static void PrepararSiguienteGeneracion() { int tamanioPoblacion = 0; Cromosoma cromosoma = null;

// Restaura estado de cromosoma tamanioPoblacion = poblacion.size(); for (int i = 0; i < tamanioPoblacion; i++) { cromosoma = poblacion.get(i); cromosoma.setSeleccionado(false); } }

Page 10: Algoritmos Genéticos

/** * Imprime la mejor solucion * * @param mejorSolucion */ private static void ImprimirSolucion(Cromosoma mejorSolucion, JTextArea visorTablero) { String tablero[][] = new String[anchoTablero][anchoTablero];

// Limpia el tablero. for (int x = 0; x < anchoTablero; x++) { for (int y = 0; y < anchoTablero; y++) { tablero[x][y] = ""; } }

for (int x = 0; x < anchoTablero; x++) { tablero[x][mejorSolucion.setGenes(x)] = "Q"; }

// Muestra el tablero. for (int y = 0; y < anchoTablero; y++) { for (int x = 0; x < anchoTablero; x++) { if (tablero[x][y] == "Q") { visorTablero.setText(visorTablero.getText() + "X "); } else { visorTablero.setText(visorTablero.getText() + "O "); } } visorTablero.setText(visorTablero.getText() + "\n"); } }

/** * Obtiene un numero aleatorio en el rango * * @param low * @param high * @return */ private static int NumeroAleatorio(int low, int high) { return (int) Math.round((high - low) * new Random().nextDouble() + low); }

/** * * @param high * @param except * @return */ private static int NumeroAleatorioExclusivo(int high, int except) { boolean terminado = false; int getRand = 0;

while (!terminado) { getRand = new Random().nextInt(high);

Page 11: Algoritmos Genéticos

if (getRand != except) { terminado = true; } }

return getRand; }

/** * Obtener numero aleatorio fuera del rango * * @param low * @param high * @param except * @return */ private static int NumeroAleatorio(int low, int high, int[] except) { boolean terminado = false; int getRand = 0;

if (high != low) { while (!terminado) { terminado = true; getRand = (int) Math.round((high - low) * new Random().nextDouble() + low); for (int i = 0; i < except.length; i++) //UBound(except) { if (getRand == except[i]) { terminado = false; } } // i } return getRand; } else { return high; // or low (it doesn't matter). } }

/** * Obtiene el minimo cromosoma * * @return int */ private static int Minimo() { // Devuelve un Ãndice de matriz. int tamanioPoblacion = 0; Cromosoma cromosoma = null; Cromosoma comosomaAux = null; int winner = 0; boolean foundNewWinner = false; boolean terminado = false;

while (!terminado) { foundNewWinner = false; tamanioPoblacion = poblacion.size(); for (int i = 0; i < tamanioPoblacion; i++) { if (i != winner) { // Avoid self-comparison.

Page 12: Algoritmos Genéticos

cromosoma = poblacion.get(i); comosomaAux = poblacion.get(winner); if (cromosoma.getConflictos() < comosomaAux.getConflictos()) { winner = i; foundNewWinner = true; } } } if (foundNewWinner == false) { terminado = true; } } return winner; }

/** * Obtiene el maximo cromosoma * * @return */ private static int Maximo() { // Devuelve un Ãndice de matriz. int tamanioPoblacion = 0; Cromosoma cromosoma = null; Cromosoma comosomaAux = null; int winner = 0; boolean foundNewWinner = false; boolean terminado = false;

while (!terminado) { foundNewWinner = false; tamanioPoblacion = poblacion.size(); for (int i = 0; i < tamanioPoblacion; i++) { if (i != winner) { // Avoid self-comparison. cromosoma = poblacion.get(i); comosomaAux = poblacion.get(winner); if (cromosoma.getConflictos() > comosomaAux.getConflictos()) { winner = i; foundNewWinner = true; } } } if (foundNewWinner == false) { terminado = true; } } return winner; }

/** * Generar poblacion inicial */ private static void GenerarPoblacionInicial() { int shuffles = 0; Cromosoma newChromo = null;

Page 13: Algoritmos Genéticos

int chromoIndex = 0;

for (int i = 0; i < poblacionIni; i++) { newChromo = new Cromosoma(anchoTablero); poblacion.add(newChromo); chromoIndex = poblacion.indexOf(newChromo);

// Escoja al azar el número de baraja realizar. shuffles = NumeroAleatorio(minBaraja, maxBaraja);

IntercambiarMutacion(chromoIndex, shuffles);

poblacion.get(chromoIndex).CalcularConflictos();

} return; }}public class Cromosoma {

private int anchoTablero = 0; private int genes[]; private double fitness = 0.0; private boolean seleccionado = false; private double probSeleccion = 0.0; private int conflictos = 0;

/** * Constructor del la clase */ public Cromosoma(int longitud) {

this.anchoTablero = longitud; genes = new int[longitud];

for (int i = 0; i < longitud; i++) { this.genes[i] = i; } }

/** * Calcula los conflictos de movimiento entre las reinas */ public void CalcularConflictos() { int x = 0; int y = 0; int auxx = 0; int auxy = 0; String tablero[][] = new String[anchoTablero][anchoTablero]; int numConflictos = 0; int dx[] = new int[]{-1, 1, -1, 1}; int dy[] = new int[]{-1, 1, 1, -1}; boolean terminado = false;

// Limpia el tablero. for (int i = 0; i < anchoTablero; i++) { for (int j = 0; j < anchoTablero; j++) {

Page 14: Algoritmos Genéticos

tablero[i][j] = ""; } }

for (int i = 0; i < anchoTablero; i++) { tablero[i][this.genes[i]] = "Q"; }

// Recorrer cada una de las Reinas y calcular el número de conflictos. for (int i = 0; i < anchoTablero; i++) { x = i; y = this.genes[i];

// Evaluar diagonales. for (int j = 0; j <= 3; j++) { auxx = x; auxy = y; terminado = false; while (!terminado) { auxx += dx[j]; auxy += dy[j]; if ((auxx < 0 || auxx >= anchoTablero) || (auxy < 0 || auxy >= anchoTablero)) { terminado = true; } else { if (tablero[auxx][auxy].compareToIgnoreCase("Q") == 0) { numConflictos++; } } } } }

this.conflictos = numConflictos; }

/** * Coloca conflicto * * @param value */ public void setConflictos(int value) { this.conflictos = value; }

/** * Obtiene conflicto * * @return int */ public int getConflictos() { return this.conflictos; }

/**

Page 15: Algoritmos Genéticos

* Obtiene la probabilidad de seleccion * * @return double */ public double getProbSeleccion() { return probSeleccion; }

/** * Coloca la probabilidad de seleccion * * @param SelProb */ public void setProbSeleccion(double SelProb) { probSeleccion = SelProb; }

/** * Obtiene si esta seleccionado * * @return boolean */ public boolean getSeleccionado() { return seleccionado; }

/** * Selecciona el cromosoma * * @param sValue */ public void setSeleccionado(boolean sValue) { seleccionado = sValue; }

/** * Obtiene el grado de optitud del cromosoma * * @return double */ public double getFitness() { return fitness; }

/** * Coloca el grado de aptitud del cromosoma * * @param score */ public void SetFitness(double score) { fitness = score; }

/** * Coloca los genes al cromosoma * * @param index

Page 16: Algoritmos Genéticos

* @return int */ public int setGenes(int index) { return genes[index]; }

/** * Obtiene los genes del cromosoma * * @param index * @param value */ public void getGenes(int index, int value) { genes[index] = value; }}

OTRO EJEMPLO

package

com.ecollado.g

a;

import java.util.Arrays;

import java.util.List;

import java.util.Random;

import java.util.Vector;

import java.util.Collection;

import java.util.Iterator;

import org.apache.log4j.LogManager;

import org.apache.log4j.Logger;

import com.ecollado.ga.gui.GARobotWindow;

/**

* @author qestcol

*

*/

public class AGRobot {

private static Logger logGeneraciones =

LogManager.getLogger("generaciones");

private static Logger logGeneral =

LogManager.getLogger("general");

private static Logger logSelection =

LogManager.getLogger("seleccion");

private static final int ROULETTE_SELECTION = 2;

private static final int TOURNAMENT_SELECTION = 0;

private int selectionSchema = TOURNAMENT_SELECTION;

private int numPopulations = 1000;

private int sizePopulation = 1000;

private int numCrowsoverPoints = 1;

private double mutationProbability = 0.1;

// Each individual of the population will be coded as an

array of integers, whe the positions x,y of ech

// element of the path. The total population if a list of

population.

Page 17: Algoritmos Genéticos

private List<int[]> population;

// Each individual of the population is evaluated

(fitness value).

// Array of evaluations for each individual.

private double[] fitnessValues;

// Fitness implementation to evaluate the population.

private RobotFitness fitness;

// Index tot he worse evaluated individual.

private int worseIndividual;

// Index to the best evaluated individual.

private int bestIndividual;

private Position startPosition;

private Position endPosition;

private GridTable scene;

private boolean stop = false;

// Constructor

// A robot is initialized with the start position and end

position of the route, and the table

// where the robot will have to move in.

public AGRobot(

Position pStartPosition,

Position pEndPosition,

GridTable pScene) {

this.startPosition = pStartPosition;

this.endPosition = pEndPosition;

this.scene = pScene;

fitness = new RobotFitness();

}

public int getNumPopulations() {

return numPopulations;

}

public void setNumPopulations(int numpopulations) {

this.numPopulations = numpopulations;

}

public int getSizePopulation() {

return sizePopulation;

}

public void setSizePopulation(int sizepopulation) {

this.sizePopulation = sizepopulation;

}

public int[] getBestIndividual() {

if(this.population != null)

return this.population.get(this.bestIndividual);

return null;

}

// Start the genetic algorithm execution.

// This method is the typical main method of any genetic

algorithm, where the next steps can be seen:

// 1- create initial population.

// 2- evaluate population

Page 18: Algoritmos Genéticos

// 3- generate next population

// 4- apply mutations

//

// the steps 2 to 4 are re-peated until the max number of

population have been reached or the current population

// cotnains a individual with the desired solution quality.

public void iterate() {

long time1 = System.currentTimeMillis();

this.createInitialPopulation();

long time2 = System.currentTimeMillis();

//log.debug("Poblaci�n inicial creada con " +

// this.numPopulations + " individuos");

//log.debug("\t tiempo empleado "

// + (time2-time1) + " milisegundos.");

this.printPopulation();

this.stop = false;

int n = 0;

for (n=0; n < numPopulations; n++) {

if(logGeneral.isDebugEnabled()) {

logGeneral.debug("************ Population "

+ n);

logGeneraciones.debug("************

Population " + n);

}

//log.debug("Size: " + this.population.size());

this.evaluatePopulation();

if(this.stop)

break;

this.generateNextPopulation();

this.mutation();

}

logGeneral.debug("Algoritmo terminado con el fitness: "

+ this.fitnessValues[this.bestIndividual]);

logGeneral.debug("Individuo: " +

this.printArray(this.population.get(this.bestIndividual)));

this.printPopulation();

}

// It calculates the fitness value for each individual of

the population storing

// reference to the best and worst individuals.

private void evaluatePopulation() {

logGeneral.debug("[Evaluating population...]");

this.fitnessValues =

this.fitness.calculateDoubleFitness(this.population,

scene, startPosition, endPosition);

//log.debug(this.printArray(fitnessValues));

double bestFitness = Double.MAX_VALUE;

double worseFitness = Double.MIN_VALUE;

for(int i=fitnessValues.length;--i>=0;) {

Page 19: Algoritmos Genéticos

if(fitnessValues[i]<bestFitness) {

bestFitness = fitnessValues[i];

this.bestIndividual = i;

} else {

if(fitnessValues[i]>worseFitness) {

worseFitness = fitnessValues[i];

this.worseIndividual = i;

}

}

}

if(bestFitness == 0.0)

this.stop = true;

logGeneral.debug("Mejor Fitness: " +

fitnessValues[this.bestIndividual] + " en el

individuo: " + this.bestIndividual);

logGeneral.debug("Peor Fitness: " +

fitnessValues[this.worseIndividual] + " en

el individuo: " + this.worseIndividual);

if(logGeneraciones.isDebugEnabled()) {

logGeneraciones.debug("Vector fitness: " +

this.printArray(fitnessValues));

}

}

//

private void generateNextPopulation() {

List<int[]> nextPopulation = new Vector<int[]>();

int[] selectedIndividuals = this.selection();

int[] parent1,parent2=null;

for(int i=selectedIndividuals.length;--i>=0;) {

if(selectedIndividuals[i] == this.worseIndividual)

{

selectedIndividuals[i] =

this.bestIndividual;

}

}

if(logGeneraciones.isDebugEnabled()) {

logGeneraciones.debug("[GenerateNextPopulation]");

logGeneraciones.debug(this.printArray(selectedIndividuals));

}

for(int i=selectedIndividuals.length-1;i>0;i-=2) {

parent1 =

this.population.get(selectedIndividuals[i]);

for(int j=i;--j>=0;) {

if(selectedIndividuals[j] !=

selectedIndividuals[i]) {

parent2 =

this.population.get(selectedIndividuals[j]);

break;

Page 20: Algoritmos Genéticos

}

}

if(parent2 == null) continue;

if(logGeneraciones.isDebugEnabled()) {

logGeneraciones.debug("Padre 1: " +

this.printArray(parent1));

logGeneraciones.debug("Padre 2: " +

this.printArray(parent2));

}

//child1 = this.crowssOverNPoint(parent1,

parent2);

//logGeneraciones.debug("Hijo 1: " +

this.printArray(child1));

//child2 = this.crowssOverNPoint(parent2,

parent1);

//log.debug("Hijo 2: " + this.printArray(child2));

//nextPopulation.add(child1);

//nextPopulation.add(child2);

List<int[]> childs =

this.crowssOverDoubleNPoint(parent1, parent2);

if(logGeneraciones.isDebugEnabled()) {

logGeneraciones.debug("Hijo1: " +

this.printArray(childs.get(0)));

logGeneraciones.debug("Hijo2: " +

this.printArray(childs.get(1)));

}

nextPopulation.add(childs.get(0));

nextPopulation.add(childs.get(1));

}

//assign new population

nextPopulation.add(this.population.get(this.bestIndividual));

this.population = nextPopulation;

}

// It chooses the individuals to be used as based for the

next generation creation.

// Two implementations available:

// 1- Roulette

// 2- Tournament

//

private int[] selection() {

if(selectionSchema == AGRobot.ROULETTE_SELECTION)

return this.rouletteSelection();

else if (selectionSchema == AGRobot.TOURNAMENT_SELECTION)

return this.tournamentSelection();

else

return null;

}

// The individuals with better fitness values have more

Page 21: Algoritmos Genéticos

probabilities to be chosen to be used as based

// for the next generation.

private int[] rouletteSelection() {

double sumFitness = 0;

double partialSum = 0;

double [] normFitness;

double[] cumulativeFitness;

int[] selectedIndividuals;

Random random;

double rValue;

//calculate sumFitness

for(int i=this.fitnessValues.length;--i>=0;) {

sumFitness += this.fitnessValues[i];

}

//normalize all fitness

normFitness = new double[this.fitnessValues.length];

for(int i=this.fitnessValues.length;--i>=0;) {

normFitness[i] = fitnessValues[i] / sumFitness;

}

//cumulative fitness

cumulativeFitness = new double[fitnessValues.length];

for(int i=-1;++i<normFitness.length;) {

partialSum += normFitness[i];

cumulativeFitness[i] = partialSum;

}

if(logSelection.isDebugEnabled()) {

logSelection.debug("[routeSelection]");

logSelection.debug("Population:");

logSelection.debug(printArray(this.fitnessValues));

logSelection.debug("Sum Fitness: " + sumFitness);

logSelection.debug("Normalized Fitness");

logSelection.debug(printArray(normFitness));

logSelection.debug("Cumulative Fitness");

logSelection.debug(this.printArray(cumulativeFitness));

logSelection.debug("Selecting...");

}

//select individuals

random = new Random();

selectedIndividuals = new int[this.population.size()-1];

for(int i=this.population.size()-1;--i>=0;) {

rValue = random.nextDouble();

for(int j=-1;++j<cumulativeFitness.length;) {

if(cumulativeFitness[j] >= rValue) {

selectedIndividuals[i] = j;

if(logSelection.isDebugEnabled()) {

logSelection.debug("Random

Number: " + rValue + " individual: " + j);

}

Page 22: Algoritmos Genéticos

break;

}

}

}

return selectedIndividuals;

}

// Two individuals are randomly chosen, and the one with

better fitness value is finally chosen as based for the

// next generation.

private int[] tournamentSelection() {

int[] selectedIndividuals = new

int[this.population.size()-1];

Random random;

int rValue1,rValue2;

//select individuals

random = new Random();

for(int i=this.population.size()-1;--i>=0;) {

rValue1 = random.nextInt(this.population.size());

rValue2 = random.nextInt(this.population.size());

selectedIndividuals[i] = (fitnessValues[rValue1]

<= fitnessValues[rValue2]) ?

rValue1:rValue2;

}

return selectedIndividuals;

}

// A second pair of individuals is generated based on the

two individuals passed as argument.

// Based on the global variable numCrowsoverPoints, the

parents are split on segments, and the children

// are generated using different segments of the parents

paths.

private List<int[]> crowssOverDoubleNPoint(int[] parent1,

int[] parent2) {

List<int[]> childs = new Vector<int[]>();

int[] child1 = new int[parent1.length];

int[] child2 = new int[parent2.length];

int[] points = new int[numCrowsoverPoints];

int point;

boolean p1 = true;

Random rValue = new Random();

if(logGeneraciones.isDebugEnabled()) {

logGeneraciones.debug("[crowssOverNPoint]");

}

for(int i=numCrowsoverPoints;--i>=0;) {

points[i] = rValue.nextInt(parent1.length-3)+1;

}

Arrays.sort(points);

if(logGeneraciones.isDebugEnabled()) {

logGeneraciones.debug("Points: " +

this.printArray(points));

Page 23: Algoritmos Genéticos

}

int pointBelow = parent1.length-1;

for(int i=points.length;--i>=0;) {

point = points[i];

for(;--pointBelow>=point;) {

if(p1) {

child1[pointBelow] =

parent1[pointBelow];

child2[pointBelow] =

parent2[pointBelow];

} else {

child1[pointBelow] =

parent2[pointBelow];

child2[pointBelow] =

parent1[pointBelow];

}

}

pointBelow++;

p1 = (p1) ? false:true;

}

for(;--pointBelow>=0;) {

if(p1) {

child1[pointBelow] =

parent1[pointBelow];

child2[pointBelow] =

parent2[pointBelow];

} else {

child1[pointBelow] =

parent2[pointBelow];

child2[pointBelow] =

parent1[pointBelow];

}

}

childs.add(child1);

childs.add(child2);

return childs;

}

private int[] crowssOverNPoint(int[] parent1, int[]

parent2) {

int[] child = new int[parent1.length];

int[] points = new int[numCrowsoverPoints];

int point;

boolean p1 = true;

Random rValue = new Random();

//log.debug("[crowssOverNPoint]");

for(int i=numCrowsoverPoints;--i>=0;) {

points[i] = rValue.nextInt(parent1.length-3)+1;

}

Arrays.sort(points);

//log.debug("Points: " + this.printArray(points));

Page 24: Algoritmos Genéticos

int pointBelow = parent1.length-1;

for(int i=points.length;--i>=0;) {

point = points[i];

for(;--pointBelow>=point;) {

child[pointBelow] = (p1) ?

parent1[pointBelow]:parent2[pointBelow];

}

pointBelow++;

p1 = (p1) ? false:true;

}

for(;--pointBelow>=0;) {

child[pointBelow] = (p1) ?

parent1[pointBelow]:parent2[pointBelow];

}

return child;

}

private void mutation() {

Random random = new Random();

if( this.mutationProbability < random.nextDouble() )

return;

int r = random.nextInt(this.sizePopulation-1);

while(r == this.bestIndividual)

r = random.nextInt(this.sizePopulation-1);

int aux;

logGeneral.debug("[mutation]");

logGeneral.debug("Individuo mutado: " + r);

//intercambio de las posiciones pares (x)

int[] individual = this.population.get(r);

int i1 = random.nextInt(individual.length-3)+1;

int i2 = random.nextInt(individual.length-3)+1;

int i3 = random.nextInt(individual.length-3)+1;

int i4 = random.nextInt(individual.length-3)+1;

if(i1 % 2 != 0)

i1++;

if(i2 % 2 != 0)

i2++;

if(i3 % 2 != 0)

i3++;

if(i4 % 2 != 0)

i4++;

aux = individual[i1];

individual[i1] = individual[i2];

individual[i2] = aux;

aux = individual[i3];

individual[i3] = individual[i4];

individual[i4] = aux;

//intercambio de las posiciones impares(direcci�n)

i1 = random.nextInt(individual.length-1);

Page 25: Algoritmos Genéticos

i2 = random.nextInt(individual.length-1);

if(i1 % 2 == 0)

i1++;

if(i2 % 2 == 0)

i2++;

aux = individual[i1];

individual[i1] = individual[i2];

individual[i2] = aux;

//una mutaci�n por inserci�n

i1 = random.nextInt(individual.length-3)+1;

if(i1 % 2 != 0)

i1++;

individual[i1] = random.nextInt(this.scene.getWeight()-

1)+1;

}

// The initial population is randomly generated.

private void createInitialPopulation() {

this.population = new Vector<int[]>();

for (int i=0; i < this.sizePopulation; i++) {

this.population.add(

this.createRamdonIndividual());

}

}

private int[] createRamdonIndividual() {

int[] individual;

int yo = this.startPosition.getY();

int yd = this.endPosition.getY();

int sign = (yo < yd) ? 1:-1;

Random random = new Random();

int x;

int d;

individual = new int[((yd-yo)*sign+1)*2];

//first position (startPosition)

individual[0] = this.startPosition.getX();

individual[1] = random.nextInt(2);

//middle positions

for(int i=2;i<individual.length-3;i+=2) {

x = random.nextInt(this.scene.getWeight()-2)+1;

d = random.nextInt(2);

individual[i] = x;

individual[i+1] = d;

}

//final position (endPosition)

individual[individual.length-2] =

this.endPosition.getX();

individual[individual.length-1] = 0;

return individual;

}

private String printArray(double[] vArray) {

String str = "";

Page 26: Algoritmos Genéticos

for(int i=0;i<vArray.length;i++)

str += vArray[i] + ",";

return str;

}

private String printArray(int[] vArray) {

String str = "";

for(int i=0;i<vArray.length;i++)

str += vArray[i] + ",";

return str;

}

private void printPopulation() {

logGeneraciones.debug("**************GENERATION*************");

for(int i=0;i<this.population.size();i++) {

int[] individual = this.population.get(i);

logGeneraciones.debug(printArray(individual));

}

logGeneraciones.debug("**************GENERATION*************");

}

public static void main(String[] args) {

GridTable scene = new GridTable();

AGRobot ag = new AGRobot(

new Position(1,1),

new

Position(27,18),

//new

Position(18,19),

scene);

ag.iterate();

GARobotWindow window =

new GARobotWindow(

scene,

new Position(1,1),

new Position(27,18),

//new Position(18,19),

ag.getBestIndividual());

}

}