#!/usr/local/bin/perl -w use Time::HiRes qw(time); $demanda = 10_000; # en unidades print "Se demandan $demanda unidades.\n"; # FASE 1: Recepción de ofertas $tiempo_de_recepcion = 0.5; # en segundos $t0 = time; $deadline = $t0+$tiempo_de_recepcion; $count = 0; while (time <= $deadline){ $oferta[$count][0]=$count; $oferta[$count][1]=(A, B, C, D, E, F, G, H, I, J, K, L)[int rand(12)]; $oferta[$count][2]=10*abs(int normal(100,20)); # tamaño del lote $importe = sprintf("%.2f", (normal(2000,200))); $oferta[$count][3]=$importe/$oferta[$count][2]; # precio unitario $count++; } print "Se han recibido $count lotes de ofertas...\n"; # FASE 2: Ordenación @sorted = sort { $a->[3] <=> $b->[3] || $a->[0] <=> $b->[0] } @oferta; # FASE 3: Selección $sum=$sumprecio=0; for $aoaref ( @sorted ){ @lote = @$aoaref; if ($lote[2]+$sum <= $demanda ){ $sum += $lote[2]; $precio = $lote[2]*$lote[3]; print "Lote $lote[0] de $lote[1]: $lote[2] u. por $precio\n"; $sumprecio += $precio; last if $sum == $demanda; }else{ $cantidad = $demanda-$sum; die "Error" if $cantidad > $lote[2]; $sum += $cantidad; $precio = sprintf("%.2f", $cantidad*$lote[3]); print "Lote parcial $lote[0] de $lote[1]: $cantidad u. por $precio\n"; $sumprecio += $precio; last; } } print "Se pueden contratar $sum unidades.\n"; $preciomedio = $sumprecio/$demanda; print "Se paga $sumprecio en total, a un precio medio de $preciomedio\n"; $tiempo = time-$t0; printf "Fin de %s: se tardó %.3f segundos.\n",$0,$tiempo; sub normal { my ($mu, $sigma) = @_; my $num =1 ; # Generate the random variables by the Box-Muller method. my @z; my $const = -2 * $sigma * $sigma; my $i; for ($i = 0 ; $i < $num ; $i += 2) { my $r = sqrt $const * log rand; my $t = 2* atan2 (0,-1) * rand; push @z, $mu + $r * sin $t, $mu + $r * cos $t; } pop @z if $i > $num; return @z if wantarray; return $z[0]; } __END__