#!/usr/bin/perl -w use strict; # Digamos que tenemos 30 proyectos de inversión con VAN positivo (VAN = NPV) my $limit = 30; my ($inversion, $npv, @INV, @VAN); for (0..$limit-1){ $inversion = sprintf ("%.02f", -1000 * rand); $npv = 1500 * rand; $INV[$_] = abs ($inversion); $VAN[$_] = $npv; } # Digamos que tenemos un presupuesto de 10_000 (BUDGET) my $PPTO = 10_000; # Enumeremos todas las posibilidades y escogemos la cartera (PORTFOLIO) # de proyectos cuya suma da un mayor VAN de la cartera my $antes = time(); my @a = (0) x $limit; my $count = 0; my $MAXNPV = 0; my $NPROYECTOS = 0; my @b; my ($van, $ppto, $c, @pn); while ($count < $limit) { # print reverse @a, "\n"; # reverse @a for avoid antinature $van = $ppto = $c = 0; for (0..$limit-1){ $van += $a[$_] * $VAN[$_]; $ppto += $a[$_] * $INV[$_]; ++$c if ($a[$_] == 1); } if ($ppto <= $PPTO && $van >= $MAXNPV){ @b = @a; @pn=(); for (0..$limit-1){ push (@pn, $_+1) if $a[$_] == 1; } $MAXNPV = $van; $NPROYECTOS = $c; print "El vector ",@b," produce $MAXNPV con una inversión de $ppto ($c proyectos)\n"; } @a = enum(@a); # next number or combination } print "Lista de proyectos: @pn\n"; my $despues = time(); print "\nElapsed time ", ($despues-$antes)/60," min.\n"; exit 0; sub enum { my @l = @_; my $i = 0; zz: if ($l[$i] == 0) { $l[$i]=1; return @l; }else{ $l[$i]=0; if (++$i > $count){ $l[++$count]=1; return @l; }else{ goto zz; } } } __END__