private void mutateAddNode(Chromosome mutatee) { double nodeRandVal = nodeRand.nextDouble(); ArrayList nodeLinks; // ArrayList nodes; NEATLinkGene chosen; NEATNodeGene newNode; NEATLinkGene newLower; NEATLinkGene newUpper; int newChromoIdx = mutatee.genes().length; // Gene[] newChromo = new Gene[newChromoIdx + 3]; Gene[] newChromo = new Gene[newChromoIdx + 2]; System.arraycopy(mutatee.genes(), 0, newChromo, 0, newChromoIdx); int linkIdx; if (nodeRandVal < this.pAddNode) { // add a node on an existing enabled connection // find an existing connection to intercept nodeLinks = this.candidateLinks(mutatee.genes(), true); if (nodeLinks.size() > 0) { // ensure there is a link to split linkIdx = nodeRand.nextInt(nodeLinks.size()); chosen = (NEATLinkGene) nodeLinks.get(linkIdx); // disable old link chosen.setEnabled(false); newNode = InnovationDatabase.database().submitNodeInnovation(chosen); // newNode.setBias(MathUtils.nextPlusMinusOne()); newLower = InnovationDatabase.database().submitLinkInnovation(chosen.getFromId(), newNode.id()); newUpper = InnovationDatabase.database().submitLinkInnovation(newNode.id(), chosen.getToId()); // set weights according to Stanley et al's NEAT document newLower.setWeight(1); newUpper.setWeight(chosen.getWeight()); // now update the chromosome with new node and 2 new links newChromo[this.findChosenIndex(chosen, mutatee)] = newNode; // newChromo[newChromoIdx++] = newNode; newChromo[newChromoIdx++] = newLower; newChromo[newChromoIdx] = newUpper; mutatee.updateChromosome(newChromo); } } }
private void mutateAddLink(Chromosome mutatee) { double linkRandVal = linkRand.nextDouble(); NEATNodeGene from; NEATNodeGene to; int rIdx; int i = 0; ArrayList links; ArrayList nodes; Gene[] genes = new Gene[mutatee.size() + 1]; System.arraycopy(mutatee.genes(), 0, genes, 0, mutatee.genes().length); Gene newLink = null; if (linkRandVal < this.pAddLink) { nodes = this.candidateNodes(mutatee.genes()); links = this.candidateLinks(mutatee.genes(), false); // find a new available link while (newLink == null && i < MAX_LINK_ATTEMPTS) { rIdx = linkRand.nextInt(nodes.size()); from = ((NEATNodeGene) nodes.get(rIdx)); rIdx = linkRand.nextInt(nodes.size()); to = ((NEATNodeGene) nodes.get(rIdx)); // TODO Remove if (from.getInnovationNumber() == 2 && to.getInnovationNumber() == 5) { System.out.println("a"); } if (!this.linkIllegal(from, to, links)) { // set it to a random value newLink = InnovationDatabase.database().submitLinkInnovation(from.id(), to.id()); ((NEATLinkGene) newLink).setWeight(MathUtils.nextPlusMinusOne()); // add link between 2 unconnected nodes genes[genes.length - 1] = newLink; mutatee.updateChromosome(genes); } i++; } } }