/
concurrent-evolutionary-algorithm.p6
93 lines (78 loc) · 2.34 KB
/
concurrent-evolutionary-algorithm.p6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#!/usr/bin/env perl6
use v6;
use Algorithm::Evolutionary::Simple;
constant tournament-size = 4;
sub regular-EA ( |parameters (
UInt :$length = 64,
UInt :$population-size = 256,
UInt :$diversify-size = 8,
UInt :$max-evaluations = 10000 )
) {
my Channel $raw .= new;
my Channel $evaluated .= new;
my Channel $channel-three = $evaluated.Supply.batch( elems => tournament-size).Channel;
my Channel $shuffler = $raw.Supply.batch( elems => $diversify-size).Channel;
my Channel $output .= new;
$raw.send( random-chromosome($length).list ) for ^$population-size;
my $count = 0;
my $end;
my $shuffle = start react whenever $shuffler -> @group {
say "Mixing in ", $*THREAD.id;
my @shuffled = @group.pick(*);
$raw.send( $_ ) for @shuffled;
}
my $evaluation = start react whenever $raw -> $one {
my $with-fitness = $one => max-ones($one);
$output.send( $with-fitness );
$evaluated.send( $with-fitness);
# say $count++, " → $with-fitness";
if $with-fitness.value == $length {
$raw.close;
$end = "Found" => $count;
}
if $count++ >= $max-evaluations {
$raw.close;
$end = "Found" => False;
}
say "Evaluating in " , $*THREAD.id;
}
my $selection = start react whenever $channel-three -> @tournament {
say "Selecting in " , $*THREAD.id;
my @ranked = @tournament.sort( { .values } ).reverse;
$evaluated.send( $_ ) for @ranked[0..1];
my @crossed = crossover(@ranked[0].key,@ranked[1].key);
$raw.send( $_.list ) for @crossed.map: { mutation($^þ)};
}
await $evaluation;
loop {
if my $item = $output.poll {
$item.say;
} else {
$output.close;
}
if $output.closed { last };
}
say "Parameters ==";
say "Evaluations => $count";
for parameters.kv -> $key, $value {
say "$key → $value";
};
say "=============";
return $end;
}
sub MAIN ( UInt :$repetitions = 30,
UInt :$length = 64,
UInt :$population-size = 256,
UInt :$diversify-size = 8,
UInt :$max-evaluations = 10000 ) {
my @found;
for ^$repetitions {
my $result = regular-EA( length => $length,
population-size => $population-size,
diversify-size => $diversify-size,
max-evaluations => $max-evaluations );
say( $result );
@found.push( $result );
}
say "Result ", @found;
}