summaryrefslogtreecommitdiff
path: root/src/genome/genome.js
blob: 3445fe98d1c862c4b74d1964afa6c590db60ead7 (plain)
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
'use strict';


export const mutation_type = Object.freeze({
  none: 'none',
  source: 'source',
  sink: 'sink',
  weight: 'weight',
});


function positive(x) {
  if (x < 0) { 
    return 0; 
  } else {
    return x;
  }
}


export function mutate(gene, type, value) {
  const [ source, sink, weight ] = gene;

  switch(type) {
    case mutation_type.none:
      return [...gene];

    case mutation_type.source:
      if (value <= 0.5) {
        return [ positive(source-1), sink, weight ];
      } else {
        return [ source+1, sink, weight ];
      }

    case mutation_type.sink:
      if (value <= 0.5) {
        return [ source, positive(sink-1), weight ];
      } else {
        return [ source, sink+1, weight ];
      }

    case mutation_type.weight:
      const w = (8*value) - 4;
      return [ source, sink, 0.5*(w + weight) ];

    default:
      throw new Error(`unknown mutation type: '${type}'`);
  };
}


export function is_valid(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 false;
  }
  else if (max_weight > 4.0) {
    return false;
  }
  else {
    return true;
  }
}