#!/usr/local/bin/perl -w

$days = 80;
$mu = 4/3; # exponential arraival
$sigma = 1;
$unloadingmin=0.5;
$unloadingmax=2;

%docks=(
	"dock1" => 1,
	"dock2" => 2,
	"dock3" => 1,
);
%busy = %docks;

$type[1] = "dock1";
$type[2] = "dock2";
$type[3] = "dock3";

$prob[1]= .25;
$prob[2]= .75;
$prob[3]= 1;


$time=0;
$delay=0;
for $d (1..$days){
    for $h (0..23){
	if ($time >= $delay){
	    $z = rand();
	    for $i (1..3) {
		if ($z < $prob[$i]){
		    $count++;		
		    $tipo[$count]=$i;
		    event($count, $tipo[$count]);
		    $delay = $time +randexp($mu,$sigma); 
		    last;
		}
	    }	
	}
	for $i (1..$count){
	    if (!defined $totaltime[$i]){
		event($i,$tipo[$i]);
	    }
	}	
	$time += 1/24;
    }
}
report();

sub event{
    my $i = shift;
    my $c = shift;
    if (!defined $start[$i]){ 
	$busy{$type[$c]}--;
	if ($busy{$type[$c]}<0){
	    $busy{$type[$c]}=-1;
	    $queue[$i]+=1/24;
            $queue{$type[$c]}+=1/24;    
	}else{
	    $start[$i]=$time;	
	    $stop[$i]=$time + $unloadingmin + rand($unloadingmax-$unloadingmin);
	}
    }elsif ($time <= $stop[$i]){
	return ;
    }elsif ($time > $stop[$i]){
	$totaltime[$i]=$stop[$i]-$start[$i];
	$jobs++;
	$busy{$type[$c]}++;
	if ($busy{$type[$c]} > $docks{$type[$c]}){ 
	    $busy{$type[$c]}=$docks{$type[$c]}; 
	}
    }
}


sub report {
    print "\nElapsed time $time days\n";
    print "Arraived $count ships and were unloaded $jobs\n";
    $min = 9e99;
    $max = 0 ;
    $maxqueue=0;
    for $i (1..$count){
        if (defined $queue[$i]){
            if ($queue[$i] > $maxqueue) { $maxqueue=$queue[$i]; }
        }else{ $queue[$i]=0; }
        $meanqueue += $queue[$i];
        if (defined $totaltime[$i]){
	    $z = $queue[$i] + $totaltime[$i];
	    if ($z < $min) { $min=$z; }
	    if ($z > $max) { $max=$z; }
	    $mean += $z;
	}
    }
    $mean /= $jobs;
    $meanqueue /= $count;
    print "\nThe minimun time to unload was $min\n";
    print "The maximun time to unload was $max\n";
    print "The mean time to unload was $mean\n\n";
    
    print "\nThe maximun time in queue was $maxqueue\n";
    print "Finally, the mean queue time was $meanqueue\n\n";

    for $i (keys %docks){
        if (defined $queue{$i}){
            print "Dock $i has a total queue of $queue{$i}\n";
        }else{
            print "Dock $i has no queues\n";
        }
    }
}


sub randexp {
    my $mu = shift;
    my $sigma = shift;	
    # Generate the random variables by inversion method.
    return $mu - $sigma * log rand;
}


__END__
