-1

So I've been trying to implement a NEAT algorithm in JS, but I'm missing something because when I try to mutate the genomes in my population, they all come out with the same mutation, as in they behave as complete clones, every single genome is the same at the end. Not sure why the array of glasses seems to share connections and nodes when they each have been declared as a new object, I'm definitely missing something I just do not know what, here's the code:

    let startingNode = [];

      let inNode1 = new Node("INPUT", 0)
      let inNode2 = new Node("INPUT", 0)
      let outNode1 = new Node("OUTPUT", 100000)

      startingNode.push(inNode1);
      startingNode.push(inNode2);
      startingNode.push(outNode1);

      let startingGenome = new Genome([], startingNode);

      let population = new Population(20, startingGenome);    



class Population {

          constructor(populationSize, startingGenome) {

            this.populationSize = populationSize;
            this.population = [];

            let genomeThings = startingGenome.copyGenome();

            while (this.population.length < this.populationSize) {
              this.population.push(new Genome(genomeThings.connections, genomeThings.nodes));
            }

            this.mutate();
            console.log(this.population);

          }

          mutate() {

            for (let genome of this.population) {
              if (Math.random() < MUTATION_RATE) {
              `genome.weightMutation()
              }
            }

          }

    class Genome {

      constructor(connections, nodes) {
        this.connections = connections;
        this.nodes = nodes;
      }

      copyGenome() {
        return {connections: this.connections, nodes: this.nodes};
      }
John Costa
  • 11
  • 1
  • 2
  • 2
    @Carcigenicate it is probably copying fine, but `genomeThings.connections` and `genomeThings.nodes` is shared between all the instances of `Genome` pushed into `this.population` – Patrick Roberts Apr 12 '20 at 20:01
  • I wanted that to happen at the start to create equal genomes but what I don't get is why they stay the same after mutating, why are the mutations shared? – John Costa Apr 12 '20 at 20:09
  • Move `let genomeThings = startingGenome.copyGenome();` _into_ the `while` loop above `this.population.push(...);` – Patrick Roberts Apr 12 '20 at 20:10
  • Did it, but its still the same – John Costa Apr 12 '20 at 20:18
  • `copyGenome()` probably isn't correctly implemented then. Feel free to [edit] your question and provide a [mcve]. – Patrick Roberts Apr 12 '20 at 20:29
  • Okay still a little long winded but its the absolute basics of my solution – John Costa Apr 12 '20 at 20:35
  • It looks like your `genome.weightMutation()` is mutating the `this.connections` array. However, all your Genome instances share the same array instance, and modify that shared instance. Have your `copyGenome()` method create copies of the arrays, like `return {connections: this.connections.slice(), nodes: this.nodes.slice()};` – Bergi Apr 12 '20 at 21:16

1 Answers1

0

After visiting a similar question: How do I correctly clone a JavaScript object?

I realised the clone method was wrong and was copying the objects in the wrong way (I don't understand enough about it to explain it really). But after creating an empty genome, and individually pushing each connection and node I managed to get it so the connections and nodes in seperate genomes no longer comflict with each other, if anyone knows precisely why this happens I would love to know.

  copyGenome() {
    let clonedGenome = new Genome([], []);

    for (let x = 0; x < this.connections.length; x++) {
      clonedGenome.connections.push(this.connections[x]);
    }

    for (let x = 0; x < this.nodes.length; x++) {
      clonedGenome.nodes.push(this.nodes[x]);
    }

    return clonedGenome;
  }
John Costa
  • 11
  • 1
  • 2