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