File Coverage

lib/Algorithm/Evolutionary/Experiment.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


line stmt bran cond sub pod time code
1 2     2   31496 use strict; #-*-CPerl-*- -*- hi-lock -*-
  2         6  
  2         82  
2 2     2   13 use warnings;
  2         3  
  2         86  
3              
4 2     2   12 use lib qw( ../../../lib );
  2         3  
  2         11  
5              
6             =head1 NAME
7              
8             Algorithm::Evolutionary::Experiment - Class for setting up an
9             experiment with algorithms and population
10              
11             =head1 SYNOPSIS
12            
13             use Algorithm::Evolutionary::Experiment;
14             my $popSize = 20;
15             my $indiType = 'BitString';
16             my $indiSize = 64;
17            
18             #Algorithm might be anything of type Op
19             my $ex = new Algorithm::Evolutionary::Experiment $popSize, $indiType, $indiSize, $algorithm;
20              
21              
22             =head1 DESCRIPTION
23              
24             This class contains (as instance variables) an algorithm and a population, and applies one to
25             the other. Can be serialized
26             using XML, and can read an XML description of the experiment.
27              
28             =head1 METHODS
29              
30             =cut
31              
32             package Algorithm::Evolutionary::Experiment;
33              
34 2     2   1422 use Algorithm::Evolutionary::Utils qw(parse_xml);
  0            
  0            
35             use Algorithm::Evolutionary qw(Individual::Base
36             Op::Base
37             Op::Creator );
38              
39             our $VERSION = sprintf "%d.%03d", q$Revision: 3.3 $ =~ /(\d+)\.(\d+)/g;
40              
41             use Carp;
42              
43             =head2 new( $pop_size, $type_of_individual, $individual_size )
44              
45             Creates a new experiment. An C has two parts: the
46             population and the algorithm. The population is created from a set
47             of parameters: popSize, indiType and indiSize, and an array of
48             algorithms that will be applied sequentially. Alternatively, if
49             only operators are passed as an argument, it is understood as an
50             array of algorithms (including, probably, initialization of the
51             population).
52              
53             =cut
54              
55             sub new ($$$$;$) {
56             my $class = shift;
57             my $self = { _pop => [] };
58             if ( index ( ref $_[0], 'Algorithm::Evolutionary') == -1 ) {
59             #If the first arg is not an algorithm, create one
60             my $popSize = shift || carp "Pop size = 0, can't create\n";
61             my $indiType = shift || carp "Empty individual class, can't create\n";
62             my $indiSize = shift || carp "Empty individual size, no reasonable default, can't create\n";
63             for ( my $i = 0; $i < $popSize; $i ++ ) {
64             my $indi = Algorithm::Evolutionary::Individual::Base::new( $indiType,
65             { length => $indiSize } );
66             $indi->randomize();
67             push @{$self->{_pop}}, $indi;
68             }
69             };
70             @_ || croak "Can't find an algorithm";
71             push @{$self->{_algo}}, @_;
72             bless $self, $class;
73             return $self
74            
75             }
76              
77             =head2 fromXML
78              
79             Creates a new experiment, same as before, but with an L specification. An
80             example of it follows:
81              
82            
83             xsi:noNamespaceSchemaLocation='ea-alpha.xsd'
84             version='0.2'>
85              
86            
87            
88            
89            
90            
91            
92            
93              
94            
95            
96            
97            
98            
99            
100            
101            
102            
103            
104            
105            
106            
107            
108            
109            
110            
111            
112              
113            
114            
115             This is an alternative constructor. Takes a well-formed string with the XML
116             spec, which should have been done according to EvoSpec 0.3, or the same
117             string processed with C, and returns a built experiment
118              
119             =cut
120              
121             sub fromXML ($;$) {
122             my $class = shift;
123             my $xml = shift || carp "XML fragment missing ";
124             if ( ref $xml eq '' ) { #We are receiving a string, parse it
125             $xml = parse_xml( $xml );
126             }
127              
128             my @pop;
129             my $self = { _pop => \@pop, #Just an empty reference
130             _xml => $xml }; # Create a reference
131             #Process operators
132             for ( @{ ref $xml->{'ea'}->{'initial'}->{'op'} eq 'ARRAY' ?
133             $xml->{'ea'}->{'initial'}->{'op'}:
134             [ $xml->{'ea'}->{'initial'}->{'op'}]} ) { #Should process the tag
135             push( @{$self->{'_algo'}},
136             Algorithm::Evolutionary::Op::Base::fromXML( $_->{'-name'},$_ ) );
137             }
138              
139             #Process population
140             if ( $xml->{'ea'}->{'initial'}->{'pop'} ) {
141             my $pop_hash = $xml->{'ea'}->{'initial'}->{'pop'};
142             my $size = $pop_hash->{'-size'};
143             my $type;
144             my %params;
145             for my $p ( @{$pop_hash->{'param'}} ) {
146             if ( $p->{'-name'} eq 'type' ) {
147             $type = $p->{'-value'};
148             } else {
149             $params{ $p->{'-name'} } = $p->{'-value'};
150             }
151             }
152             my $creator = new Algorithm::Evolutionary::Op::Creator $size, $type, \%params ;
153            
154             $creator->apply( \@pop );
155             push( @{$self->{_pop}}, @pop ) ;
156             }
157              
158             #Process population, if it exists
159             if ( $xml->{'ea'}->{'pop'} ) { #Process runtime population
160             for my $i ( @{$xml->{'ea'}->{'pop'}->{'indi'}} ) {
161             push( @{$self->{_pop}},
162             Algorithm::Evolutionary::Individual::Base::fromXML( $i->{'-type'}, $i ) );
163             }
164             }
165             #Bless and return
166             bless $self, $class;
167              
168             return $self;
169             }
170              
171              
172             =head2 go
173              
174             Applies the different operators in the order that they appear; returns the population
175             as a ref-to-array.
176              
177             =cut
178              
179             sub go {
180             my $self = shift;
181             for ( @{$self->{_algo}} ) {
182             $_->apply( $self->{_pop} );
183             }
184             return $self->{_pop}
185             }
186              
187             =head2 asXML
188            
189             Opposite of fromXML; serializes the object in XML. First the operators, and then
190             the population
191              
192             =cut
193              
194             sub asXML {
195             my $self = shift;
196             my $str=<<'EOC';
197            
198            
200            
201             EOC
202              
203             for ( @{$self->{_algo}} ) {
204             $str.= $_->asXML()."\n";
205             }
206            
207             $str .="\t\n\n";
208             for ( @{$self->{_pop}} ) {
209             $str .= $_->asXML()."\n";
210             }
211             $str .="\n\t\n\n";
212             return $str;
213             }
214              
215             =head2 SEE ALSO
216              
217             L , another option for setting up
218             experiments, which is the one you should rather use, as XML support is
219             going to be deprecated (some day).
220              
221             =head1 Copyright
222            
223             This file is released under the GPL. See the LICENSE file included in this distribution,
224             or go to http://www.fsf.org/licenses/gpl.txt
225              
226             CVS Info: $Date: 2012/07/11 06:14:51 $
227             $Header: /media/Backup/Repos/opeal/opeal/Algorithm-Evolutionary/lib/Algorithm/Evolutionary/Experiment.pm,v 3.3 2012/07/11 06:14:51 jmerelo Exp $
228             $Author: jmerelo $
229             $Revision: 3.3 $
230              
231             =cut
232              
233             "What???";