1use strict; 2use warnings; 3 4=head1 NAME 5 6Algorithm::Evolutionary::Op::Crossover - n-point crossover 7 operator; puts fragments of the second operand into the first operand 8 9 10=head1 SYNOPSIS 11 12 #Create from XML description using EvoSpec 13 my $xmlStr3=<<EOC; 14 <op name='Crossover' type='binary' rate='1'> 15 <param name='numPoints' value='3' /> #Max is 2, anyways 16 </op> 17 EOC 18 my $op3 = Algorithm::Evolutionary::Op::Base->fromXML( $xmlStr3 ); 19 print $op3->asXML(), "\n"; 20 21 #Apply to 2 Individuals of the String class 22 my $indi = new Algorithm::Evolutionary::Individual::BitString 10; 23 my $offspring = $op3->apply( $indi2, $indi3 ); #$indi2 == $offspring 24 25 #Initialize using OO interface 26 my $op4 = new Algorithm::Evolutionary::Op::Crossover 2; #Crossover with 2 crossover points 27 28=head1 Base Class 29 30L<Algorithm::Evolutionary::Op::Base|Algorithm::Evolutionary::Op::Base> 31 32=head1 DESCRIPTION 33 34Crossover operator for a Individuals of type 35L<Algorithm::Evolutionary::Individual::String|Individual::String> and 36their descendants 37(L<Algorithm::Evolutionary::Individual::BitString|Individual::BitString>). Crossover 38for L<Algorithm::Evolutionary::Individual::Vector|Individual::Vector> 39would be L<Algorithm::Evolutionary::Op::VectorCrossover|Op::VectorCrossover> 40 41=head1 METHODS 42 43=cut 44 45package Algorithm::Evolutionary::Op::Crossover; 46 47use lib qw(../../..); 48 49our $VERSION = sprintf "%d.%03d", q$Revision: 3.2 $ =~ /(\d+)\.(\d+)/g; # Hack for avoiding version mismatch 50 51use Clone qw(clone); 52use Carp; 53 54use base 'Algorithm::Evolutionary::Op::Base'; 55 56#Class-wide constants 57our $APPLIESTO = 'Algorithm::Evolutionary::Individual::String'; 58our $ARITY = 2; 59our %parameters = ( numPoints => 2 ); 60 61=head2 new( [$options_hash] [, $operation_priority] ) 62 63Creates a new n-point crossover operator, with 2 as the default number 64of points, that is, the default would be 65 my $options_hash = { numPoints => 2 }; 66 my $priority = 1; 67 68=cut 69 70sub new { 71 my $class = shift; 72 my $hash = { numPoints => shift || 2 }; 73 my $rate = shift || 1; 74 my $self = Algorithm::Evolutionary::Op::Base::new( $class, $rate, $hash ); 75 return $self; 76} 77 78=head2 apply( $chromsosome_1, $chromosome_2 ) 79 80Applies xover operator to a "Chromosome", a string, really. Can be 81applied only to I<victims> with the C<_str> instance variable; but 82it checks before application that both operands are of type 83L<BitString|Algorithm::Evolutionary::Individual::String>. 84 85Changes the first parent, and returns it. If you want to change both 86parents at the same time, check L<QuadXOver|Algorithm::Evolutionary::Op::QuadXOver> 87 88=cut 89 90sub apply ($$$){ 91 my $self = shift; 92 my $arg = shift || croak "No victim here!"; 93 my $victim = clone( $arg ); 94 my $victim2 = shift || croak "No victim here!"; 95 my $minlen = ( length( $victim->{_str} ) > length( $victim2->{_str} ) )? 96 length( $victim2->{_str} ): length( $victim->{_str} ); 97 my $pt1 = int( rand( $minlen ) ); 98 my $range = 1 + int( rand( $minlen - $pt1 ) ); 99# print "Puntos: $pt1, $range \n"; 100 croak "No number of points to cross defined" if !defined $self->{_numPoints}; 101 if ( $self->{_numPoints} > 1 ) { 102 $range = int ( rand( length( $victim->{_str} ) - $pt1 ) ); 103 } 104 105 substr( $victim->{_str}, $pt1, $range ) = substr( $victim2->{_str}, $pt1, $range ); 106 $victim->{'_fitness'} = undef; 107 return $victim; 108} 109 110=head1 SEE ALSO 111 112=over 4 113 114=item L<Algorithm::Evolutionary::Op::QuadXOver> for pass-by-reference xover 115 116=item L<Algorithm::Evolutionary::Op::Uniform_Crossover> another more mutation-like xover 117 118=item L<Algorithm::Evolutionary::Op::Gene_Boundary_Crossover> don't disturb the building blocks! 119 120=item L<Algorithm::Evolutionary::Op::Uniform_Crossover_Diff> vive la difference! 121 122=back 123 124=head1 Copyright 125 126 This file is released under the GPL. See the LICENSE file included in this distribution, 127 or go to http://www.fsf.org/licenses/gpl.txt 128 129 CVS Info: $Date: 2011/02/14 06:55:36 $ 130 $Header: /media/Backup/Repos/opeal/opeal/Algorithm-Evolutionary/lib/Algorithm/Evolutionary/Op/Crossover.pm,v 3.2 2011/02/14 06:55:36 jmerelo Exp $ 131 $Author: jmerelo $ 132 $Revision: 3.2 $ 133 $Name $ 134 135=cut 136