#!/usr/bin/perl -w

use 5.034;

my $N = 401;    # abundante
my @datos;
my $s = 0;
for (0..$N-1){  # son 401 datos para una ecuación SUM $w_i * $datos_i = OBJETIVO
    push @datos, int (rand()*123456789);
    $s += $datos[-1];
}
say "Datos generados. $N parámetros. Suma = $s";

### Comienzo de main
my $t0 = time();
my @cand;
my $err;
my $k = 0;
my $record = 9e99;
my @candidato;
my $objetivo = -55555.55555;             # OBJETIVO, importante
my $et = 60*15;                          # 15 minutos de presupuesto de tiempo

push @candidato, (rand()-0.5)/10_000 for (0..$N-1);

loop1:                          # un nuevo reinicio aleatorio     
@cand = @candidato;

while (1){                          # tras pequeña modificación, loop. Es el principal, porque llama al sub function()
    select(undef,undef,undef,0.001);
    $err = $objetivo - function(@cand);
    
    if ( abs($err) <= $record ){
	if (abs($err) < $record) {
	    say "$k) OBJ = $objetivo -> error $err   ", time()-$t0, " seconds.";
	}
	$record = abs($err);
	@candidato = @cand;
	exit 3 if $err == 0;
    }elsif (++$k % 500_000 == 0){
	goto loop1;
    }

    last if (time()-$t0 > $et);
    muta();
}

exit 2;

sub muta {
    my $p = int( rand() * $N );
    my $q = 2 * rand() / $N;
    if ( $err < 0 ) {
	$cand[$p] = -1*$q;
    }else{
	$cand[$p] = $q;
    }
}

sub function {
    my @w = @_;
    my $sum = 0;
    $sum += $_ * $datos[$_] for (@w);
    return $sum;
}

__END__

