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