Algorithm-Evolutionary

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN


	* MANIFEST: 0.70 fixes a bug in Easy.pm and those derived from it:
	last population element was not eliminated. An animated GIF output
	has been added, and a bug in Makefile.PL that caused problems with
	Solaris has also been fixed (Thanks to Alex Muntada).

2009-07-26    <jmerelo@localhost.localdomain>

	* lib/Algorithm/Evolutionary.pm (import): 0.69_1 fixed some
	problems with missing prerrequisites in the test programs, and
	some copy/paste stuff left from creating new modules. 0.70 starts
	with the intention of finally having a GUI.

2009-07-24    <jmerelo@localhost.localdomain>

	* lib/Algorithm/Evolutionary.pm: 0.68 was shortlived, but 0.69
	more or less the same. 0.69 included missing file and fixed some
	docs errors; 0.69_1 starts with the same objective, let's see how
	it ends.

2009-07-24  Juan Julian Merelo Guervos  <jmerelo@geneura.ugr.es>

	* TODO: 0.68 ends with several new test functions added (Trap,
	ECC), and finally a multiobjective evolutionary algorithm, not
	very good, but in working order.

2009-03-29    <jmerelo@localhost.localdomain>

	* lib/Algorithm/Evolutionary.pm: 0.68 starts with the usual
	cosmetic changes to the documentation.  

	* Added "rough consensus" utility as well as a "convergence
	terminator", which checks whether a part of the population has
	converged. Upgraded to 0.67. Already!

2009-02-21  jmerelo  <jmerelo@localhost.localdomain>

	* lib/Algorithm/Evolutionary.pm (import): Changing to 0.64_2 to
	eventually fix  the 0500-generation-skel.t, which was not written

LICENSE  view on Meta::CPAN


    a) You must cause the modified files to carry prominent notices
    stating that you changed the files and the date of any change.

    b) You must cause any work that you distribute or publish, that in
    whole or in part contains or is derived from the Program or any
    part thereof, to be licensed as a whole at no charge to all third
    parties under the terms of this License.

    c) If the modified program normally reads commands interactively
    when run, you must cause it, when started running for such
    interactive use in the most ordinary way, to print or display an
    announcement including an appropriate copyright notice and a
    notice that there is no warranty (or else, saying that you provide
    a warranty) and that users may redistribute the program under
    these conditions, and telling the user how to view a copy of this
    License.  (Exception: if the Program itself is interactive but
    does not normally print such an announcement, your work based on
    the Program is not required to print an announcement.)

These requirements apply to the modified work as a whole.  If

LICENSE  view on Meta::CPAN


		     END OF TERMS AND CONDITIONS

	    How to Apply These Terms to Your New Programs

  If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.

  To do so, attach the following notices to the program.  It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.

    <one line to give the program's name and a brief idea of what it does.>
    Copyright (C) <year>  <name of author>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

LICENSE  view on Meta::CPAN

    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA


Also add information on how to contact you by electronic and paper mail.

If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:

    Gnomovision version 69, Copyright (C) year name of author
    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
    This is free software, and you are welcome to redistribute it
    under certain conditions; type `show c' for details.

The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License.  Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.

lib/Algorithm/Evolutionary/Individual/Bit_Vector.pm  view on Meta::CPAN

sub TIEARRAY {
  my $class = shift; 
  my $self = { _bit_vector => Bit::Vector->new_Bin(scalar( @_), join("",@_)) };
  bless $self, $class;
  return $self;
}

=head2 Atom

Sets or gets the value of the n-th character in the string. Counting
starts at 0, as usual in Perl arrays.

=cut

sub Atom: lvalue {
  my $self = shift;
  my $index = shift;
  my $last_index = $self->{'_bit_vector'}->Size()-1;
  if ( @_ ) {
      $self->{'_bit_vector'}->Bit_Copy($last_index-$index, shift );
  } else {

lib/Algorithm/Evolutionary/Individual/String.pm  view on Meta::CPAN

  my $str = $self->{'_str'} . " -> ";
  if ( defined $self->{'_fitness'} ) {
	$str .=$self->{'_fitness'};
  }
  return $str;
}

=head2 Atom

Sets or gets the value of the n-th character in the string. Counting
starts at 0, as usual in Perl arrays.

=cut

sub Atom {
  my $self = shift;
  my $index = shift;
  if ( @_ ) {
    substr( $self->{_str}, $index, 1 ) = substr(shift,0,1);
  } else {
    substr( $self->{_str}, $index, 1 );

lib/Algorithm/Evolutionary/Individual/Vector.pm  view on Meta::CPAN

=head1 SYNOPSIS

    use Algorithm::Evolutionary::Individual::Vector;
    my $indi = new Algorithm::Evolutionary::Individual::Vector 10 ; # Build random vector individual with length 10
                                   # Each element in the range 0 .. 1
    my $indi2 = new Algorithm::Evolutionary::Individual::Vector 20, -5, 5; #Same, with range between -5 and 5

    #Creating a vector step by step. In Perl, there's always more than one way of doing it
    my $indi3 = new Algorithm::Evolutionary::Individual::Vector;
    $indi3->set( {length => 20,
		  rangestart => -5,
		  rangeend => 5 } );   #Sets values, but does not build the array
    
    $indi3->randomize(); #Creates an array using above parameters

    print $indi3->Atom( 7 );       #Returns the value of the 7th character
    $indi3->Atom( 3 ) = '2.35';       #Sets the value

    $indi3->addAtom( 7.5 ); #Adds a new component to the array at the end

    my $indi4 = Algorithm::Evolutionary::Individual::Vector->fromString( '3.5,4.5, 0.1, 3.2');

lib/Algorithm/Evolutionary/Individual/Vector.pm  view on Meta::CPAN


use Carp;
use Exporter;

our ($VERSION) = ( '$Revision: 3.2 $ ' =~ / (\d+\.\d+)/ );

use base 'Algorithm::Evolutionary::Individual::Base';

=head1 METHODS 

=head2 new( [$length = 10] [, $start_of_range = 0] [, $end_of_range = 1] )

Creates a new random array individual, with fixed initial length, and uniform distribution
of values within a range

=cut

sub new {
  my $class = shift; 
  my $self;
  $self->{_length} = shift || 10;
  $self->{_array} = ();
  $self->{_rangestart} = shift || 0;
  $self->{_rangeend } = shift || 1;
 
  $self->{_fitness} = undef;
  bless $self, $class;
  $self->randomize();
  return $self;
}

=head2 size()

lib/Algorithm/Evolutionary/Individual/Vector.pm  view on Meta::CPAN

  my $self = { _array => \@_,
               _length => scalar( @_ ),
               _fitness => undef };
  bless $self, $class;
  return $self;
}

=head2 set( $ref_to_hash )

Sets values of an individual; takes a hash as input. The array is
initialized to a null array, and the start and end range are
initialized by default to 0 and 1

=cut

sub set {
  my $self = shift; 
  my $hash = shift || croak "No params here";
  for ( keys %{$hash} ) {
    $self->{"_$_"} = $hash->{$_};
  }
  $self->{_array} = shift || ();
  $self->{_rangestart} =  $self->{_rangestart} || 0;
  $self->{_rangeend} =  $self->{_rangeend} || 1;
  $self->{_fitness} = undef;
}

=head2 randomize()

Assigns random values to the elements

=cut

sub randomize {
  my $self = shift; 
  my $range = $self->{_rangeend} - $self->{_rangestart};
  for ( my $i = 0; $i < $self->{_length}; $i++  ) {
    push @{$self->{_array}}, rand( $range ) + $self->{_rangestart};
  }
}

=head2 Atom

Gets or sets the value of an atom

=cut

sub Atom{

lib/Algorithm/Evolutionary/Op/GaussianMutation.pm  view on Meta::CPAN

  my $self = shift;
  my $arg = shift || croak "No victim here!";
  croak "Incorrect type".(ref $arg) if !$arg->{_array};
  my $victim = clone($arg);
  my @deltas = random_normal( @{$victim->{_array}} + 1,  #+1 is needed, returns empty if not
			      $self->{_avg}, $self->{_stddev} );
  for ( @{$victim->{_array}} ) {
      my $adjust = pop @deltas;
      $_ += $adjust;
      # makes sure that the new value stays within its confines
      if($_ < $victim->{_rangestart}) {
	  $_ = $victim->{_rangestart};
      } elsif($_ > $victim->{_rangeend}) {
	  $_ = $victim->{_rangeend};
      }
  }
  $victim->{_fitness} = undef;
  return $victim;
}

=head1 THANKS

lib/Algorithm/Evolutionary/Run.pm  view on Meta::CPAN

#----------------------------------------------------------#
  bless $self, $class;
  $self->reset_population;
  for ( @{$self->{'_population'}} ) {
    if ( !defined $_->Fitness() ) {
      $_->evaluate( $fitness_object );
    }
  }

  $self->{'_generation'} = $generation;
  $self->{'_start_time'} = $inicioTiempo;
  return $self;
}

=head2 population_size( $new_size )

Resets the population size to the C<$new_size>. It does not do
anything to the actual population, just resests the number. You should
do a C<reset_population> afterwards.

=cut

lib/Algorithm/Evolutionary/Run.pm  view on Meta::CPAN


=cut

sub results {
  my $self = shift;
  my $population_size = scalar @{$self->{'_population'}};
  my $last_good_pos = $population_size*(1-$self->{'selection_rate'});
  my $results = { best => $self->{'_population'}->[0],
		  median => $self->{'_population'}->[ $population_size / 2],
		  last_good => $self->{'_population'}->[ $last_good_pos ],
		  time =>  tv_interval( $self->{'_start_time'} ),
		  evaluations => $self->{'_fitness'}->evaluations() };
  return $results;

}

=head2 evaluated_population()

Returns the portion of population that has been evaluated (all but the new ones)

=cut 

scripts/canonical-genetic-algorithm.pl  view on Meta::CPAN


=head1 SYNOPSIS

  prompt% ./canonical-genetic-algorithm.pl <bits> <block size> <population> <number of generations> <selection rate>


=head1 DESCRIPTION  

A canonical GA uses mutation, crossover, binary representation, and
    roulette wheel selection. Here mainly for reference, and so that
    you can peruse to start your own programs.

In this case, we are optimizing the Royal Road function,
L<http://web.cecs.pdx.edu/~mm/handbook-of-ec-rr.pdf>. By default,
these values are used:

=over

=item * 

I<number of bits>: 64 (this is the chromosome length)

scripts/rectangle-coverage.pl  view on Meta::CPAN


=head1 DESCRIPTION  

A demo that combines the L<Algorithm::Evolutionary::Op::Easy> module
    with L<Tk> to create a visual demo of the evolutionary
    algorithm. It generates randomly a number of rectangles, and shows
    how the population evolves to find the solution. The best point is
    shown in darkening yellow color, the rest of the population in
    green. 

Use "Start" to start the algorithm after setting the variables, and
    then Finish to stop the EA, Exit to close the window.

Default values are as follows

=over

=item * 

I<number of rectangles>: 300

scripts/rectangle-coverage.pl  view on Meta::CPAN

		   -bd => 2)->pack(-side => 'top',
				   -fill => 'x');

for my $v ( qw( num_rects arena_side bits pop_size number_of_generations selection_rate ) ){
  create_and_pack( $f, $v );
}

my $canvas = $mw->Canvas( -cursor=>"crosshair", -background=>"white",
              -width=>$width, -height=>$height )->pack;
$mw->Button( -text    => 'Start',
	     -command => \&start,
	   )->pack( -side => 'left',
		    -expand => 1);
$mw->Button( -text    => 'End',
	       -command => \&finished,
	     )->pack( -side => 'left',
		      -expand => 1 );
$mw->Button( -text    => 'Exit',
	     -command => sub { exit(0);},
	   )->pack( -side => 'left',
		    -expand => 1 );

scripts/rectangle-coverage.pl  view on Meta::CPAN


sub create_and_pack {
  my $frame = shift;
  my $var = shift;
  my $f = $frame->Frame();
  my $label = $f->Label(-text => $var )->pack(-side => 'left');
  my $entry = $f->Entry( -textvariable => eval '\$'.$var )->pack(-side => 'right' );
  $f->pack();
}

sub start {
  #Generate random rectangles
  for my $i (0 .. $num_rects) {
    
    my $x_0 = rand( $arena_side );
    my $y_0 = rand( $arena_side);
    my $side_x = rand( $arena_side - $x_0 );
    my $side_y = rand($arena_side-$y_0);
    $alg->add_rectangle("rectangle_$i", $x_0, $y_0, 
			$x_0+$side_x, $x_0+$side_y );
    my $val = 255*$i/$num_rects;

t/0408-gaussian-mutation.t  view on Meta::CPAN

my $sm = new Algorithm::Evolutionary::Op::GaussianMutation $center, $sd;
isa_ok( $sm, 'Algorithm::Evolutionary::Op::GaussianMutation' );

my $result;
for ( 1..100 ) {
  $result = $sm->apply( $indi );
  for ( my $i = 0; $i < $indi->size(); $i ++ ) {
    isnt( $result->Atom($i), $indi->Atom($i), 
	$result->Atom($i)." differs from ". $indi->Atom($i));
    isnt( $result->Atom($i) > $indi->{'_rangeend'}, 1,  'Within upper bounds');
    isnt( $result->Atom($i) < $indi->{'_rangestart'}, 1,  'Within lower bounds');
  }
}

done_testing();

t/general.t  view on Meta::CPAN

print "BitString...\n";
my $bs = Algorithm::Evolutionary::Individual::BitString->new(100);
is( ref $bs, "Algorithm::Evolutionary::Individual::BitString", , "Good ref" );
is( ref Algorithm::Evolutionary::Individual::Base::create( 'BitString', { length => 10 }), "Algorithm::Evolutionary::Individual::BitString", "Good ref" );

#Vector - 5..7
print "Vector...\n";
is( ref Algorithm::Evolutionary::Individual::Vector->new(10), "Algorithm::Evolutionary::Individual::Vector", "Good ref" );
is( ref Algorithm::Evolutionary::Individual::Base::create( 'Vector', 
							   { length => 20,
							     rangestart => -5,
							     rangeend => 5 }), 
    "Algorithm::Evolutionary::Individual::Vector", "Good ref" );

my $primitives = { sum => [2, -1, 1],
		   multiply => [2, -1, 1],
		   substract => [2, -1, 1],
		   divide => [2, -1, 1],
		   x => [0, -10, 10],
		   y => [0, -10, 10] };



( run in 0.454 second using v1.01-cache-2.11-cpan-0d8aa00de5b )