The Perl Toolchain Summit 2025 Needs You: You can help 🙏 Learn more

use strict;
=head1 NAME
Algorithm::Evolutionary::Op::Eval::MO_Rank - Multiobjective evaluator
based on Pareto rank
=head1 SYNOPSIS
=head1 Base Class
L<Algorithm::Evolutionary::Op::Base>
=head1 DESCRIPTION
After evaluating the population, it's ranked according to the Pareto
fron they're in
=head1 METHODS
=cut
use lib qw(../../../..);
our $VERSION = sprintf "%d.%03d", q$Revision: 3.2 $ =~ /(\d+)\.(\d+)/g;
use Carp;
use Algorithm::Evolutionary::Utils qw(vector_compare);
# Class-wide constants
our $APPLIESTO = 'ARRAY';
our $ARITY = 1;
=head2 new( $evaluation_function )
Creates an evaluator object
=cut
sub new {
my $class = shift;
my $self = {};
$self->{'_eval'} = shift || croak "No eval function found";
bless $self, $class;
return $self;
}
=head2 set( $ref_to_params_hash, $ref_to_code_hash, $ref_to_operators_hash )
Sets the instance variables. Takes a ref-to-hash as input. Not
intended to be used from outside the class. This should go to base,
probably.
=cut
sub set {
my $self = shift;
my $hashref = shift || croak "No params here";
my $codehash = shift || croak "No code here";
my $opshash = shift || croak "No ops here";
for ( keys %$codehash ) {
$self->{"_$_"} = eval "sub { $codehash->{$_} } ";
}
$self->{_ops} =();
for ( keys %$opshash ) {
push @{$self->{_ops}},
Algorithm::Evolutionary::Op::Base::fromXML( $_, $opshash->{$_}->[1], $opshash->{$_}->[0] ) ;
}
}
=head2 apply( $population )
Evaluates the population, setting its fitness value. Fitness should be
univocal, that is, have a single value per string.
=cut
sub apply ($) {
my $self = shift;
my $pop = shift || croak "No population here";
croak "Incorrect type ".(ref $pop) if ref( $pop ) ne $APPLIESTO;
my $eval = $self->{_eval};
#Compute vector fitness
my %fitness_vector_of;
for my $p (@$pop ) {
$p->evaluate( $eval );
$fitness_vector_of{$p->as_string} = $p->Fitness(); #Provisional fitness
}
#Compute rank
my @dominated_by;
my $i;
for ( $i = 0; $i < @$pop; $i++ ) {
for ( my $j = $i+1; $j < @$pop; $j++ ) {
my $result =
vector_compare( $fitness_vector_of{ $pop->[$i]->as_string },
$fitness_vector_of{ $pop->[$j]->as_string } );
$dominated_by[$j]++ if $result == -1;
$dominated_by[$i]++ if $result == 1;
}
}
for ( $i = 0; $i < @$pop; $i++ ) {
$dominated_by[$i]++; # To avoid uninitialized
$pop->[$i]->Fitness( 1/$dominated_by[$i] );
}
}
=head1 SEE ALSO
=over 4
=item *
L<Algorithm::Evolutionary::Fitness::Base>
=back
=head1 Copyright
This file is released under the GPL. See the LICENSE file included in this distribution,
CVS Info: $Date: 2009/11/23 12:31:16 $
$Header: /media/Backup/Repos/opeal/opeal/Algorithm-Evolutionary/lib/Algorithm/Evolutionary/Op/Eval/MO_Rank.pm,v 3.2 2009/11/23 12:31:16 jmerelo Exp $
$Author: jmerelo $
$Revision: 3.2 $
=cut
"The truth is out there";