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   5 use strict;
  1         2  
  1         31  
2 1     1   6 use warnings;
  1         2  
  1         48  
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   4 use lib qw(../../..);
  1         2  
  1         5  
62              
63             our ($VERSION) = ( '$Revision: 3.0 $ ' =~ / (\d+\.\d+)/ ) ;
64              
65 1     1   164 use Carp;
  1         2  
  1         65  
66              
67 1     1   7 use base 'Algorithm::Evolutionary::Op::Base';
  1         1  
  1         130  
68              
69             use Algorithm::Evolutionary qw(Wheel Op::Replace_Worst);
70              
71             # Class-wide constants
72             our $APPLIESTO = 'ARRAY';
73             our $ARITY = 1;
74              
75             =head2 new( $evaluation_function, $selector, $ref_to_operator_array, $replacement_operator )
76              
77             Creates an algorithm, with no defaults except for the default
78             replacement operator (defaults to L)
79              
80             =cut
81              
82             sub new {
83             my $class = shift;
84             my $self = {};
85             $self->{_eval} = shift || croak "No eval function found";
86             $self->{_selector} = shift || croak "No selector found";
87             $self->{_ops} = shift || croak "No operators found";
88             $self->{_replacementRate} = shift || 1; #Default to all replaced
89             $self->{_replacement_op} = shift || new Algorithm::Evolutionary::Op::Replace_Worst;
90             bless $self, $class;
91             return $self;
92             }
93              
94              
95             =head2 set( $ref_to_params_hash, $ref_to_code_hash, $ref_to_operators_hash )
96              
97             Sets the instance variables. Takes a ref-to-hash as
98             input. Not intended to be used from outside the class
99              
100             =cut
101              
102             sub set {
103             my $self = shift;
104             my $hashref = shift || croak "No params here";
105             my $codehash = shift || croak "No code here";
106             my $opshash = shift || croak "No ops here";
107              
108             for ( keys %$codehash ) {
109             $self->{"_$_"} = eval "sub { $codehash->{$_} } ";
110             }
111              
112             $self->{_ops} =();
113             for ( keys %$opshash ) {
114             push @{$self->{_ops}},
115             Algorithm::Evolutionary::Op::Base::fromXML( $_, $opshash->{$_}->[1], $opshash->{$_}->[0] ) ;
116             }
117             }
118              
119             =head2 apply( $population )
120              
121             Applies the algorithm to the population, which should have
122             been evaluated first; checks that it receives a
123             ref-to-array as input, croaks if it does not. Returns a sorted,
124             culled, evaluated population for next generation.
125              
126             =cut
127              
128             sub apply ($) {
129             my $self = shift;
130             my $pop = shift || croak "No population here";
131             croak "Incorrect type ".(ref $pop) if ref( $pop ) ne $APPLIESTO;
132              
133             #Evaluate only the new ones
134             my $eval = $self->{_eval};
135             my @ops = @{$self->{_ops}};
136              
137             #Breed
138             my $selector = $self->{_selector};
139             my @genitors = $selector->apply( @$pop );
140              
141             #Reproduce
142             my $totRate = 0;
143             my @rates;
144             for ( @ops ) {
145             push( @rates, $_->{rate});
146             }
147             my $opWheel = new Algorithm::Evolutionary::Wheel @rates;
148              
149             my @newpop;
150             my $pringaos = @$pop * $self->{_replacementRate} ;
151             for ( my $i = 0; $i < $pringaos; $i++ ) {
152             my @offspring;
153             my $selectedOp = $ops[ $opWheel->spin()];
154             # print $selectedOp->asXML;
155             for ( my $j = 0; $j < $selectedOp->arity(); $j ++ ) {
156             my $chosen = $genitors[ rand( @genitors )];
157             # print "Elegido ", $chosen->asString(), "\n";
158             push( @offspring, $chosen->clone() );
159             }
160             my $mutante = $selectedOp->apply( @offspring );
161             push( @newpop, $mutante );
162             }
163            
164             #Eliminate and substitute
165             map( $_->evaluate( $eval), @newpop );
166             my $pop_hash = $self->{'_replacement_op'}->apply( $pop, \@newpop );
167             @$pop = sort { $b->{_fitness} <=> $a->{_fitness}; } @$pop_hash ;
168            
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: 2009/07/24 08:46:59 $
189             $Header: /cvsroot/opeal/Algorithm-Evolutionary/lib/Algorithm/Evolutionary/Op/Generation_Skeleton.pm,v 3.0 2009/07/24 08:46:59 jmerelo Exp $
190             $Author: jmerelo $
191             $Revision: 3.0 $
192              
193             =cut
194              
195             "The truth is out there";