File Coverage

lib/Algorithm/Evolutionary/Individual/Bit_Vector.pm
Criterion Covered Total %
statement 21 21 100.0
branch n/a
condition n/a
subroutine 7 7 100.0
pod n/a
total 28 28 100.0


line stmt bran cond sub pod time code
1 1     1   28238 use strict; #-*-cperl-*-
  1         3  
  1         243  
2 1     1   6 use warnings;
  1         2  
  1         31  
3              
4 1     1   6 use lib qw(../../../../lib);
  1         2  
  1         5  
5              
6             =head1 NAME
7              
8             Algorithm::Evolutionary::Individual::Bit_Vector - Classic bitstring individual for evolutionary computation;
9             usually called chromosome, and using a different implementation from Algorithm::Evolutionary::Individual::BitString
10              
11              
12             =head1 SYNOPSIS
13              
14             use Algorithm::Evolutionary::Individual::BitVector;
15              
16             my $indi = new Algorithm::Evolutionary::Individual::Bit_Vector 10 ; # Build random bitstring with length 10
17             # Each element in the range 0 .. 1
18              
19             my $indi3 = new Algorithm::Evolutionary::Individual::Bit_Vector;
20             $indi3->set( { length => 20 } ); #Sets values, but does not build the string
21            
22             $indi3->randomize(); #Creates a random bitstring with length as above
23            
24             print $indi3->Atom( 7 ); #Returns the value of the 7th character
25             $indi3->Atom( 3 ) = 1; #Sets the value
26              
27             $indi3->addAtom( 1 ); #Adds a new character to the bitstring at the end
28              
29             my $indi4 = Algorithm::Evolutionary::Individual::Bit_Vector->fromString( '10110101'); #Creates an individual from that string
30              
31             my $indi5 = $indi4->clone(); #Creates a copy of the individual
32              
33             my @array = qw( 0 1 0 1 0 0 1 ); #Create a tied array
34             tie my @vector, 'Algorithm::Evolutionary::Individual::Bit_Vector', @array;
35             print tied( @vector )->asXML();
36              
37             print $indi3->asString(); #Prints the individual
38             print $indi3->asXML() #Prints it as XML. See L
39             print $indi3->as_yaml() #Change of convention, I know...
40              
41             =head1 Base Class
42              
43             L
44              
45             =head1 DESCRIPTION
46              
47             Bitstring Individual for a Genetic Algorithm. Used, for instance, in a canonical GA
48              
49             =cut
50              
51             package Algorithm::Evolutionary::Individual::Bit_Vector;
52              
53 1     1   201 use Carp;
  1         2  
  1         109  
54 1     1   908 use Bit::Vector;
  1         1892  
  1         57  
55 1     1   934 use String::Random; # For initial string generation
  1         3909  
  1         91  
56              
57             our ($VERSION) = ( '$Revision: 3.1 $ ' =~ / (\d+\.\d+)/ );
58              
59 1     1   10 use base 'Algorithm::Evolutionary::Individual::Base';
  1         2  
  1         640  
60              
61             use constant MY_OPERATORS => ( qw(Algorithm::Evolutionary::Op::BitFlip Algorithm::Evolutionary::Op::Mutation ));
62            
63              
64             =head1 METHODS
65              
66             =head2 new( $arg )
67              
68             Creates a new bitstring individual. C<$arg> can be either { length =>
69             $length} or { string => [binary string] }. With no argument, a
70             length of 16 is given by default.
71              
72             =cut
73              
74             sub new {
75             my $class = shift;
76             my $self = Algorithm::Evolutionary::Individual::Base::new( $class );
77             my $arg = shift || { length => 16};
78             if ( $arg =~ /^\d+$/ ) { #It's a number
79             $self->{'_bit_vector'} = _create_bit_vector( $arg );
80             } elsif ( $arg->{'length'} ) {
81             $self->{'_bit_vector'} = _create_bit_vector( $arg->{'length'} );
82             } elsif ( $arg->{'string'} ) {
83             $self->{'_bit_vector'} =
84             Bit::Vector->new_Bin( length($arg->{'string'}), $arg->{'string'} );
85             }
86             croak "Incorrect creation options" if !$self->{'_bit_vector'};
87             return $self;
88             }
89              
90             sub _create_bit_vector {
91             my $length = shift || croak "No length!";
92             my $rander = new String::Random;
93             my $hex_string = $rander->randregex("[0-9A-F]{".int($length/4)."}");
94             return Bit::Vector->new_Hex( $length, $hex_string );
95             }
96              
97             sub TIEARRAY {
98             my $class = shift;
99             my $self = { _bit_vector => Bit::Vector->new_Bin(scalar( @_), join("",@_)) };
100             bless $self, $class;
101             return $self;
102             }
103              
104             =head2 Atom
105              
106             Sets or gets the value of the n-th character in the string. Counting
107             starts at 0, as usual in Perl arrays.
108              
109             =cut
110              
111             sub Atom: lvalue {
112             my $self = shift;
113             my $index = shift;
114             my $last_index = $self->{'_bit_vector'}->Size()-1;
115             if ( @_ ) {
116             $self->{'_bit_vector'}->Bit_Copy($last_index-$index, shift );
117             } else {
118             $self->{'_bit_vector'}->bit_test($last_index - $index);
119             }
120             }
121              
122             =head2 size()
123              
124             Returns size in bits
125              
126             =cut
127              
128             sub size {
129             my $self = shift;
130             return $self->{'_bit_vector'}->Size();
131             }
132              
133             =head2 clone()
134              
135             Clones using native methods. Does not work with general Clone::Fast, since it's implemented as an XS
136              
137             =cut
138              
139             sub clone {
140             my $self = shift;
141             my $clone = Algorithm::Evolutionary::Individual::Base::new( ref $self );
142             $clone->{'_bit_vector'} = $self->{'_bit_vector'}->Clone();
143             return $clone;
144             }
145              
146             =head2 as_string()
147              
148             Overrides the default; prints the binary chromosome
149              
150             =cut
151              
152             sub as_string {
153             my $self = shift;
154             return $self->{'_bit_vector'}->to_Bin();
155             }
156              
157             =head2 Chrom()
158              
159             Returns the internal bit_vector
160              
161             =cut
162              
163             sub Chrom {
164             my $self = shift;
165             return $self->{'_bit_vector'};
166             }
167              
168             =head2 TIE methods
169              
170             String implements FETCH, STORE, PUSH and the rest, so an String
171             can be tied to an array and used as such.
172              
173             =cut
174              
175             sub FETCH {
176             my $self = shift;
177             my $bit_vector = $self->{'_bit_vector'};
178             return $bit_vector->bit_test( $bit_vector->Size() - 1 - shift );
179             }
180              
181             sub STORE {
182             my $self = shift;
183             my $bit_vector = $self->{'_bit_vector'};
184             my $index = shift;
185             $self->{'_bit_vector'}->Bit_Copy($bit_vector->Size()- 1 -$index, shift );
186             }
187              
188             sub PUSH {
189             my $self = shift;
190             my $new_vector = Bit::Vector->new_Bin(scalar(@_), join("",@_));
191             $self->{'_bit_vector'} = $self->{'_bit_vector'}->Concat( $new_vector );
192             }
193              
194             sub UNSHIFT {
195             my $self = shift;
196             my $new_vector = Bit::Vector->new_Bin(scalar(@_), join("",@_));
197             $self->{'_bit_vector'} = Bit::Vector->Concat_List( $new_vector, $self->{'_bit_vector'}) ;
198             }
199              
200             sub POP {
201             my $self = shift;
202             my $bit_vector = $self->{'_bit_vector'};
203             my $length = $bit_vector->Size();
204             my $pop = $bit_vector->lsb();
205             $self->{'_bit_vector'}->Delete(0,1);
206             $self->{'_bit_vector'}->Resize($length-1);
207             return $pop;
208             }
209              
210             sub SHIFT {
211             my $self = shift;
212             my $length = $self->{'_bit_vector'}->Size();
213             my $bit = $self->{'_bit_vector'}->shift_left('0');
214             $self->{'_bit_vector'}->Reverse( $self->{'_bit_vector'});
215             $self->{'_bit_vector'}->Resize($length-1);
216             $self->{'_bit_vector'}->Reverse( $self->{'_bit_vector'});
217              
218             return $bit;
219             }
220              
221             sub SPLICE {
222             my $self = shift;
223             my $offset = shift;
224             my $bits = shift;
225             my $new_vector;
226             my $slice = Bit::Vector->new($bits);
227             my $size = $self->{'_bit_vector'}->Size();
228             $slice->Interval_Copy( $self->{'_bit_vector'}, 0, $size-$offset-$bits, $bits );
229             if ( @_ ) {
230             $new_vector = Bit::Vector->new_Bin(scalar(@_), join("",@_));
231             $self->{'_bit_vector'}->Interval_Substitute( $new_vector,
232             $size-$offset-$bits, 0 , 0,
233             $new_vector->Size() );
234             } else {
235             $self->{'_bit_vector'}->Interval_Substitute( Bit::Vector->new(0), $size-$offset-$bits, $bits,
236             0, 0 );
237             }
238             return split(//,$slice->to_Bin());
239              
240             }
241              
242             sub FETCHSIZE {
243             my $self = shift;
244             return length( $self->{'_bit_vector'}->Size() );
245             }
246              
247              
248             =head2 Copyright
249            
250             This file is released under the GPL. See the LICENSE file included in this distribution,
251             or go to http://www.fsf.org/licenses/gpl.txt
252              
253             CVS Info: $Date: 2010/12/19 21:39:12 $
254             $Header: /media/Backup/Repos/opeal/opeal/Algorithm-Evolutionary/lib/Algorithm/Evolutionary/Individual/Bit_Vector.pm,v 3.1 2010/12/19 21:39:12 jmerelo Exp $
255             $Author: jmerelo $
256             $Revision: 3.1 $
257             $Name $
258              
259             =cut