#!/usr/bin/perl -w

use 5.032;

# grafo   a -> b -> c   y    a -> d -> c    ¿interesa b <-> d siempre/nunca (paradoja de Braess)?
# ¿sí o no a la ruta bd o db?

my $DEBUG =  0;

my $t = 0;  # contador

my @coches;
push @coches, 1+int (rand()*10) for (0..1_000_000);   # número de viajes a -> c por unidad de tiempo

my %cap = (
    ab => 50,
    bc => 25,
    ad => 30,
    dc => 40,
#    bd => sub { if ($t%2) { return 30; } else { return 0; } },
    bd => 0,
);   # DATO: posibles capacidades de todas las rutas; se expresan en vehículos/minuto

# PRECOMPUTACIÓN DIRECTA: tiempo mínimo

my %timer = (
    ab => 1/$cap{ab},
    bc => 1/$cap{bc},
    ad => 1/$cap{ad},
    dc => 1/$cap{dc},
#    bd => 1/$cap{bd},
);        # tiempos actuales de todas las rutas

my %recorrido = ( # tiempos de los 4 posibles recorridos ac
    abc => 0,
    adc => 0,
    abdc => 0,
#    adbc => 0,
);

my %statsreport;
my ($max, $min, $mean);
my ($tmax, $tmin, $tmean) = (-9e99, 9e99, 0);    # tiempo mínimo - máximo - medio

# decisión: se puede elegir la siguiente iteración por el tiempo mínimo de la anterior

# UNIDAD DE TIEMPO: vamos a suponer que cada oleada de coches sale cada 5 minutos                            /* CANCELADO */
# y vamos a suponer que los tiempos de desplazamiento tienen que ser del orden de UNA HORA                   /* CANCELADO */

# decisión 2: vamos a suponer que el retardo informativo de la decisión de ruta es del orden también de UNA HORA

my $k = 0; 
while ( $k <= 1 ){
    if ($k==0) {                            # primera pasada
	$cap{bd} = 0;
	$timer{bd} = "NO";
    }else{                                  # segunda pasada
	$cap{bd} = 30;
	$timer{bd} = 1/$cap{bd};
#	$timer{db} = 1/$cap{db};
	# primer problema: aparentemente, de b a d tiene sentido y lo contrario no, independientemente de todo lo demás 
    }	
    
    $t = 0;
    my @queue;
    $queue[0]=0;
    %statsreport=();

    my ($ab, $ad, $bd, $bc, $dc) = (0) x 5;
    for my $i (@coches){
	$t++;
        print  "\r" . qw( · - o \ | / )[ $t % 6 ] .
            " |" . "=" x int(50*$t/1000000) . ">" .
            " " x int(50*(1000000-$t)/1000000) . "| " .
            int(100*$t/1000000) . "%  ";    
	
	$i += $queue[$t-1];
    
        ($ab, $ad) = decision($i);        # aqui se ramifican coches ab y ad
	if ($k == 0) {
	    $bc = $ab;
	    $bd = 0;
	}else{
	    ($bd, $bc) = decision($ab);       # en b también se pueden ramificar
	}
	$dc = $bd+$ad;                    # esto no tiene vuelta de hoja

	say "ab=$ab ad=$ad bd=$bd bc=$bc dc=$dc" if $DEBUG;
	
#	for my $j (keys %timer){
#	    my $var = $j;
#	    $timer{$j} *= eval '$' . $var;          # variable de variable, mala programación
#	}
    
	$recorrido{abc} = $timer{ab} * $ab + $timer{bc} * $bc;
	say $recorrido{abc} if $DEBUG;
	$recorrido{adc} = $timer{ad} * $ad + $timer{dc} * $dc;
	say $recorrido{adc} if $DEBUG;
	if ($k == 1) {
	    $recorrido{abdc} = $timer{ab} * $ab + $timer{bd} * $bd + $timer{dc} * $dc;
	    say $recorrido{abdc} if $DEBUG;
	}
#	$recorrido{adbc} = $timer{ad} + $timer{db} + $timer{bc};
#	say $recorrido{abdc} if $DEBUG;
	
	for (keys %recorrido){
	    say $recorrido{$_} if $DEBUG;
	}
	
	$queue[$t] = $i -$cap{ab} -$cap{ad};
	if ($queue[$t] < 0) { $queue[$t] = 0; } 

	stats();
    }
    report();
    $k++;
}


exit 1;

sub decision {
    my ($branch) = @_;
    my $r = int rand()*$branch*5/8;                # adaptado a los datos
    return ($r, ($branch-$r)*3/8) if $k==0;
    return (0, $branch) if $k == 1;
}


sub stats {
    state $c;
    for my $i (keys %recorrido){
	$c++;
	$statsreport{$i} += $recorrido{$i}/scalar(@coches);
    }
    return;
}

sub report {
    my ($i,$j);
    say "";
    $tmean = 0;
    my $tex;
    if ($k ==0){ $tex = "SIN"; } else { $tex = "CON"; }
    say "$tex ramal bd (Braess)";
    say "----------------------";
    say "";
    while (($i,$j) = each %statsreport){
	if ($j < $tmin && $j > 0) { $tmin = $j;  $min = $i; }
	if ($j > $tmax) { $tmax = $j;  $max = $i; } 	
	$tmean += $j;
	say "$i -> $j";
    }
    say "";
    say "tmin = $tmin ($min)";
    say "tmax = $tmax ($max)";
    say "tmean = ",$tmean/scalar(keys %statsreport); 
    return;
}

__END__
  https://es.wikipedia.org/wiki/Paradoja_de_Braess

La conclusión no puede ser más paradógica, ya que se pueden estar 
  construyendo más kilómetros de vías y a la vez, empeorando el 
  tráfico. Pero lo contrario tampoco es cierto: si quitas calles,
  puede que no mejores el tráfico.
  
