コード例 #1
0
  private void assignNeuronDepth(Gene[] nodeGenes, int depth, Chromosome mutated) {
    int i;
    NEATNodeGene node;
    // ArrayList nodeGenes = this.findOutputNodes(this.candidateNodes(genes));

    for (i = 0; i < nodeGenes.length; i++) {
      node = (NEATNodeGene) nodeGenes[i];
      if (node.getType() == NEATNodeGene.OUTPUT) {
        if (depth == 1) {
          node.setDepth(depth);
          this.assignNeuronDepth(
              this.findSourceNodes(node.id(), mutated.genes()), depth + 1, mutated);
        }
      } else if (node.getType() == NEATNodeGene.HIDDEN) {
        if (node.getDepth() == 0) {
          // we have an unassigned depth
          node.setDepth(depth);
          this.assignNeuronDepth(
              this.findSourceNodes(node.id(), mutated.genes()), depth + 1, mutated);
        }
      } else if (node.getType() == NEATNodeGene.INPUT) {
        node.setDepth(Integer.MAX_VALUE);
      }
    }
  }
コード例 #2
0
  private NEATNodeGene findNode(int id, Gene[] genes) {
    int i = 0;
    Gene gene;
    NEATNodeGene node = null;
    boolean found = false;

    while (i < genes.length && !found) {
      gene = genes[i];
      if (gene instanceof NEATNodeGene) {
        node = (NEATNodeGene) genes[i];
        if (node.id() == id) {
          found = true;
        }
      }
      i++;
    }

    return (node);
  }
コード例 #3
0
  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);
      }
    }
  }
コード例 #4
0
  private Gene[] findOutputNodes(ArrayList nodes) {
    ArrayList outputNodes = new ArrayList();
    Gene[] nodeGenes;
    NEATNodeGene node;
    int i;

    for (i = 0; i < nodes.size(); i++) {
      node = (NEATNodeGene) nodes.get(i);
      if (node.getType() == NEATNodeGene.OUTPUT) {
        outputNodes.add(node);
      }
    }

    nodeGenes = new NEATNodeGene[outputNodes.size()];
    for (i = 0; i < nodeGenes.length; i++) {
      nodeGenes[i] = (NEATNodeGene) outputNodes.get(i);
    }

    return (nodeGenes);
  }
コード例 #5
0
  private boolean linkIllegal(NEATNodeGene from, NEATNodeGene to, ArrayList links) {
    boolean illegal = false;
    int idx = 0;
    NEATLinkGene linkGene;

    if ((to.getType() == NEATNodeGene.INPUT)) {
      illegal = true;
    } else {
      while (!illegal && (idx < links.size())) {
        linkGene = (NEATLinkGene) links.get(idx);
        //				if ((linkGene.getFromId() == from.id() && linkGene.getToId() == to.id()) ||
        // ((to.getDepth() <= from.getDepth()) && !this.recurrencyAllowed)) {
        if ((linkGene.getFromId() == from.id() && linkGene.getToId() == to.id())) {
          illegal = true;
        }
        idx++;
      }
    }

    return (illegal);
  }
コード例 #6
0
  private Gene[] ensureLegalLinks(Gene[] genes) {
    ArrayList links;
    NEATLinkGene link;
    NEATNodeGene from;
    NEATNodeGene to;
    Gene[] newGenes = null;
    ArrayList tmpGenes = new ArrayList();
    int i;

    // only need to prune if recurrency not allowed
    if (!this.recurrencyAllowed) {
      // only return enabled links
      links = this.candidateLinks(genes, false);
      for (i = 0; i < genes.length; i++) {
        if (genes[i] instanceof NEATLinkGene) {
          link = (NEATLinkGene) genes[i];
          from = this.findNode(link.getFromId(), genes);
          to = this.findNode(link.getToId(), genes);
          if (from.getDepth() > to.getDepth()) {
            // not recurrent - so keep
            tmpGenes.add(genes[i]);
          }
        } else {
          tmpGenes.add(genes[i]);
        }
      }
      newGenes = new Gene[tmpGenes.size()];
      for (i = 0; i < newGenes.length; i++) {
        newGenes[i] = (Gene) tmpGenes.get(i);
      }
    } else {
      newGenes = genes;
    }

    return (newGenes);
  }
コード例 #7
0
  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++;
      }
    }
  }
コード例 #8
0
  private Gene mutateNode(NEATNodeGene mutatee) {
    double perturbRandVal = perturbRand.nextDouble();
    double mutateBias = perturbRand.nextDouble();
    NEATNodeGene mutated = mutatee;
    double newSF = mutatee.sigmoidFactor();
    double newBias = mutatee.bias();

    if (perturbRandVal < this.pPerturb) {
      newSF = mutatee.sigmoidFactor() + MathUtils.nextClampedDouble(-perturb, perturb);
      mutated =
          new NEATNodeGene(
              mutated.getInnovationNumber(),
              mutated.id(),
              newSF,
              mutated.getType(),
              mutated.bias());
    }

    if (mutateBias < this.pMutateBias) {
      newBias += MathUtils.nextClampedDouble(-biasPerturb, biasPerturb);
      mutated =
          new NEATNodeGene(
              mutated.getInnovationNumber(),
              mutated.id(),
              mutated.sigmoidFactor(),
              mutated.getType(),
              newBias);
    }

    return (mutated);
  }