summaryrefslogtreecommitdiff
path: root/src/genome/genome.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/genome/genome.js')
-rw-r--r--src/genome/genome.js99
1 files changed, 49 insertions, 50 deletions
diff --git a/src/genome/genome.js b/src/genome/genome.js
index 0f7275f..c288d02 100644
--- a/src/genome/genome.js
+++ b/src/genome/genome.js
@@ -3,56 +3,6 @@
import { network } from '../mind/topology';
-export const mutation_type = Object.freeze({
- none: 'none',
- source: 'source',
- sink: 'sink',
- weight: 'weight',
-});
-
-
-// clamp a number in the range [0, infinity)
-function nonneg(x) {
- if (x < 0) {
- return 0;
- } else {
- return x;
- }
-}
-
-
-// mutate a gene
-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 [ nonneg(source-1), sink, weight ];
- } else {
- return [ source+1, sink, weight ];
- }
-
- case mutation_type.sink:
- if (value <= 0.5) {
- return [ source, nonneg(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}'`);
- };
-}
-
-
// 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(
@@ -89,3 +39,52 @@ export function parse_genome(num_input, num_output, genome) {
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),
+ ];
+}