#!/usr/bin/perl
use warnings;
use strict;
#Incluimos los elementos de la librería necesarios
use Algorithm::Evolutionary::Individual::Vector;
use Algorithm::Evolutionary::Op::Easy;
use Algorithm::Evolutionary::Op::GaussianMutation;
use Algorithm::Evolutionary::Op::VectorCrossover;
#----------------------------------------------------------#
#leemos los parámetros de la línea de comandos
my $popSize = shift || 100;
my $numGens = shift || 100 ;
#----------------------------------------------------------#
#Definimos la función de fitness,
que es la función Griewank
my $funcion_griewank = sub {
my $indi = shift;
my @cr = @{$indi->{_array}};
my $fr=4000;
my $sum;
my $prod=1;
for(my $i=1; $i<=$#cr; $i++){
$sum+=$cr[$i-1]^2;
$prod*=cos($cr[$i-1]/sqrt($i));
}
return -$sum/$fr + $prod-1;
#Using n==2
#my ($x, $y) = @{$indi->{_array}};
#return ($x*$x+$y*$y)/$fr
#-(cos($x)+ cos($y)/sqrt(2));
};
#----------------------------------------------------------#
#Creamos la población inicial con $popSize
individuos
my @pop;
for ( 0..$popSize ) {
my $indi = Algorithm::Evolutionary
::Individual::Vector->new( 2 );
push( @pop, $indi );
}
#----------------------------------------------------------#
#Definimos los operadores de variación
my $mut_operator = Algorithm::Evolutionary::Op::
GaussianMutation->new( 0, 0.1 );
my $cross_operator = Algorithm::Evolutionary::Op::
VectorCrossover->new(2);
#----------------------------------------------------------#
# Usamos estos operadores para definir una
# generación del algoritmo. Lo cual
# no es realmente necesario ya que este algoritmo
# define ambos operadores por
# defecto. Los parámetros son la función de
# fitness, la tasa de selección y
# los operadores de variación.
my $generation = Algorithm::Evolutionary::Op
::Easy->new( $funcion_griewank,
0.2 , [$mut_operator, $cross_operator] ) ;
#----------------------------------------------------------#
#Evaluamos la población inicial
for( @pop ){
if ( !defined $_->Fitness() ) {
my $fitness = $funcion_griewank->($_);
$_->Fitness( $fitness );
}
}
#Bucle del algoritmo evolutivo
my $contador=0;
do {
$generation->apply( \@pop );
print "$contador : ", $pop[0]->asString(),
"\n" ;
$contador++;
} while( $contador < $numGens );
#----------------------------------------------------------#
#Tomamos la mejor solución encontrada y la mostramos
my ( $x, $y ) = @{$pop[0]->{_array}};
print "El mejor es:\n\t ";
print $pop[0]->asString() ;
print "\n\t x=$x \n\t y=$y \n\t Fitness: ";
print $pop[0]->Fitness() ;
Lo único a destacar es que yo la había hecho para sólo dos elementos, pero al ver que todo el mundo la ha generalizado, pues no iba yo a ser menos ...
En fin, en el siguiente enlace está la captura de pantalla que demuestra que el algoritmo funciona
No hay comentarios:
Publicar un comentario