1use strict;
2use warnings;
3
4=head1 NAME
5
6    Algorithm::Evolutionary::Op::NoChangeTerm - Checks for termination of an algorithm; terminates
7                   when several generations transcur without change
8
9=head1 SYNOPSIS
10
11    my $nct = new Algorithm::Evolutionary::Op::NoChangeTerm 10;
12    #nct->apply( \@pop ) will return false after 10 generations w/o change
13
14=head1 Base Class
15
16L<Algorithm::Evolutionary::Op::Base|Algorithm::Evolutionary::Op::Base>
17
18=head1 DESCRIPTION
19
20Algorithm::Evolutionary::Op::NoChangeTerm is used when we want an
21algorithm to finish when the population has stagnated, or the global
22optimum is found. It counts how many generations the population has
23not changed, and returns false after that limit is reached.
24
25It is useful if you want to run an algorithm for a certain time, or if
26you want to apply some fancy diversity operator
27
28=head1 METHODS
29
30=cut
31
32package Algorithm::Evolutionary::Op::NoChangeTerm;
33
34our ($VERSION) = ( '$Revision: 3.0 $ ' =~ / (\d+\.\d+)/ ) ;
35
36use base 'Algorithm::Evolutionary::Op::Base';
37
38=head2 new( [$number_of_generations_without_change] )
39
40Creates a new terminator. Takes as an argument the number of
41generations after which it will return false, which defaults to 10.
42
43=cut
44
45sub new {
46  my $class = shift;
47  my $hash = { noChangeCounterMax => shift || 10,
48	       noChangeCounter => 0,
49	       lastBestFitness => rand()}; # A random value, unlikely
50                                            # to be matched
51  my $self = Algorithm::Evolutionary::Op::Base::new( __PACKAGE__, 1, $hash );
52  return $self;
53}
54
55
56=head2 apply( $population )
57
58Checks if the first member of the population has the same fitness as before,
59and increments counter. The population I<should be ordered>
60
61=cut
62
63sub apply ($) {
64  my $self = shift;
65  my $pop = shift;
66
67  if ( $pop->[0]->Fitness() == $self->{_lastBestFitness} ) {
68	$self->{_noChangeCounter}++;
69#	print "NCT => ", $self->{_noChangeCounter}++, "\n";
70  } else {
71	$self->{_lastBestFitness}= $pop->[0]->Fitness();
72	$self->{_noChangeCounter} = 0;
73  }
74  return $self->{_noChangeCounter} < $self->{_noChangeCounterMax};
75
76}
77
78=head1 See Also
79
80L<Algorithm::Evolutionary::Op::FullAlgorithm> needs an object of this class to check
81for the termination condition. It's normally used alongside "generation-type"
82objects such as L<Algorithm::Evolutionary::Op::Easy>.
83
84There are other options for termination conditions: L<Algorithm::Evolutionary::Op::DeltaTerm> and
85L<Algorithm::Evolutionary::Op::GenerationalTerm>.
86
87
88=head1 Copyright
89
90  This file is released under the GPL. See the LICENSE file included in this distribution,
91  or go to http://www.fsf.org/licenses/gpl.txt
92
93  CVS Info: $Date: 2009/07/24 08:46:59 $
94  $Header: /media/Backup/Repos/opeal/opeal/Algorithm-Evolutionary/lib/Algorithm/Evolutionary/Op/NoChangeTerm.pm,v 3.0 2009/07/24 08:46:59 jmerelo Exp $
95  $Author: jmerelo $
96  $Revision: 3.0 $
97  $Name $
98
99=cut
100
101"The truth is out there";
102