File Coverage

lib/Algorithm/MasterMind/Evolutionary_Base.pm
Criterion Covered Total %
statement 19 21 90.4
branch n/a
condition n/a
subroutine 7 7 100.0
pod n/a
total 26 28 92.8


line stmt bran cond sub pod time code
1             package Algorithm::MasterMind::Evolutionary_Base;
2              
3 8     8   48 use warnings;
  8         13  
  8         213  
4 8     8   37 use strict;
  8         14  
  8         196  
5 8     8   37 use Carp;
  8         12  
  8         480  
6              
7 8         42 use lib qw(../../lib
8             ../../../lib
9             ../../../../Algorithm-Evolutionary/lib/
10             ../../../Algorithm-Evolutionary/lib/
11             ../../Algorithm-Evolutionary/lib/
12 8     8   37 ../Algorithm-Evolutionary/lib/);
  8         13  
13              
14             our $VERSION = sprintf "%d.%03d", q$Revision: 1.13 $ =~ /(\d+)\.(\d+)/g;
15              
16 8     8   3470 use base 'Algorithm::MasterMind';
  8         12  
  8         805  
17              
18 8     8   41 use Algorithm::MasterMind qw(entropy);
  8         12  
  8         405  
19              
20 8     8   5638 use Algorithm::Evolutionary::Individual::String;
  0            
  0            
21              
22             # ---------------------------------------------------------------------------
23              
24             sub fitness_compress {
25             my $self = shift;
26             my $object = shift;
27             my $combination = $object->{'_str'};
28             my $matches = $self->matches( $combination );
29             $object->{'_matches'} = $matches->{'matches'};
30             my $fitness = 1;
31             my @rules = @{$self->{'_rules'}};
32             my $rules_string = $combination;
33             for ( my $r = 0; $r <= $#rules; $r++) {
34             $rules_string .= $rules[$r]->{'combination'};
35             $fitness += abs( $rules[$r]->{'blacks'}
36             - $matches->{'result'}->[$r]->{'blacks'} )
37             + abs( $rules[$r]->{'whites'} - $matches->{'result'}->[$r]->{'whites'} );
38             }
39            
40             return entropy($rules_string)/$fitness;
41             }
42              
43             sub fitness_orig {
44             my $self = shift;
45             my $object = shift;
46             my $combination = $object->{'_str'};
47             my $matches = $self->matches( $combination );
48             $object->{'_matches'} = $matches->{'matches'};
49              
50             my $fitness = 1;
51             my @rules = @{$self->{'_rules'}};
52             for ( my $r = 0; $r <= $#rules; $r++) {
53             $fitness += abs( $rules[$r]->{'blacks'} - $matches->{'result'}->[$r]->{'blacks'} ) +
54             abs( $rules[$r]->{'whites'} - $matches->{'result'}->[$r]->{'whites'} );
55             }
56             return 1/$fitness;
57             }
58              
59             sub issue_first {
60             my $self = shift;
61             #Initialize population for next step
62             $self->reset();
63             $self->{'_first'} = 1; # flag for first
64             return $self->{'_last'} = $self->issue_first_Knuth();
65             }
66              
67             sub reset {
68             my $self=shift;
69             my %pop;
70             if ( scalar( (@{$self->{'_alphabet'}})** $self->{'_length'} ) < $self->{'_pop_size'} ) {
71             croak( "Can't do, population bigger than space" );
72             }
73             while ( scalar ( keys %pop ) < $self->{'_pop_size'} ) {
74             my $indi = Algorithm::Evolutionary::Individual::String->new( $self->{'_alphabet'}, $self->{'_length'} );
75             $pop{ $indi->{'_str'}} = $indi;
76             }
77             my @pop = values %pop;
78             $self->{'_pop'}= \@pop;
79             }
80              
81             sub reset_old {
82             my $self=shift;
83             my @pop;
84             for ( 0.. ($self->{'_pop_size'}-1) ) {
85             my $indi = Algorithm::Evolutionary::Individual::String->new( $self->{'_alphabet'},
86             $self->{'_length'} );
87             push( @pop, $indi );
88             }
89             $self->{'_pop'}= \@pop;
90             }
91              
92             sub realphabet {
93             my $self = shift;
94             my $alphabet = $self->{'_alphabet'};
95             my $pop = $self->{'_pop'};
96            
97             my %alphabet_hash;
98             map ( $alphabet_hash{$_} = 1, @$alphabet );
99              
100             for my $p ( @$pop ) {
101             for ( my $i = 0; $i < length( $p->{'_str'} ); $i++ ) {
102             if ( !$alphabet_hash{substr($p->{'_str'},$i,1)} ) {
103             substr($p->{'_str'},$i,1, $alphabet->[rand( @$alphabet )]);
104             }
105             }
106             $p->{'_chars'} = $alphabet;
107             }
108             }
109              
110             sub shrink_to {
111             my $self = shift;
112             my $new_size = shift || croak "Need a new size" ;
113              
114             do {
115             splice( @{$self->{'_pop'}}, rand( @{$self->{'_pop'}} ), 1 )
116             } until (@{$self->{'_pop'}} < $new_size );
117             }
118              
119             # sub distance {
120             # my $self = shift;
121             # my $evo_comb = shift || croak "Need somebody to love\n";
122              
123             # my @rules = @{$self->{'_rules'}};
124             # my $matches = 0;
125             # my $distance = 0;
126             # # print "Checking $string, ", $self->{'_evaluated'}, "\n";
127             # my $string = $evo_comb->{'_str'};
128             # for my $r ( @rules ) {
129             # my $rule_result;
130             # if ( !$evo_comb->{'_results'}->{$r->{'combination'}} ) {
131             # $rule_result = check_rule( $r, $string );
132             # $evo_comb->{'_results'}->{$r->{'combination'}} = $rule_result;
133             # } else {
134             # $rule_result = $evo_comb->{'_results'}->{$r->{'combination'}};
135             # }
136             # $matches++ if ( $rule_result->{'match'} );
137             # $distance -= abs( $r->{'blacks'} - $rule_result->{'blacks'} ) +
138             # abs( $r->{'whites'} - $rule_result->{'whites'} );
139             # }
140              
141             # return [$distance, $matches];
142            
143             # }
144             "some blacks, 0 white"; # Magic true value required at end of module
145              
146             __END__