#!/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.

