¿Cómo implementar un algoritmo genético en Java?
Recorre el laberinto mediante un algoritmo genético. Aunque tanto las Figuras 1 como 2 salieron exitosamente del laberinto, el camino en la Figura 1 es mucho más largo y complejo que el de la Figura 2. El algoritmo genético puede calcular cuántas posibilidades hay y seleccionar la más simple como resultado de la operación.
Figura de muestra 1:
Figura de muestra 2:
Código de implementación:
import?java.util.ArrayList;
importar?java.util.Collections;
importar?java.util.Iterator;
importar?java.util.LinkedList;
importar ?java.util.List;
import?java.util.Random;
/** * Usa algoritmo genético para caminar por el laberinto* * @author Orisun * */ p>
public?class?GA {
int?gene_len;?//longitud del gen
int?chrom_len;?//longitud del cromosoma
int? población;?// Tamaño de la población
double?cross_ratio;?// Tasa de cruce
double?muta_ratio;?// Tasa de mutación
int? iter_limit; ?// Las generaciones más evolucionadas
Listlt; boolean[]gt; individuos;?// Almacena los cromosomas de la población contemporánea
Laberinto laberinto;
int? width;?//Cuántas celdas hay en una fila del laberinto
int?height;?//Cuántas filas hay en el laberinto
público ?clase?BI {
doble ?fitness;
booleano[] indv
público?BI(doble?f, ?booleano[] ind) {
fitness = f;
p>indv = ind;
}
public?double?getFitness() {
retorno?fitness;
}
public?boolean[] getIndv() {
retorno?indv;
}
}
Listlt; BIgt; best_individual;?// Almacena los mejores individuos de cada generación
public?GA(Labyrinth labyrinth) {
this.labyrinth=labyrinth;?
this.width = labyrinth.map[0].length;
this.height = labyrinth.map.length; p>
chrom_len =?4?* (ancho alto);
gene_len =?2;
población =?20;
cross_ratio =? 0.83;
muta_ratio =?0.002;
iter_limit =?300;
individuos =?new?ArrayListlt;boolean[]gt;(población);
mejor_individual =?nuevo?Ar
rayListlt;BIgt;(iter_limit);
}
public?int?getWidth() {
return?width;
}
public?void?setWidth(int?width) {
this.width = ancho;
}
public?double? getCross_ratio() {
retorno?cross_ratio;
}
público?Listlt;BIgt; getBest_individual() {
retorno?mejor_individual ;
}
público?Laberinto getLabyrinth() {
retorno?laberinto;
}
público ?void?setLabyrinth(Laberinto laberinto) {
this.labyrinth = laberinto;
}
public?void?setChrom_len(int?chrom_len) { p>
p>
this.chrom_len = chrom_len;
}
public?void?setPopulation(int?population) {
esto .población = población;
}
public?void?setCross_ratio(double?cross_ratio) {
this.cross_ratio = cross_ratio
}
público?void?setMuta_ratio(double?muta_ratio) {
this.muta_ratio = muta_ratio;
}
¿público? void?setIter_limit(int ?iter_limit) {
this.iter_limit = iter_limit;
}
//Inicializar la población
público ?void?initPopulation() {
Aleatorio r =?new?Random(System.currentTimeMillis());
for?(int?i =?0; i lt; población ; i ) {
p>
int?len = gene_len * chrom_len;
boolean[] ind =?new?boolean[len];
for?(int?j =?0; j lt; len; j )
ind[j] = r.nextBoolean();
individuos.add(ind);
}
}
// Cruz
public?void?cross(boolean[] arr1,?boole
an[] arr2) {
Aleatorio r =?new?Random(System.currentTimeMillis());
int?length = arr1.length;
int?slice =?0;
hacer?{
slice = r.nextInt(longitud);
}? while?(slice ==?0 );
si?(slice lt; longitud /?2) {
for?(int?i =?0; i lt; slice; i ) {
booleano?tmp = arr1[i];
arr1[i] = arr2[i];
arr2[i] = tmp;
}
}?else?{
for?(int?i = segmento; i lt; longitud; i) {
booleano?tmp = arr1[ i];
arr1[i] = arr2[i];
arr2[i] = tmp;
}
}
}
// Mutación
public?void?mutation(boolean[] individual) {
int?length = individuo. longitud;
Aleatorio r =?new?Random(System.currentTimeMillis());
individual[r.nextInt(longitud)] ^=?false;
}
//El método de la ruleta selecciona la siguiente generación y devuelve el valor de aptitud más alto en la generación actual
public?double?selection() {
boolean [][] next_generación =?new?boolean[población][];?// próxima generación
int?length = gene_len * chrom_len;
for?(int? i = ?0; i lt; población; i )
siguiente_generación[i] =?nuevo?booleano[longitud];
doble[] acumulación =?nuevo?doble[población] ];
int?best_index =?0;
doble?max_fitness = getFitness(individuos.get(best_index));
acumulación[0] = max_fitness ;
for?(int?i =?1; i lt; población; i ) {
doble?fit = getFitness(individuos.get(i));
acumulación[i] = acumulación[i -?1] fit;
//Encuentra el mejor individuo contemporáneo
if?(fit gt; max_fitness) { p >
mejor_índice = i;<
/p>
max_fitness = ajuste;
}
}
Rand aleatorio =?new?Random(System.currentTimeMillis()); p>
p>
for?(int?i =?0; i lt; población; i )
próxima_generación[i] = individuos.get(findByHalf(acumulación,
rand .nextDouble() * cumulation[population -?1]));
//Coloque el individuo óptimo contemporáneo y su aptitud en best_individual
BI bi =? nuevo ?BI(max_fitness, individuos.get(best_index));
// printPath(individuos.get(best_index));
//System.out.println(max_fitness) ;
best_individual.add(bi);
//La nueva generación es la generación actual
for?(int?i =?0; i lt ; población; i )
individuos.set(i, próxima_generación[i]);
retorno?max_fitness;
}
// Reducir a la mitad la búsqueda
public?int?findByHalf(double[] arr,?double?find) {
if?(find lt;?0?|| find ==? 0?| | encontrar gt; arr[arr.length -?1])
retorno?-1;
int?min =?0;
int?max = arr.length -?1;
int?medium = min;
hacer?{
if?(medio == (min max ) /? 2)
romper;
medio = (mínimo máximo) /?2;
si?(arr[medio] lt; buscar)
min = medio;
else?if?(arr[medium] gt; find)
max = medio;
else
retorno?medio;
}?mientras?(min lt; max
retorno?max
}
// Calcular condición física
public?double?getFitness(boolean[] individual) {
int?length = individual.length;
/ / Registro La posición actual, el punto de entrada es (1, 0)
int?x =?1;
int?y =?0;
//Según La guía de los genes en los cromosomas avanza
for?(int?i =?0; i lt; length; i) {
>
boolean?b1 = individuo[i];
boolean?b2 = individuo[i];
// 00 ir a la izquierda
si ? (b1 ==?false?amp; b2 ==?false) {
if?(x gt;?0?amp;amp; laberinto.map[y][x -?1 ] == ?verdadero) {
x--;
}
}
// 01 Ir a la derecha
else?if?(b1 ==?false?amp;amp; b2 ==?true) {
if?(x ?1?lt; ancho amp;amp; laberinto.map [y][ x ?1] ==?true) {
x ;
}
}
// 10 arriba Ir
else?if?(b1 ==?true?amp; b2 ==?false) {
if?(y gt;?0?amp;amp; laberinto.map[y - ?1][x] ==?true) {
y--;
}
}
// 11 ir abajo
else?if?(b1 ==?true?amp; amp; b2 ==?true) {
if?(y ?1 ?lt; altura amp; amp ; laberinto.map[y ?1][x] ==?true) {
y;
}
}
}
int?n = Math.abs(x - laberinto.x_end) Math.abs(y -labyrinth.y_end) ?1
/ /? if(n== 1)
//? printPath(individual);
return?1.0?/ n;
}
// Ejecute el algoritmo genético
public?boolean?run() {
// Inicializar la población
initPopulation();
Rand aleatorio = ?new?Random(System.currentTimeMillis());
boolean?success =?false;
mientras?(iter_limit-- gt;?0) {
//Barajar el orden de la población
Collections.shuffle(individuals);
for?(int?i =?0; i lt; población - ?1; i =?2) {
// Cruz
if?(rand.nextDouble() lt; cross_ratio) {
cruz(individuos. get(i) , individuos.get(i ?1));
}
// Mutación
if?(rand.nextDouble() lt; muta_ratio) {
mutación(individuos.ge
t(i));
}
}
// Reemplazo de población
if?(selection() ==?1 ) {
éxito =?true;
romper;
}
}
retorno?éxito;
}
//? public static void main(String[] args) {
//? GA ga = new GA(8, 8);
//? if (!ga.run()) {
//? System.out.println("No se encontró ninguna ruta para salir del laberinto."); p >
//? } else {
//? int gen = ga.best_individual.size();
//? booleano[] individual = ga.best_individual . get(gen - 1).indv;
//? System.out.println(ga.getPath(individual));
//? p >//? }
//Imprimir movimientos basados en cromosomas
public?String getPath(boolean[] individual) {
int?length = individual longitud;
int?x =?1;
int?y =?0;
LinkedListlt; pila=new?LinkedListlt; ( );
for?(int?i =?0; i lt; longitud; i ) {
booleano?b1 = individual[i];
> booleano?b2 = individual[i];
si?(b1 ==?false?amp; b2 ==?false) {
si?(x gt;? 0 ?amp;amp; laberinto.map[y][x -?1] ==?true) {
x--;
if(!stack.isEmpty() amplificador ; amp; pila.peek()=="derecha")
stack.poll();
else
stack.push("izquierda") ;
}
}?else?if?(b1 ==?false?amp; amp; b2 ==?true) {
si? x ?1?lt; ancho & laberinto.map[y][x?1] ==?true) {
x ;
if(!stack. isEmpty () & stack.peek()=="izquierda")
stack.poll();
else
stack.push( "derecha" );
}
}?else?if?(b1 ==?verdadero?amp; amp; b2 ==?falso) {
si? (y gt;?0?am
p;amp; laberinto.map[y -?1][x] ==?true) {
y--;
if(!stack.isEmpty() amp; amp; stack.peek()=="下")
stack.poll();
else
stack.push("superior");
}
}?else?if?(b1 ==?verdadero?amp; amp; b2 ==?verdadero) {
si?(y ?1?lt; altura amp;amp; laberinto.map[y ?1][x] ==?true) {
y ;
if(!stack.isEmpty( ) amp; ");
}
}
}
StringBuilder sb=new?StringBuilder(longitud/4);
Iteratorlt; Stringgt; iter=stack.descendingIterator();
mientras(iter.hasNext())
sb.append(iter.next()); p>
p>
return?sb.toString();
}
}