#!/usr/bin/perl -w use 5.032; my $DEBUG = 1; ### BASIC decision on uncertainly ### # EXAMPLE # WE KNOWN 3 POSIBLE SCENARIOS: RECESSION, ESTABLE, GROWN # WE have a lot (say 5) posible PROJECTS OF INVERSION # WE HAVE TO DECIDE WHICH PROJECT OF INVERSION IS BETTER TO CHOOSE # WE HAVE EXPECTED DATA -> EVERY ROI of posible combinations # @ ROI[ SCENARIO i ][ Project number j] # SIMPLE SOLUTION: 1) There are a lot diferent criteria # 2) A conservative one could be # 2.1 FOR EACH SCENARIO i # 2.2 AND EACH PROJECT j # 2.3 CALCULATE MINIMUN ROI [ * ] [ j ]; # # 2.4 FOR EACH PROJECT j # 2.5 CALCULATE MAXIM ( MUNIMUN _previously_calculated_ ROI [i][i] ) # 2.6 THAT PROJECT j MAX OF MIN IS THE BEST PROJECT # # ANEXO: # # RandomForest: generar pesos aleatorios que sumen 1 # aplicarlos a cada escenario i # comparar cada proyecto j segun la media ponderada sin y con truncamiento de extremos # iterar un número suficiente de veces # el análisis de los resultados es la miga. Se puede hacer un conteo de veces que sale un proyecto mejor y peor my $scenarios = 5; # a well wide number of number of scenarios my $NP = 15; # número de proyectos my $NI = 1_000_000; # número de iteraciones my @escenario = qw(recesion decrecimiento_moderado estabilidad crecimiento_moderado expansion); # hay incertidumbre total sobre la probabilidad de los escenarios my @escen = 0..$scenarios-1; my @projects = 0..($NP-1); my @ROI; for my $i (@escen){ for my $j (@projects){ $ROI[$i][$j] = rand() * 1000 + $i *2 ; # hay que añadir una trampa para verificar los resultados print "$ROI[$i][$j] " if $DEBUG; } say "" if $DEBUG; } say "Data generated" if $DEBUG; say ""; my $t0 = time; my ($z, $ROIz) = max_min(); say "El criterio max_min elige proyecto $z con ROI $ROIz"; say ""; my (@bien, @mal) = ((0) x $NP, (0) x $NP); for (1..$NI){ my ($x,$y) = random_forest(); # stats bien[j] mal[j] $bien[$x]++; $mal[$y]++; } say "Relación de resultados por proyecto de $NI iteraciones"; for my $j (@projects){ $bien[$j] = 0 unless defined $bien[$j]; $mal[$j] = 0 unless defined $mal[$j]; say "Proyecto $j: mejor $bien[$j] peor $mal[$j]"; } say ""; say "$0: Elapsed time ",time()-$t0, " secs."; exit 1; sub max_min { my $maxj = -9e99; my @mini = (9e99) x $NP; my ($indj, @indi); for my $i ( @escen ){ for my $j (@projects){ if ($ROI[$i][$j] < $mini[$j]) { $mini[$j] = $ROI[$i][$j]; $indi[$j] = $j; } } } for my $j (@projects){ if ($mini[$j] > $maxj){ $maxj = $mini[$j]; $indj = $indi[$j]; } } return ($indj, $maxj); # devuelve el index y el valor } sub random_forest { my @w; my $sum = 0; # for my $i (@escen){ # if ($i < 2){ # push @w, rand()/(3-1); # $sum += $w[-1]; # }else{ # push @w, 1-$w[1]-$w[0]; # } # } my $ok = 0; while ($ok < $scenarios){ # this randomization is better my $i = int (rand()*$scenarios); if (!defined $w[$i]){ $w[$i] = rand(); $ok++; $sum += $w[$i]; } } my $sum2 = 0; for my $i (0..$scenarios-1) { $w[$i] /= $sum; $sum2 += $w[$i]; } # if ($sum2 != 1.0 && $DEBUG) { # warn "No suma 1, suma $sum2"; # } my (@wp, @pond); for my $j (@projects){ for my $i (@escen){ $wp[$i][$j] = $ROI[$i][$j] * $w[$i]; $pond[$j] += $wp[$i][$j]; } } my $max = -9e99; my $min = 9e99; my ($r, $r2); for my $j (@projects){ if ($pond[$j] > $max){ $max = $pond[$j]; $r = $j; }elsif ($pond[$j] < $min){ $min = $pond[$j]; $r2 = $j; } } $r = -1 unless defined $r; $r2 = -1 unless defined $r2; return ($r, $r2); } __END__ This v0.02 adresses the problem of multiple scenarios and projects.