#!/usr/bin/perl -w

use 5.034;

my $costekm = 0.25;
my $factor = 1.25;

my $N = 100;             # número de puntos
my (@x, @y, @dem);
for (0..$N-1){
    $x[$_] = rand()* 10;
    $y[$_] = rand()* 10;
    $dem[$_] = rand() * 100;
}

# -----------------------------------

my $r = 1000;     # rejilla

my $Dmin = 9e99;

my ($x, $y, $D) = rejilla(\@x, \@y, \@dem);

say "El centro de gravedad o punto logístico es $x $y para un coste $D";

my ($hx, $hy, $sx, $sy, $c) = ($x,$y,0,0,0); 
while (1){
    $hx += (rand()-0.5)/10000;
    $hy += (rand()-0.5)/10000;
    $D=0;
    for my $p (0..$N-1){
	$D += sqrt( ($x[$p]-$hx)**2 + ($y[$p]-$hy)**2 ) * $factor * $costekm * $dem[$p];
    }
    if ($D < $Dmin){
	$Dmin = $D;
	$sx = $hx;
	$sy = $hy;
	say "Mejorando con modo heurístico x=$sx y=$sy con un coste de $Dmin";
	last if ++$c >= 100;  # 100 soluciones mejores
    }
} 

exit 2;


sub rejilla {
    my ($a, $b, $c) = @_;
    my @x = @$a;
    my @y = @$b;
    my @z = @$c;
    
    my ($minx, $maxx, $miny, $maxy) = (9e99, -9e99, 9e99, -9e99);
    for my $i (0..$N-1){
	$minx = $x[$i] if ($x[$i] < $minx);
	$maxx = $x[$i] if ($x[$i] > $maxx);
    	$miny = $y[$i] if ($y[$i] < $miny);
	$maxy = $y[$i] if ($y[$i] > $maxy);
    }

    my ($rx, $ry);
    for (my $i = $minx; $i <= $maxx; $i += ($maxx-$minx) / $r){
	for (my $j = $miny; $j <= $maxy; $j += ($maxy-$miny) / $r){
	    my ($k, $l, $D) = (0,0,0);
	    $k = ($i + ($maxx-$minx) /$r)/2;
	    $l = ($j + ($maxy-$miny) /$r)/2;
	    for my $p (0..$N-1){
		$D += sqrt( ($x[$p]-$k)**2 + ($y[$p]-$l)**2 ) * $factor * $costekm * $z[$p];
	    }
	    if ($D < $Dmin){
		$Dmin = $D;
		$rx = $k;
		$ry = $l;
	    }
	}
    }
    return ($rx, $ry, $Dmin);
}


