File Coverage

lib/Algorithm/Evolutionary/Op/Permutation.pm
Criterion Covered Total %
statement 18 18 100.0
branch n/a
condition n/a
subroutine 6 6 100.0
pod n/a
total 24 24 100.0


line stmt bran cond sub pod time code
1 2     2   26127 use strict;
  2         3  
  2         79  
2 2     2   14 use warnings;
  2         3  
  2         314  
3              
4             =head1 NAME
5              
6             Algorithm::Evolutionary::Op::Permutation - Per-mutation. Got it?
7              
8             =head1 SYNOPSIS
9              
10             use Algorithm::Evolutionary::Op::Permutation;
11              
12             my $op = new Algorithm::Evolutionary::Op::Permutation ; #Create from scratch
13             my $bit_chromosome = new Algorithm::Evolutionary::Individual::BitString 10;
14             $op->apply( $bit_chromosome );
15              
16             my $priority = 2;
17             my $max_iterations = 100; # Less than 10!, absolute maximum number
18             # of permutations
19             $op = new Algorithm::Evolutionary::Op::Permutation $priority, $max_iterations;
20              
21             my $xmlStr=<
22            
23             EOC
24             my $ref = XMLin($xmlStr);
25              
26             my $op = Algorithm::Evolutionary::Op::->fromXML( $ref );
27             print $op->asXML(), "\n*Arity ->", $op->arity(), "\n";
28              
29              
30             =head1 Base Class
31              
32             L
33              
34             =head1 DESCRIPTION
35              
36             Class independent permutation operator; any individual that has the
37             C<_str> instance variable (like
38             L and
39             L) will have some
40             of its elements swapped. Each string of length l has l!
41             permutations; the C parameter should not be higher
42             than that.
43              
44             This kind of operator is used extensively in combinatorial
45             optimization problems. See, for instance,
46             @article{prins2004simple,
47             title={{A simple and effective evolutionary algorithm for the vehicle routing problem}},
48             author={Prins, C.},
49             journal={Computers \& Operations Research},
50             volume={31},
51             number={12},
52             pages={1985--2002},
53             issn={0305-0548},
54             year={2004},
55             publisher={Elsevier}
56             }
57              
58             And, of course, L, where it is used in the
59             evolutionary algorithms solutions.
60              
61              
62             =cut
63              
64             package Algorithm::Evolutionary::Op::Permutation;
65              
66 2     2   13 use lib qw( ../../.. );
  2         4  
  2         13  
67              
68             our ($VERSION) = ( '$Revision: 3.5 $ ' =~ /(\d+\.\d+)/ );
69              
70 2     2   525 use Carp;
  2         5  
  2         249  
71 2     2   2139 use Clone qw(clone);
  2         10953  
  2         182  
72              
73 2     2   21 use base 'Algorithm::Evolutionary::Op::Base';
  2         5  
  2         717  
74             use Algorithm::Permute;
75              
76             #Class-wide constants
77             our $APPLIESTO = 'Algorithm::Evolutionary::Individual::String';
78             our $ARITY = 1;
79              
80             =head1 METHODS
81              
82             =head2 new( [$rate = 1][, $max_iterations = 10] )
83              
84             Creates a new permutation operator; see
85             L for details common to all
86             operators. The chromosome will undergo a random number of at most
87             C<$max_iterations>. By default, it equals 10.
88              
89             =cut
90              
91             sub new {
92             my $class = shift;
93             my $rate = shift || 1;
94              
95             my $self = Algorithm::Evolutionary::Op::Base::new( 'Algorithm::Evolutionary::Op::Permutation', $rate );
96             $self->{'_max_iterations'} = shift || 10;
97             return $self;
98             }
99              
100              
101             =head2 create
102              
103             Creates a new mutation operator with an application priority, which
104             defaults to 1.
105              
106             Called create to distinguish from the classwide ctor, new. It just
107             makes simpler to create an Operator
108              
109             =cut
110              
111             sub create {
112             my $class = shift;
113             my $rate = shift || 1;
114              
115             my $self = { rate => $rate,
116             max_iterations => shift || 10 };
117              
118             bless $self, $class;
119             return $self;
120             }
121              
122             =head2 apply( $chromosome )
123              
124             Applies at most C permutations to a "Chromosome" that includes the C<_str>
125             instance variable. The number of iterations will be random, so
126             that applications of the operator on the same individual will
127             create diverse offspring.
128              
129             =cut
130              
131             sub apply ($;$) {
132             my $self = shift;
133             my $arg = shift || croak "No victim here!";
134             my $victim = clone($arg);
135             croak "Incorrect type ".(ref $victim) if ! $self->check( $victim );
136             my @arr = split("",$victim->{_str});
137             my $p = new Algorithm::Permute( \@arr );
138             my $iterations = 1+rand($self->{'_max_iterations'}-1);
139             for (1..$iterations) {
140             @arr = $p->next;
141             }
142             if ( !@arr) {
143             croak "I broke \@arr $iterations ", $self->{'_max_iterations'}, " ", $victim->{'_str'}, "\n";
144             }
145             if ( join( "", @arr ) eq $arg->{'_str'} ) {
146             # Check for all equal
147             my %letters;
148             map( $letters{$_}=1, @arr );
149             if ( scalar keys %letters > 1) {
150             $p->reset; # We are looking for anything different, after all
151             do {
152             @arr = $p->next;
153             } until ( join( "", @arr ) ne $arg->{'_str'} );
154             # print "Vaya tela $iterations ", $self->{'_max_iterations'}, " ", $victim->{'_str'}, "\n";
155             # print $victim->{'_str'}, "\n";
156             }
157             }
158             if ( !@arr) {
159             croak "Gosh $iterations ", $self->{'_max_iterations'}, " ", $victim->{'_str'}, "\n";
160             }
161             $victim->{'_str'} = join( "", @arr );
162             return $victim;
163             }
164              
165             =head2 SEE ALSO
166              
167             Uses L, which is purported to be the fastest
168             permutation library around. Might change it in the future to
169             L, which is much more comprehensive.
170              
171             =head1 Copyright
172            
173             This file is released under the GPL. See the LICENSE file included in this distribution,
174             or go to http://www.fsf.org/licenses/gpl.txt
175              
176             CVS Info: $Date: 2011/02/19 17:59:32 $
177             $Header: /cvsroot/opeal/Algorithm-Evolutionary/lib/Algorithm/Evolutionary/Op/Permutation.pm,v 3.5 2011/02/19 17:59:32 jmerelo Exp $
178             $Author: jmerelo $
179             $Revision: 3.5 $
180              
181             =cut
182