#!/usr/bin/perl -w

my $puntos = 100;
my @data;

for (0..$puntos-1){
    $data[$_][0] = rand()*100;
    $data[$_][1] = rand()*100;
    $data[$_][2] = rand()*1000;
}

my $N = 100;          # size of each run
my $candidates = 10;  # size of the best's list 
my $minx = 0;
my $maxx = 100;
my $miny = 0;
my $maxy = 100;
my (@matrix, @list);

print "Value x and y           Error\n";
while (1) {
    for my $i (0..$N-1) {
	$matrix[$i][0] = $minx + rand()*($maxx-$minx);                   # value x
	$matrix[$i][1] = $miny + rand()*($maxy-$miny);
	$matrix[$i][2] = cost($matrix[$i][0],$matrix[$i][1]) ;      # unsigned error
    }
    @list = sort { $a->[2] <=> $b->[2] } @matrix;  
    $minx = 9e99;   # value of the best and worst candidate
    $miny = 9e99;
    $maxx = -9e99;
    $maxy = -9e99;
    for my $i (reverse 0..$candidates-2){
	if ($list[$i][0] > $maxx ) {  $maxx=$list[$i][0]; } 
	if ($list[$i][1] > $maxy ) {  $maxy=$list[$i][1]; } 
	if ($list[$i][0] < $minx ) {  $minx=$list[$i][0]; } 
	if ($list[$i][1] < $miny ) {  $miny=$list[$i][1]; } 
    }
    if ($maxx < $minx ) {
	($minx , $maxx ) = ( $maxx, $minx);	
    }
    if ($maxy < $miny ) {
	($miny , $maxy ) = ( $maxy, $miny);	
    }
    print "$list[0][0] $list[0][1] $list[0][2]\n";
    if (("$list[0][0]" eq "$list[$candidates-1][0]") && ("$list[0][1]" eq "$list[$candidates-1][1]")){
	print "-" x 40, "\n";
	print join(" ",objective())," ",cost(objective()), "\n";
	exit 0;
    }
}

sub objective {
    my ($xx,$yy,$sum);
    for (0..$puntos-1){
	$xx += $data[$_][0]*$data[$_][2];
	$yy += $data[$_][1]*$data[$_][2];
	$sum += $data[$_][2];
    }
    $xx /= $sum;
    $yy /= $sum;
    return ($xx, $yy);
}

sub cost {
    my ($x,$y) = @_;
    my $cost;
    for (0..$puntos-1){
	$cost += 2*$data[$_][2]*sqrt(($data[$_][0]-$x)**2 + ($data[$_][1]-$y)**2);
    }
    return $cost;
}


__END__

Monte Carlo simulation of location
See that the center of gravity (objective)
  is not the point of minimun cost.
  
