File Coverage

lib/Algorithm/Evolutionary/Op/Uniform_Crossover_Diff.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   26766 use strict;
  1         2  
  1         35  
2 1     1   5 use warnings;
  1         2  
  1         63  
3              
4             =head1 NAME
5              
6             Algorithm::Evolutionary::Op::Uniform_Crossover_Diff - Uniform crossover, but interchanges only those atoms that are different
7              
8            
9              
10             =head1 SYNOPSIS
11              
12             my $xmlStr3=<
13            
14             #Max is 2, anyways
15            
16             EOC
17             my $ref3 = XMLin($xmlStr3);
18              
19             my $op3 = Algorithm::Evolutionary::Op::Base->fromXML( $ref3 );
20             print $op3->asXML(), "\n";
21              
22             my $indi = new Algorithm::Evolutionary::Individual::BitString 10;
23             my $indi2 = $indi->clone();
24             my $indi3 = $indi->clone(); #Operands are modified, so better to clone them
25             $op3->apply( $indi2, $indi3 );
26              
27             my $op4 = new Algorithm::Evolutionary::Op::Uniform_Crossover_Diff 1; #Uniform_Crossover_Diff with 1 crossover points
28              
29             =head1 Base Class
30              
31             L
32              
33             =head1 DESCRIPTION
34              
35             Crossover operator for a GA acting only on those bits that are different.
36              
37             =head1 METHODS
38              
39             =cut
40              
41             package Algorithm::Evolutionary::Op::Uniform_Crossover_Diff;
42              
43 1     1   6 use lib qw( ../../.. );
  1         1  
  1         8  
44              
45             our $VERSION = sprintf "%d.1%02d", q$Revision: 3.5 $ =~ /(\d+)\.(\d+)/g; # Hack for avoiding version mismatch
46              
47 1     1   167 use Carp;
  1         2  
  1         95  
48              
49 1     1   5 use base 'Algorithm::Evolutionary::Op::Crossover';
  1         2  
  1         495  
50              
51             #Class-wide constants
52             our $APPLIESTO = 'Algorithm::Evolutionary::Individual::String';
53             our $ARITY = 2;
54              
55             =head2 new( [$options_hash] [, $operation_priority] )
56              
57             Creates a new n-point crossover operator, with 2 as the default number
58             of points, that is, the default would be
59             my $options_hash = { crossover_rate => 0.5 };
60             my $priority = 1;
61              
62             =cut
63              
64             sub new {
65             my $class = shift;
66             my $hash = { numPoints => shift || 1 };
67             croak "Less than 1 points to cross"
68             if $hash->{'numPoints'} < 1;
69             my $priority = shift || 1;
70             my $self = Algorithm::Evolutionary::Op::Base::new( $class, $priority, $hash );
71             return $self;
72             }
73              
74             =head2 apply( $parent_1, $parent_2 )
75              
76             Same as L, but making
77             sure that what is interchanged is different.
78              
79             =cut
80              
81             sub apply ($$){
82             my $self = shift;
83             my $arg = shift || croak "No victim here!";
84             my $arg2 = shift || croak "No victim here!";
85             my $victim2 = $arg2->clone();
86             my $victim = $arg->clone();
87             my $min_length = ( length( $victim->{_str} ) > length( $victim2->{_str} ) )?
88             length( $victim2->{_str} ): length( $victim->{_str} );
89              
90             my @diffs;
91             for ( my $i = 0; $i < $min_length; $i ++ ) {
92             if ( substr( $victim2->{_str}, $i, 1 ) ne substr( $victim->{_str}, $i, 1 ) ) {
93             push @diffs, $i;
94             }
95             }
96              
97             for ( my $i = 0; $i < $self->{'_numPoints'}; $i ++ ) {
98             if ( $#diffs > 0 ) {
99             my $diff = splice( @diffs, rand(@diffs), 1 );
100             substr( $victim->{'_str'}, $diff, 1 ) = substr( $victim2->{'_str'}, $diff, 1 );
101             } else {
102             last;
103             }
104             }
105             $victim->Fitness( undef );
106             return $victim;
107             }
108              
109             =head1 Copyright
110            
111             This file is released under the GPL. See the LICENSE file included in this distribution,
112             or go to http://www.fsf.org/licenses/gpl.txt
113              
114             CVS Info: $Date: 2011/08/12 09:08:47 $
115             $Header: /cvsroot/opeal/Algorithm-Evolutionary/lib/Algorithm/Evolutionary/Op/Uniform_Crossover_Diff.pm,v 3.5 2011/08/12 09:08:47 jmerelo Exp $
116             $Author: jmerelo $
117             $Revision: 3.5 $
118             $Name $
119              
120             =cut