use strict; # -*- cperl -*-
use warnings;
use lib qw( ../../../../lib );
=head1 NAME
Algorithm::Evolutionary::Fitness::Knapsack - Fitness function for the knapsack problem
=head1 SYNOPSIS
my $n_max=100; #Max. number of elements to choose
my $capacity=286; #Max. Capacity of the knapsack
my $rho=5.0625; #Penalty coeficient
my @profits = qw( 1..100 );
my @weights = qw( 2.. 101 );
my $knapsack = Algorithm::Evolutionary::Fitness::Knapsack->new( $n_max, $capacity, $rho, \@profits, \@weights );
=head1 DESCRIPTION
Knapsack function with penalties applied in a particular way.
=head1 METHODS
=cut
package Algorithm::Evolutionary::Fitness::Knapsack;
our ($VERSION) = ( '$Revision: 3.1 $ ' =~ / (\d+\.\d+)/ ) ;
use Carp qw( croak );
use base qw(Algorithm::Evolutionary::Fitness::String);
=head2 new
Creates a new instance of the problem, with the said number of bits and peaks
=cut
sub new {
my $class = shift;
my ( $n_max, $capacity, $rho, $profits_ref, $weights_ref ) = @_;
if ( ((scalar @$profits_ref) != $n_max ) ||
((scalar @$weights_ref) != $n_max ) ) {
croak "Wrong number of profits";
}
if ( (scalar @$profits_ref) != ( scalar @$weights_ref ) ) {
croak "Profits and weights differ";
}
#Instantiate superclass
my $self = $class->SUPER::new();
$self->{'capacity'} = $capacity;
$self->{ 'rho' } = $rho;
$self->{ 'profits'} = $profits_ref;
$self->{ 'weights'} = $weights_ref;
$self->initialize();
return $self;
}
sub _really_apply {
my $self = shift;
return $self->knapsack( @_ );
}
=head2 knapsack
Applies the knapsack problem to the string, using a penalty function
=cut
sub knapsack {
my $self = shift;
my $string = shift;
my $cache = $self->{'_cache'};
if ( $cache->{$string} ) {
return $cache->{$string};
}
my $profit=0.0;
my $weight=0.0;
my @profits = @{$self->{'profits'}};
my @weights = @{$self->{'weights'}};
for (my $i=0 ; $i < length($string); $i++) { #Compute weight
my $this_bit=substr ($string, $i, 1);
if ($this_bit == 1) {
$profit += $profits[$i];
$weight += $weights[$i];
}
}
if ($weight > $self->{'capacity'}) { # Apply penalty
my $penalty = $self->{'rho'} * ($weight - $self->{'capacity'});
$profit = $profit - ( $penalty + log(1.0 + $penalty) / log(2.0) );
}
#Y devolvemos la ganancia calculada
$cache->{$string} = $profit;
return $profit;
}
=head1 Copyright
This file is released under the GPL. See the LICENSE file included in this distribution,
or go to http://www.fsf.org/licenses/gpl.txt
CVS Info: $Date: 2010/09/24 08:39:07 $
$Header: /media/Backup/Repos/opeal/opeal/Algorithm-Evolutionary/lib/Algorithm/Evolutionary/Fitness/Knapsack.pm,v 3.1 2010/09/24 08:39:07 jmerelo Exp $
$Author: jmerelo $
$Revision: 3.1 $
$Name $
=cut
"What???";