Vous êtes sur la page 1sur 28

Algoritmos Genticos (# Reinas)

ALGORTIRMOS GENETICOS
Los Algoritmos Genticos (AG's) son mtodos adaptativos que pueden usarse para resolver
problemas de bsqueda y optimizacin. Estn basados en el proceso gentico de los organismos
vivos. A lo largo de las generaciones, las poblaciones evolucionan en la naturaleza de acorde con
los principios de la seleccin natural y la supervivencia de los ms fuertes, postulados por Darwin
(1859). Por imitacin de este proceso, los Algoritmos Genticos son capaces de ir creando
soluciones para problemas del mundo real. La evolucin de dichas soluciones hacia valores
ptimos del problema depende en buena medida de una adecuada codificacin 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 alemn 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;
// Tamao 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

*/
public static void AlgoritmoGenetico(JTextArea tablero, JTextArea
generaciones) {
int tamanioPoblacion = 0;
Cromosoma cromosoma = null;
boolean terminado = false;
GenerarPoblacionInicial();
poblacin inicial

//Genera

numMutaciones = 0;
sigMutacion = NumeroAleatorio(0, (int) Math.round(1.0 /
tasaMutacion));
while (!terminado) {
terminada la bsqueda
tamanioPoblacion = poblacion.size();
poblacin
for (int i = 0; i < tamanioPoblacion; i++) {
cromosoma = poblacion.get(i);
if ((cromosoma.getConflictos() == 0)) {
terminado = true;
}
}

//Mientras no

Fitness();
fitness dependiendo la cantidad de conflictos

//Calcula el

Seleccion();
los padres de la siguiente generacin

//Selecciona

Reproduccion();
cruce parcial de los padres

//Realiza el

PrepararSiguienteGeneracion();
los hijos de la siguiente generacin

//Selecciona

//Tamao de

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() {

// Menor error = 100%, Mayor Error = 0%


int tamanioPoblacion = poblacion.size();
Cromosoma cromosoma = null;
double mejor = 0;
double peor = 0;
// La peor puntuacin sera el que tiene la mayor energa, mejor
ms 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();

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;

// 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;
}

} // 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++) {

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.

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() {
// Funcin sobrecargada, consulta "choosepadre (ByVal Parenta As
Integer)".

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) {
// Funcin 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);
}
}

/**
* 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);

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.

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;

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 nmero de baraja realizar.
shuffles = NumeroAleatorio(minBaraja, maxBaraja);
IntercambiarMutacion(chromoIndex, shuffles);
poblacion.get(chromoIndex).CalcularConflictos();
}
return;
}
}
public class Cromosoma {
private
private
private
private
private
private

int anchoTablero = 0;
int genes[];
double fitness = 0.0;
boolean seleccionado = false;
double probSeleccion = 0.0;
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++) {

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 nmero 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
*
* @return
*/
public int
return
}
/**

conflicto
int
getConflictos() {
this.conflictos;

* 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

* @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.ga;
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.
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
// 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("Poblacin 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;) {
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;
}
}
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 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);
}
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));
}
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));
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(direccin)
i1 = random.nextInt(individual.length-1);
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 mutacin por insercin
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 = "";
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());
}
}

Vous aimerez peut-être aussi