File Coverage

lib/Algorithm/Evolutionary/Individual/Bit_Vector.pm
Criterion Covered Total %
statement 89 98 90.8
branch 9 12 75.0
condition 2 5 40.0
subroutine 21 24 87.5
pod 6 6 100.0
total 127 145 87.5


line stmt bran cond sub pod time code
1 2     2   33592 use strict; #-*-cperl-*-
  2         4  
  2         72  
2 2     2   11 use warnings;
  2         2  
  2         74  
3              
4 2     2   11 use lib qw(../../../../lib);
  2         3  
  2         14  
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 2     2   258 use Carp;
  2         2  
  2         136  
54 2     2   942 use Bit::Vector;
  2         3540  
  2         89  
55 2     2   1006 use String::Random; # For initial string generation
  2         5164  
  2         160  
56              
57             our ($VERSION) = ( '$Revision: 3.1 $ ' =~ / (\d+\.\d+)/ );
58              
59 2     2   13 use base 'Algorithm::Evolutionary::Individual::Base';
  2         3  
  2         489  
60              
61 2     2   9 use constant MY_OPERATORS => ( qw(Algorithm::Evolutionary::Op::BitFlip Algorithm::Evolutionary::Op::Mutation ));
  2         2  
  2         1886  
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 3     3 1 22 my $class = shift;
76 3         13 my $self = Algorithm::Evolutionary::Individual::Base::new( $class );
77 3   50     8 my $arg = shift || { length => 16};
78 3 50       40 if ( $arg =~ /^\d+$/ ) { #It's a number
    100          
    50          
79 0         0 $self->{'_bit_vector'} = _create_bit_vector( $arg );
80             } elsif ( $arg->{'length'} ) {
81 2         7 $self->{'_bit_vector'} = _create_bit_vector( $arg->{'length'} );
82             } elsif ( $arg->{'string'} ) {
83 1         8 $self->{'_bit_vector'} =
84             Bit::Vector->new_Bin( length($arg->{'string'}), $arg->{'string'} );
85             }
86 3 50       22 croak "Incorrect creation options" if !$self->{'_bit_vector'};
87 3         9 return $self;
88             }
89              
90             sub _create_bit_vector {
91 2   33 2   5 my $length = shift || croak "No length!";
92 2         11 my $rander = new String::Random;
93 2         47 my $hex_string = $rander->randregex("[0-9A-F]{".int($length/4)."}");
94 2         331 return Bit::Vector->new_Hex( $length, $hex_string );
95             }
96              
97             sub TIEARRAY {
98 1     1   10 my $class = shift;
99 1         7 my $self = { _bit_vector => Bit::Vector->new_Bin(scalar( @_), join("",@_)) };
100 1         2 bless $self, $class;
101 1         3 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 20     20 1 53 my $self = shift;
113 20         23 my $index = shift;
114 20         42 my $last_index = $self->{'_bit_vector'}->Size()-1;
115 20 100       32 if ( @_ ) {
116 1         6 $self->{'_bit_vector'}->Bit_Copy($last_index-$index, shift );
117             } else {
118 19         131 $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 19     19 1 8112 my $self = shift;
130 19         94 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 0     0 1 0 my $self = shift;
141 0         0 my $clone = Algorithm::Evolutionary::Individual::Base::new( ref $self );
142 0         0 $clone->{'_bit_vector'} = $self->{'_bit_vector'}->Clone();
143 0         0 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 11     11 1 34 my $self = shift;
154 11         71 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 0     0 1 0 my $self = shift;
165 0         0 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 2     2   25 my $self = shift;
177 2         5 my $bit_vector = $self->{'_bit_vector'};
178 2         13 return $bit_vector->bit_test( $bit_vector->Size() - 1 - shift );
179             }
180              
181             sub STORE {
182 1     1   3 my $self = shift;
183 1         2 my $bit_vector = $self->{'_bit_vector'};
184 1         2 my $index = shift;
185 1         13 $self->{'_bit_vector'}->Bit_Copy($bit_vector->Size()- 1 -$index, shift );
186             }
187              
188             sub PUSH {
189 1     1   8 my $self = shift;
190 1         8 my $new_vector = Bit::Vector->new_Bin(scalar(@_), join("",@_));
191 1         13 $self->{'_bit_vector'} = $self->{'_bit_vector'}->Concat( $new_vector );
192             }
193              
194             sub UNSHIFT {
195 1     1   2 my $self = shift;
196 1         9 my $new_vector = Bit::Vector->new_Bin(scalar(@_), join("",@_));
197 1         16 $self->{'_bit_vector'} = Bit::Vector->Concat_List( $new_vector, $self->{'_bit_vector'}) ;
198             }
199              
200             sub POP {
201 1     1   2 my $self = shift;
202 1         2 my $bit_vector = $self->{'_bit_vector'};
203 1         3 my $length = $bit_vector->Size();
204 1         4 my $pop = $bit_vector->lsb();
205 1         12 $self->{'_bit_vector'}->Delete(0,1);
206 1         4 $self->{'_bit_vector'}->Resize($length-1);
207 1         3 return $pop;
208             }
209              
210             sub SHIFT {
211 1     1   2 my $self = shift;
212 1         5 my $length = $self->{'_bit_vector'}->Size();
213 1         5 my $bit = $self->{'_bit_vector'}->shift_left('0');
214 1         5 $self->{'_bit_vector'}->Reverse( $self->{'_bit_vector'});
215 1         3 $self->{'_bit_vector'}->Resize($length-1);
216 1         4 $self->{'_bit_vector'}->Reverse( $self->{'_bit_vector'});
217              
218 1         5 return $bit;
219             }
220              
221             sub SPLICE {
222 3     3   5 my $self = shift;
223 3         4 my $offset = shift;
224 3         3 my $bits = shift;
225 3         3 my $new_vector;
226 3         14 my $slice = Bit::Vector->new($bits);
227 3         11 my $size = $self->{'_bit_vector'}->Size();
228 3         20 $slice->Interval_Copy( $self->{'_bit_vector'}, 0, $size-$offset-$bits, $bits );
229 3 100       6 if ( @_ ) {
230 1         5 $new_vector = Bit::Vector->new_Bin(scalar(@_), join("",@_));
231 1         6 $self->{'_bit_vector'}->Interval_Substitute( $new_vector,
232             $size-$offset-$bits, 0 , 0,
233             $new_vector->Size() );
234             } else {
235 2         16 $self->{'_bit_vector'}->Interval_Substitute( Bit::Vector->new(0), $size-$offset-$bits, $bits,
236             0, 0 );
237             }
238 3         30 return split(//,$slice->to_Bin());
239              
240             }
241              
242             sub FETCHSIZE {
243 0     0     my $self = shift;
244 0           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