File Coverage

lib/Algorithm/Evolutionary/Op/Generation_Skeleton.pm
Criterion Covered Total %
statement 15 15 100.0
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 20 20 100.0


line stmt bran cond sub pod time code
1 1     1   6 use strict;
  1         2  
  1         35  
2 1     1   5 use warnings;
  1         3  
  1         51  
3              
4             =head1 NAME
5              
6             Algorithm::Evolutionary::Op::Generation_Skeleton - Even more customizable single generation for an evolutionary algorithm.
7            
8             =head1 SYNOPSIS
9              
10             use Algorithm::Evolutionary qw( Individual::BitString
11             Op::Mutation Op::Crossover
12             Op::RouletteWheel
13             Fitness::ONEMAX Op::Generation_Skeleton
14             Op::Replace_Worst);
15              
16             use Algorithm::Evolutionary::Utils qw(average);
17              
18             my $onemax = new Algorithm::Evolutionary::Fitness::ONEMAX;
19              
20             my @pop;
21             my $number_of_bits = 20;
22             my $population_size = 20;
23             my $replacement_rate = 0.5;
24             for ( 1..$population_size ) {
25             my $indi = new Algorithm::Evolutionary::Individual::BitString $number_of_bits ; #Creates random individual
26             $indi->evaluate( $onemax );
27             push( @pop, $indi );
28             }
29              
30             my $m = new Algorithm::Evolutionary::Op::Mutation 0.5;
31             my $c = new Algorithm::Evolutionary::Op::Crossover; #Classical 2-point crossover
32              
33             my $selector = new Algorithm::Evolutionary::Op::RouletteWheel $population_size; #One of the possible selectors
34              
35             my $generation =
36             new Algorithm::Evolutionary::Op::Generation_Skeleton( $onemax, $selector, [$m, $c], $replacement_rate );
37              
38             my @sortPop = sort { $b->Fitness() <=> $a->Fitness() } @pop;
39             my $bestIndi = $sortPop[0];
40             my $previous_average = average( \@sortPop );
41             $generation->apply( \@sortPop );
42              
43             =head1 Base Class
44              
45             L
46              
47             =head1 DESCRIPTION
48              
49             Skeleton class for a general single-generation (or single step) in an
50             evolutionary algorithm; its instantiation requires a
51             L function, a
52             L, a reference to an
53             array of operators and a replacement operator
54              
55             =head1 METHODS
56              
57             =cut
58              
59             package Algorithm::Evolutionary::Op::Generation_Skeleton;
60              
61 1     1   5 use lib qw(../../..);
  1         2  
  1         6  
62              
63             our ($VERSION) = ( '$Revision: 3.3 $ ' =~ / (\d+\.\d+)/ ) ;
64              
65 1     1   180 use Carp;
  1         2  
  1         62  
66              
67 1     1   5 use base 'Algorithm::Evolutionary::Op::Base';
  1         7  
  1         130  
68              
69             use Algorithm::Evolutionary qw(Wheel Op::Replace_Worst);
70             use Sort::Key qw( rnkeysort);
71              
72             # Class-wide constants
73             our $APPLIESTO = 'ARRAY';
74             our $ARITY = 1;
75              
76             =head2 new( $evaluation_function, $selector, $ref_to_operator_array, $replacement_operator )
77              
78             Creates an algorithm, with no defaults except for the default
79             replacement operator (defaults to L)
80              
81             =cut
82              
83             sub new {
84             my $class = shift;
85             my $self = {};
86             $self->{_eval} = shift || croak "No eval function found";
87             $self->{_selector} = shift || croak "No selector found";
88             $self->{_ops} = shift || croak "No operators found";
89             $self->{_replacementRate} = shift || 1; #Default to all replaced
90             $self->{_replacement_op} = shift || new Algorithm::Evolutionary::Op::Replace_Worst;
91             bless $self, $class;
92             return $self;
93             }
94              
95              
96             =head2 set( $ref_to_params_hash, $ref_to_code_hash, $ref_to_operators_hash )
97              
98             Sets the instance variables. Takes a ref-to-hash as
99             input. Not intended to be used from outside the class
100              
101             =cut
102              
103             sub set {
104             my $self = shift;
105             my $hashref = shift || croak "No params here";
106             my $codehash = shift || croak "No code here";
107             my $opshash = shift || croak "No ops here";
108              
109             for ( keys %$codehash ) {
110             $self->{"_$_"} = eval "sub { $codehash->{$_} } ";
111             }
112              
113             $self->{_ops} =();
114             for ( keys %$opshash ) {
115             push @{$self->{_ops}},
116             Algorithm::Evolutionary::Op::Base::fromXML( $_, $opshash->{$_}->[1], $opshash->{$_}->[0] ) ;
117             }
118             }
119              
120             =head2 apply( $population )
121              
122             Applies the algorithm to the population, which should have
123             been evaluated first; checks that it receives a
124             ref-to-array as input, croaks if it does not. Returns a sorted,
125             culled, evaluated population for next generation.
126              
127             =cut
128              
129             sub apply ($) {
130             my $self = shift;
131             my $pop = shift || croak "No population here";
132             croak "Incorrect type ".(ref $pop) if ref( $pop ) ne $APPLIESTO;
133              
134             #Evaluate only the new ones
135             my $eval = $self->{'_eval'};
136             my @ops = @{$self->{'_ops'}};
137              
138             #Breed
139             my $selector = $self->{'_selector'};
140             my @genitors = $selector->apply( @$pop );
141              
142             #Reproduce
143             my $totRate = 0;
144             my @rates;
145             for ( @ops ) {
146             push( @rates, $_->{'rate'});
147             }
148             my $opWheel = new Algorithm::Evolutionary::Wheel @rates;
149              
150             my @newpop;
151             my $pringaos = @$pop * $self->{'_replacementRate'} ;
152             for ( my $i = 0; $i < $pringaos; $i++ ) {
153             my @offspring;
154             my $selectedOp = $ops[ $opWheel->spin()];
155             # print $selectedOp->asXML;
156             for ( my $j = 0; $j < $selectedOp->arity(); $j ++ ) {
157             my $chosen = $genitors[ rand( @genitors )];
158             # print "Elegido ", $chosen->asString(), "\n";
159             push( @offspring, $chosen->clone() );
160             }
161             my $mutante = $selectedOp->apply( @offspring );
162             push( @newpop, $mutante );
163             }
164            
165             #Eliminate and substitute
166             map( $_->evaluate( $eval), @newpop );
167             my $pop_hash = $self->{'_replacement_op'}->apply( $pop, \@newpop );
168             @$pop = rnkeysort { $_->{'_fitness'} } @$pop_hash ;
169             }
170              
171             =head1 SEE ALSO
172              
173             More or less in the same ballpark, alternatives to this one
174              
175             =over 4
176              
177             =item *
178              
179             L
180              
181             =back
182              
183             =head1 Copyright
184            
185             This file is released under the GPL. See the LICENSE file included in this distribution,
186             or go to http://www.fsf.org/licenses/gpl.txt
187              
188             CVS Info: $Date: 2013/01/05 12:43:32 $
189             $Header: /media/Backup/Repos/opeal/opeal/Algorithm-Evolutionary/lib/Algorithm/Evolutionary/Op/Generation_Skeleton.pm,v 3.3 2013/01/05 12:43:32 jmerelo Exp $
190             $Author: jmerelo $
191             $Revision: 3.3 $
192              
193             =cut
194              
195             "The truth is out there";