1use strict; 2use warnings; 3 4=encoding utf8 5 6=head1 NAME 7 8Algorithm::Evolutionary::Op::Combined - Combinator of several operators of the same arity, unary or binary 9 10=head1 SYNOPSIS 11 12 13 #Initialize using OO interface 14 my $op = new Algorithm::Evolutionary::Op::Mutation 0.1 3 15 my $another_op = new Algorithm::Evolutionary::Op::Permutation 2 16 # Single operator with rate of application = 3 17 my $combined_op = new Algorithm::Evolutionary::Op::Combined [ $op, $another_op ], 3; 18 19=head1 Base Class 20 21L<Algorithm::Evolutionary::Op::Base|Algorithm::Evolutionary::Op::Base> 22 23=head1 DESCRIPTION 24 25Some algorithms (such as 26L<Algorithm::Evolutionary::Op::Canonical_GA_NN>) need a single 27"mutation" and a single "crossover" operator. If you want to combine 28several (like above, mutation and permutation), each one with its own 29rate, you have to give them a façade like this one. 30 31=head1 METHODS 32 33=cut 34 35package Algorithm::Evolutionary::Op::Combined; 36 37use lib qw(../../..); 38 39our $VERSION = '1.2'; 40 41use Algorithm::Evolutionary::Wheel; 42use Carp; 43 44use base 'Algorithm::Evolutionary::Op::Base'; 45 46#Class-wide constants 47our $APPLIESTO = 'Algorithm::Evolutionary::Individual::String'; 48our $ARITY = 2; 49our %parameters = ( numPoints => 2 ); 50 51=head2 new( $ref_to_operator_array [, $operation_priority] ) 52 53Priority defaults to one, operator array has no defaults. 54 55=cut 56 57sub new { 58 my $class = shift; 59 croak "Need operator array" if (!@_) ; 60 my $hash = { ops => shift }; 61 my $rate = shift || 1; 62 my $self = Algorithm::Evolutionary::Op::Base::new( $class, $rate, $hash ); 63 return $self; 64} 65 66=head2 apply( @operands ) 67 68Applies the operator to the set of operands. All are passed, as such, 69to whatever operator is selected 70 71=cut 72 73sub apply ($$$){ 74 my $self = shift; 75 my @victims = @_; # No need to clone, any operator will also clone. 76 my $op_wheel = new Algorithm::Evolutionary::Wheel map( $_->{'rate'}, @{$self->{'_ops'}} ); 77 my $selected_op = $self->{'_ops'}->[ $op_wheel->spin()]; 78 79 return $selected_op->apply(@victims); 80} 81 82=head1 SEE ALSO 83 84=over 4 85 86=item L<Algorithm::Evolutionary::Op::Mutation> a mutation operator. 87 88=item L<Algorithm::Evolutionary::Op::Uniform_Crossover> another more mutation-like crossover. These two operators can be combined using this one, for instance. 89 90=back 91 92=head1 Copyright 93 94This file is released under the GPL. See the LICENSE file included in this distribution, 95or go to http://www.fsf.org/licenses/gpl.txt 96 97=cut 98