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
94
95
96
97
98
99
100
101
102
103
104
105
106
|
'use strict';
import { network } from '../mind/topology';
// check if a given genome is valid and compute its size
export function get_size(num_input, num_output, genome) {
const [ max_index, max_weight ] = genome.reduce(
([max_index, max_weight ], [ source, sink, weight]) => [
Math.max(max_index, source, sink),
Math.max(max_weight, Math.abs(weight)),
],
[ 0, 0 ]
);
if (max_index < num_input + num_output - 1) {
return -1;
}
else if (max_weight > 4.0) {
return -1;
}
else {
return max_index + 1;
}
}
export function parse_genome(num_input, num_output, genome) {
const size = get_size(num_input, num_output, genome);
if (size < 0) {
// bad genome
throw new Error('invalid genome sequence!');
}
const n = genome.reduce(
(acc, [source, sink, weight]) => acc.connect(source, sink, weight),
network(num_input, size-num_input-num_output, num_output)
);
return n;
}
// --===== mutations =====--
function clamp(value, min, max) {
if (value > max) { return max; }
if (value < min) { return min; }
return value;
}
export function mut_gene_source(n_input, n_internal, n_output, gene, r) {
const [source, sink, weight] = gene;
const new_source = r < 0.5 ? source-1 : source+1;
return [
clamp(new_source, 0, n_input+n_internal-1),
sink,
weight,
];
}
export function mut_gene_sink(n_input, n_internal, n_output, gene, r) {
const [source, sink, weight] = gene;
const new_sink = r < 0.5 ? sink-1 : sink+1;
return [
source,
clamp(new_sink, n_input+n_internal, n_input+n_internal+n_output-1),
weight,
];
}
export function mut_gene_weight(weight_max, gene, r) {
const [source, sink, weight] = gene;
const rr = (2*r)-1;
const move = weight_max * rr;
const new_weight = (2*weight + move)/3;
return [
source,
sink,
clamp(new_weight, -weight_max, weight_max),
];
}
export function mut_genome_expand(
[n_input, n_internal, n_output, genome], r
) {
const expand_index = Math.floor(n_internal * r) + n_input;
const new_genome = genome.map(([source, sink, weight]) => [
source >= expand_index ? source+1 : source,
sink >= expand_index ? sink+1 : sink,
weight,
]);
return [
n_input, n_internal+1, n_output, new_genome,
];
}
|