'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; } }