private Gene mutateLink(NEATLinkGene mutatee) { double perturbRandVal = perturbRand.nextDouble(); double disableRandVal = disableRand.nextDouble(); double newWeight; NEATLinkGene mutated = mutatee; if (perturbRandVal < this.pPerturb) { if (this.pWeightReplaced > perturbRand.nextDouble()) { newWeight = MathUtils.nextPlusMinusOne(); } else { newWeight = mutatee.getWeight() + MathUtils.nextClampedDouble(-perturb, perturb); } // newWeight = mutatee.getWeight() + MathUtils.nextClampedDouble(-PERTURB, PERTURB); mutated = new NEATLinkGene( mutatee.getInnovationNumber(), mutatee.isEnabled(), mutatee.getFromId(), mutatee.getToId(), newWeight); } if (disableRandVal < this.pToggle) { if (this.featureSelection) { mutated.setEnabled(!mutated.isEnabled()); } } return (mutated); }
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); } } }