1
by jmerelo
The fichero |
1 |
#!/usr/bin/perl
|
2 |
||
4
by jmerelo
Mejoras mínimas en funciones y crossover |
3 |
use strict; |
4 |
use warnings; |
|
5 |
||
11
by JJ Merelo
Eliminating sort |
6 |
use Sort::Key::Top qw(rnkeytop) ; |
8
by jmerelo
Cambio del clasificador de sort por defecto |
7 |
|
1
by jmerelo
The fichero |
8 |
my $chromosome_length = shift || 16; |
9 |
my $population_size = shift || 32; |
|
10 |
my $generations = shift || 100; |
|
11 |
||
12 |
print<<EOC; |
|
13 |
CL $chromosome_length
|
|
14 |
PS $population_size
|
|
15 |
GEN $generations
|
|
16 |
EOC
|
|
17 |
||
18 |
my @population = map( random_chromosome( $chromosome_length ), |
|
19 |
1..$population_size ); |
|
20 |
||
2
by jmerelo
Primera mejora, con caché |
21 |
my %fitness_of; |
4
by jmerelo
Mejoras mínimas en funciones y crossover |
22 |
my ($this_generation,@best); |
26
by JJ Merelo
Fixed GA errors |
23 |
while ( $this_generation++ <= $generations ) { |
7
by jmerelo
Eliminación de un bucle para cálculo del fitness total |
24 |
my $total_fitness = 0; |
25 |
map( ((!$fitness_of{$_})?compute_fitness( $_ ):1) |
|
26 |
&& ( $total_fitness += $fitness_of{$_} ), @population ); |
|
11
by JJ Merelo
Eliminating sort |
27 |
@best = rnkeytop { $fitness_of{$_} } 2 => @population; |
28 |
my @wheel = map( $fitness_of{$_}/$total_fitness, @population); |
|
7
by jmerelo
Eliminación de un bucle para cálculo del fitness total |
29 |
my @slots = spin( \@wheel, $population_size ); |
30 |
my @pool; |
|
31 |
my $index = 0; |
|
32 |
do { |
|
33 |
my $p = $index++ % @slots; |
|
34 |
my $copies = $slots[$p]; |
|
35 |
for (1..$copies) { |
|
11
by JJ Merelo
Eliminating sort |
36 |
push @pool, $population[$p]; |
7
by jmerelo
Eliminación de un bucle para cálculo del fitness total |
37 |
}
|
38 |
} while ( @pool <= $population_size ); |
|
39 |
||
40 |
@population = (); |
|
41 |
for ( my $i = 0; $i < $population_size/2 -1 ; $i++ ) { |
|
42 |
my $first = $pool[rand($#pool)]; |
|
43 |
my $second = $pool[rand($#pool)]; |
|
44 |
||
45 |
push @population, crossover( $first, $second ); |
|
1
by jmerelo
The fichero |
46 |
}
|
26
by JJ Merelo
Fixed GA errors |
47 |
map( $_ = mutate($_), @population ); |
1
by jmerelo
The fichero |
48 |
|
7
by jmerelo
Eliminación de un bucle para cálculo del fitness total |
49 |
push @population, @best; |
26
by JJ Merelo
Fixed GA errors |
50 |
last if ($fitness_of{$best[0]} >= $chromosome_length ); |
51 |
}
|
|
52 |
||
53 |
print "Best ", $best[0], " fitness ", $fitness_of{$best[0]}, |
|
54 |
"\nGeneration ", $this_generation, "\n"; |
|
55 |
||
56 |
#-------------------------------------------------------------
|
|
1
by jmerelo
The fichero |
57 |
sub random_chromosome { |
58 |
my $length = shift; |
|
59 |
my $string = ''; |
|
60 |
for (1..$length) { |
|
61 |
$string .= (rand >0.5)?1:0; |
|
62 |
}
|
|
2
by jmerelo
Primera mejora, con caché |
63 |
$string; |
1
by jmerelo
The fichero |
64 |
}
|
65 |
||
11
by JJ Merelo
Eliminating sort |
66 |
sub spin { |
67 |
my ( $wheel, $slots ) = @_; |
|
68 |
my @slots = map( $_*$slots, @$wheel ); |
|
69 |
return @slots; |
|
70 |
}
|
|
71 |
||
1
by jmerelo
The fichero |
72 |
sub mutate { |
73 |
my $chromosome = shift; |
|
2
by jmerelo
Primera mejora, con caché |
74 |
my $mutation_point = rand( length( $chromosome )); |
75 |
substr($chromosome, $mutation_point, 1, |
|
76 |
( substr($chromosome, $mutation_point, 1) eq 1 )?0:1 ); |
|
77 |
return $chromosome; |
|
1
by jmerelo
The fichero |
78 |
}
|
79 |
||
80 |
sub crossover { |
|
2
by jmerelo
Primera mejora, con caché |
81 |
my ($chromosome_1, $chromosome_2) = @_; |
1
by jmerelo
The fichero |
82 |
my $length = length( $chromosome_1 ); |
4
by jmerelo
Mejoras mínimas en funciones y crossover |
83 |
my $xover_point_1 = int rand( $length - 2 ); |
84 |
my $range = 1 + int rand ( $length - $xover_point_1 ); |
|
1
by jmerelo
The fichero |
85 |
my $swap_chrom = $chromosome_1; |
4
by jmerelo
Mejoras mínimas en funciones y crossover |
86 |
substr($chromosome_1, $xover_point_1, $range, |
87 |
substr($chromosome_2, $xover_point_1, $range) ); |
|
88 |
substr($chromosome_2, $xover_point_1, $range, |
|
89 |
substr($swap_chrom, $xover_point_1, $range) ); |
|
1
by jmerelo
The fichero |
90 |
return ( $chromosome_1, $chromosome_2 ); |
91 |
}
|
|
92 |
||
93 |
sub compute_fitness { |
|
94 |
my $chromosome = shift; |
|
3
by jmerelo
Segunda mejora, cambio fitness |
95 |
my $copy_of = $chromosome; |
96 |
$fitness_of{$chromosome} = ($copy_of =~ tr/1/0/); |
|
1
by jmerelo
The fichero |
97 |
}
|
98 |
||
99 |