``````#!/usr/bin/perl

tide_bitstring.pl - Implementation of the Tide optimization using A::E

prompt% ./tide_bitstring.pl <population> <number of generations>

or

prompt% perl tide_bitstring.pl <population> <number of generations>

# Shows the values of the two floating-point components of the
# chromosome and finally the best value and fitness reached, which
# should be as close to 1 as possible.

A simple example of how to run an Evolutionary algorithm based on
Algorithm::Evolutionary. Tries to find the max of the bidimensional
Tide , and outputs the x and y coordinates, along with fitness. Best
fitness is close to 1. Around 50 generations should be enough, but
default is population and number of generations equal to 100.
This one uses a bitstring, as opposed to floating point, representation.

=cut

use warnings;
use strict;

use Time::HiRes qw( gettimeofday tv_interval);

use lib qw(lib ../lib);
use Algorithm::Evolutionary::Individual::BitString;
use Algorithm::Evolutionary::Op::Easy;
use Algorithm::Evolutionary::Op::Bitflip;
use Algorithm::Evolutionary::Op::Crossover;
use Algorithm::Evolutionary::Op::Creator;

#----------------------------------------------------------#
my \$popSize = shift || 100; #Population size
my \$numGens = shift || 100; #Max number of generations
my \$precision = shift || 20;

my \$max = 2 << \$precision -1;
#----------------------------------------------------------#
#Fitness function will be Tide
my \$funcionMarea = sub {
my \$indi = shift;
my \$str = \$indi->Chrom();

#extraemos los dos números reales de la cadena binaria
my \$l2=length(\$str)/2;
my \$x=eval("0b".substr (\$str, 0, \$l2));
\$x = \$x/\$max*2 -1;
my \$y=eval("0b".substr (\$str, \$l2));
\$y = \$y/\$max*2 -1;
my \$sqrt = sqrt( \$x*\$x+\$y*\$y);

if( !\$sqrt ){ return 1; }
return sin( \$sqrt )/\$sqrt;
};

#----------------------------------------------------------#
# Variation operators
my \$m = Algorithm::Evolutionary::Op::Bitflip->new();
my \$c = Algorithm::Evolutionary::Op::Crossover->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( \$funcionMarea , 0.2 , [\$m, \$c] ) ;

#Time
my \$inicioTiempo = [gettimeofday()];
#----------------------------------------------------------#
#Initial population
my @pop;
my \$creator = new Algorithm::Evolutionary::Op::Creator( 20, 'BitString', { length => \$precision*2 } );
\$creator->apply( \@pop );
map( \$_->evaluate(\$funcionMarea), @pop );

do {
\$generation->apply( \@pop );

print "\$contador : ", \$pop[0]->asString(), "\n" ;

} while( \$contador < \$numGens );

#----------------------------------------------------------#
# Show the best
print "El mejor es:\n\t ",\$pop[0]->asString()," Fitness: ",\$pop[0]->Fitness(),"\n";

print "\n\nTime: ". tv_interval( \$inicioTiempo ) . "\n";

Contributed by Pedro Castillo Valdivieso, modified by J. J. Merelo

=cut