예제 #1
0
  /** Evaluates the argument number in the current context */
  public void evaluate(
      final EvolutionState state,
      final int thread,
      final GPData input,
      final ADFStack stack,
      final GPIndividual individual,
      final Problem problem,
      final int argument) {
    // do I have that many arguments?
    if (argument >= adf.children.length || argument < 0) // uh oh
    {
      individual.printIndividual(state, 0);
      state.output.fatal("Invalid argument number for " + adf.errorInfo());
    }

    // Am I an ADM or an ADF?
    if (adf == null) state.output.fatal("ADF is null for " + adf.errorInfo());
    else if (adf instanceof ADF) // it's an ADF
    arguments[argument].copyTo(input);
    else // it's an ADM
    {
      // get rid of my context temporarily
      if (stack.moveOntoSubstack(1) != 1)
        state.output.fatal("Substack prematurely empty for " + adf.errorInfo());

      // Call the GPNode
      adf.children[argument].eval(state, thread, input, stack, individual, problem);

      // restore my context
      if (stack.moveFromSubstack(1) != 1)
        state.output.fatal("Stack prematurely empty for " + adf.errorInfo());
    }
  }
예제 #2
0
  public void describe(
      final EvolutionState state,
      final Individual ind,
      final int subpopulation,
      final int threadnum,
      final int log) {
    if (ca == null) ca = new CA(CA_WIDTH, NEIGHBORHOOD);

    int[] trial = new int[CA_WIDTH];

    MajorityData input = (MajorityData) (this.input);

    // extract the rule
    ((GPIndividual) ind)
        .trees[0].child.eval(state, threadnum, input, stack, ((GPIndividual) ind), this);

    int[] rule = ca.getRule();
    for (int i = 0; i < 64; i++) rule[i] = (int) (((input.data0) >> i) & 0x1);
    for (int i = 64; i < 128; i++) rule[i] = (int) (((input.data1) >> (i - 64)) & 0x1);
    ca.setRule(rule); // for good measure though it doesn't matter

    // print rule
    String s = "Rule: ";
    for (int i = 0; i < rule.length; i++) s += rule[i];
    state.output.println(s, log);

    double sum = 0;
    for (int i = 0; i < NUM_TESTS; i++) {
      // set up and run the CA
      int result = makeTrial(state, threadnum, trial, RANDOM) ? 1 : 0;
      ca.setVals(trial);
      ca.step(STEPS, true);

      // extract the fitness
      if (all(ca.getVals(), result)) sum++;
    }

    density = (sum / NUM_TESTS);
    state.output.println("Generalization Accuracy: " + density, 1); // stderr
    state.output.println("Generalization Accuracy: " + density, log);
  }
예제 #3
0
  public void evaluate(
      final EvolutionState state,
      final Individual ind,
      final int subpopulation,
      final int threadnum) {
    if (ca == null) ca = new CA(CA_WIDTH, NEIGHBORHOOD);

    // we always reevaluate
    // if (!ind.evaluated)  // don't bother reevaluating
    {
      MajorityData input = (MajorityData) (this.input);

      int sum = 0;

      // extract the rule
      ((GPIndividual) ind)
          .trees[0].child.eval(state, threadnum, input, stack, ((GPIndividual) ind), this);

      int[] rule = ca.getRule();
      for (int i = 0; i < 64; i++) rule[i] = (int) (((input.data0) >> i) & 0x1);
      for (int i = 64; i < 128; i++) rule[i] = (int) (((input.data1) >> (i - 64)) & 0x1);
      ca.setRule(rule); // for good measure though it doesn't matter

      for (int i = 0; i < NUM_TRIALS; i++) {
        // set up and run the CA
        ca.setVals(trials[i]);
        ca.step(STEPS, true);

        // extract the fitness
        if (all(ca.getVals(), majorities[i])) sum++;
      }

      SimpleFitness f = ((SimpleFitness) ind.fitness);
      f.setFitness(state, sum / (double) NUM_TRIALS, (sum == NUM_TRIALS));
      ind.evaluated = true;
    }
  }
  public int produce(
      final int min,
      final int max,
      final int start,
      final int subpopulation,
      final Individual[] inds,
      final EvolutionState state,
      final int thread) {

    // how many individuals should we make?
    int n = typicalIndsProduced();
    if (n < min) n = min;
    if (n > max) n = max;

    // should we bother?
    if (!state.random[thread].nextBoolean(likelihood))
      return reproduce(
          n,
          start,
          subpopulation,
          inds,
          state,
          thread,
          true); // DO produce children from source -- we've not done so already

    GPInitializer initializer = ((GPInitializer) state.initializer);

    for (int q = start; q < n + start; /* no increment */ ) // keep on going until we're filled up
    {
      // grab two individuals from our sources
      if (sources[0] == sources[1]) // grab from the same source
      sources[0].produce(2, 2, 0, subpopulation, parents, state, thread);
      else // grab from different sources
      {
        sources[0].produce(1, 1, 0, subpopulation, parents, state, thread);
        sources[1].produce(1, 1, 1, subpopulation, parents, state, thread);
      }

      // at this point, parents[] contains our two selected individuals

      // are our tree values valid?
      if (tree1 != TREE_UNFIXED && (tree1 < 0 || tree1 >= parents[0].trees.length))
        // uh oh
        state.output.fatal(
            "GP Crossover Pipeline attempted to fix tree.0 to a value which was out of bounds of the array of the individual's trees.  Check the pipeline's fixed tree values -- they may be negative or greater than the number of trees in an individual");
      if (tree2 != TREE_UNFIXED && (tree2 < 0 || tree2 >= parents[1].trees.length))
        // uh oh
        state.output.fatal(
            "GP Crossover Pipeline attempted to fix tree.1 to a value which was out of bounds of the array of the individual's trees.  Check the pipeline's fixed tree values -- they may be negative or greater than the number of trees in an individual");

      int t1 = 0;
      int t2 = 0;
      if (tree1 == TREE_UNFIXED || tree2 == TREE_UNFIXED) {
        do
        // pick random trees  -- their GPTreeConstraints must be the same
        {
          if (tree1 == TREE_UNFIXED)
            if (parents[0].trees.length > 1)
              t1 = state.random[thread].nextInt(parents[0].trees.length);
            else t1 = 0;
          else t1 = tree1;

          if (tree2 == TREE_UNFIXED)
            if (parents[1].trees.length > 1)
              t2 = state.random[thread].nextInt(parents[1].trees.length);
            else t2 = 0;
          else t2 = tree2;
        } while (parents[0].trees[t1].constraints(initializer)
            != parents[1].trees[t2].constraints(initializer));
      } else {
        t1 = tree1;
        t2 = tree2;
        // make sure the constraints are okay
        if (parents[0].trees[t1].constraints(initializer)
            != parents[1].trees[t2].constraints(initializer)) // uh oh
        state.output.fatal(
              "GP Crossover Pipeline's two tree choices are both specified by the user -- but their GPTreeConstraints are not the same");
      }

      // validity results...
      boolean res1 = false;
      boolean res2 = false;

      // prepare the nodeselectors
      nodeselect1.reset();
      nodeselect2.reset();

      // pick some nodes

      GPNode p1 = null;
      GPNode p2 = null;

      for (int x = 0; x < numTries; x++) {
        // pick a node in individual 1
        p1 = nodeselect1.pickNode(state, subpopulation, thread, parents[0], parents[0].trees[t1]);

        // pick a node in individual 2
        p2 = nodeselect2.pickNode(state, subpopulation, thread, parents[1], parents[1].trees[t2]);

        // check for depth and swap-compatibility limits
        res1 = verifyPoints(initializer, p2, p1); // p2 can fill p1's spot -- order is important!
        if (n - (q - start) < 2 || tossSecondParent) res2 = true;
        else
          res2 = verifyPoints(initializer, p1, p2); // p1 can fill p2's spot -- order is important!

        // did we get something that had both nodes verified?
        // we reject if EITHER of them is invalid.  This is what lil-gp does.
        // Koza only has numTries set to 1, so it's compatible as well.
        if (res1 && res2) break;
      }

      // at this point, res1 AND res2 are valid, OR either res1
      // OR res2 is valid and we ran out of tries, OR neither is
      // valid and we ran out of tries.  So now we will transfer
      // to a tree which has res1 or res2 valid, otherwise it'll
      // just get replicated.  This is compatible with both Koza
      // and lil-gp.

      // at this point I could check to see if my sources were breeding
      // pipelines -- but I'm too lazy to write that code (it's a little
      // complicated) to just swap one individual over or both over,
      // -- it might still entail some copying.  Perhaps in the future.
      // It would make things faster perhaps, not requiring all that
      // cloning.

      // Create some new individuals based on the old ones -- since
      // GPTree doesn't deep-clone, this should be just fine.  Perhaps we
      // should change this to proto off of the main species prototype, but
      // we have to then copy so much stuff over; it's not worth it.

      GPIndividual j1 = (GPIndividual) (parents[0].lightClone());
      GPIndividual j2 = null;
      if (n - (q - start) >= 2 && !tossSecondParent) j2 = (GPIndividual) (parents[1].lightClone());

      // Fill in various tree information that didn't get filled in there
      j1.trees = new GPTree[parents[0].trees.length];
      if (n - (q - start) >= 2 && !tossSecondParent) j2.trees = new GPTree[parents[1].trees.length];

      // at this point, p1 or p2, or both, may be null.
      // If not, swap one in.  Else just copy the parent.

      for (int x = 0; x < j1.trees.length; x++) {
        if (x == t1 && res1) // we've got a tree with a kicking cross position!
        {
          j1.trees[x] = (GPTree) (parents[0].trees[x].lightClone());
          j1.trees[x].owner = j1;
          j1.trees[x].child = parents[0].trees[x].child.cloneReplacing(p2, p1);
          j1.trees[x].child.parent = j1.trees[x];
          j1.trees[x].child.argposition = 0;
          j1.evaluated = false;
        } // it's changed
        else {
          j1.trees[x] = (GPTree) (parents[0].trees[x].lightClone());
          j1.trees[x].owner = j1;
          j1.trees[x].child = (GPNode) (parents[0].trees[x].child.clone());
          j1.trees[x].child.parent = j1.trees[x];
          j1.trees[x].child.argposition = 0;
        }
      }

      if (n - (q - start) >= 2 && !tossSecondParent)
        for (int x = 0; x < j2.trees.length; x++) {
          if (x == t2 && res2) // we've got a tree with a kicking cross position!
          {
            j2.trees[x] = (GPTree) (parents[1].trees[x].lightClone());
            j2.trees[x].owner = j2;
            j2.trees[x].child = parents[1].trees[x].child.cloneReplacing(p1, p2);
            j2.trees[x].child.parent = j2.trees[x];
            j2.trees[x].child.argposition = 0;
            j2.evaluated = false;
          } // it's changed
          else {
            j2.trees[x] = (GPTree) (parents[1].trees[x].lightClone());
            j2.trees[x].owner = j2;
            j2.trees[x].child = (GPNode) (parents[1].trees[x].child.clone());
            j2.trees[x].child.parent = j2.trees[x];
            j2.trees[x].child.argposition = 0;
          }
        }

      // add the individuals to the population
      inds[q] = j1;
      q++;
      if (q < n + start && !tossSecondParent) {
        inds[q] = j2;
        q++;
      }
    }
    return n;
  }
  public int produce(
      final int min,
      final int max,
      final int start,
      final int subpopulation,
      final Individual[] inds,
      final EvolutionState state,
      final int thread) {

    // how many individuals should we make?
    int n = typicalIndsProduced();
    if (n < min) n = min;
    if (n > max) n = max;

    // should we bother?
    if (!state.random[thread].nextBoolean(likelihood))
      return reproduce(
          n,
          start,
          subpopulation,
          inds,
          state,
          thread,
          true); // DO produce children from source -- we've not done so already

    // random select one tree from treelib
    // int treeIndex = (new Random()).nextInt(state.maxTreelibSize);

    // GPNode TR = state.treelib[treeIndex];
    // create tree: 1 - TR
    GPNode OneSubTR = (GPNode) (((GPNode[]) fs.nodesByName.get("-"))[0]).lightClone();
    OneSubTR.children = new GPNode[2];

    RegERC oneNode = new RegERC();
    oneNode.constraints = 6;
    oneNode.children = new GPNode[0];
    oneNode.value = 1;

    OneSubTR.children[0] = oneNode;

    GPInitializer initializer = ((GPInitializer) state.initializer);

    for (int q = start; q < n + start; /* no increment */ ) // keep on going until we're filled up
    {
      // grab two individuals from our sources
      if (sources[0] == sources[1]) // grab from the same source
      sources[0].produce(2, 2, 0, subpopulation, parents, state, thread);
      else // grab from different sources
      {
        sources[0].produce(1, 1, 0, subpopulation, parents, state, thread);
        sources[1].produce(1, 1, 1, subpopulation, parents, state, thread);
      }

      // at this point, parents[] contains our two selected individuals

      // random select one tree from treelib
      int treeIndex = (new Random()).nextInt(state.maxTreelibSize);
      GPNode TR = state.treelib[treeIndex];

      OneSubTR.children[1] = (GPNode) TR.clone();

      double[] randomSemanticTraining = state.semanticTreelibTraining[treeIndex];
      double[] randomSemanticTesting = state.semanticTreelibTesting[treeIndex];

      // are our tree values valid?
      if (tree1 != TREE_UNFIXED && (tree1 < 0 || tree1 >= parents[0].trees.length))
        // uh oh
        state.output.fatal(
            "GP Crossover Pipeline attempted to fix tree.0 to a value which was out of bounds of the array of the individual's trees.  Check the pipeline's fixed tree values -- they may be negative or greater than the number of trees in an individual");
      if (tree2 != TREE_UNFIXED && (tree2 < 0 || tree2 >= parents[1].trees.length))
        // uh oh
        state.output.fatal(
            "GP Crossover Pipeline attempted to fix tree.1 to a value which was out of bounds of the array of the individual's trees.  Check the pipeline's fixed tree values -- they may be negative or greater than the number of trees in an individual");

      int t1 = 0;
      int t2 = 0;
      if (tree1 == TREE_UNFIXED || tree2 == TREE_UNFIXED) {
        do
        // pick random trees  -- their GPTreeConstraints must be the same
        {
          if (tree1 == TREE_UNFIXED)
            if (parents[0].trees.length > 1)
              t1 = state.random[thread].nextInt(parents[0].trees.length);
            else t1 = 0;
          else t1 = tree1;

          if (tree2 == TREE_UNFIXED)
            if (parents[1].trees.length > 1)
              t2 = state.random[thread].nextInt(parents[1].trees.length);
            else t2 = 0;
          else t2 = tree2;
        } while (parents[0].trees[t1].constraints(initializer)
            != parents[1].trees[t2].constraints(initializer));
      } else {
        t1 = tree1;
        t2 = tree2;
        // make sure the constraints are okay
        if (parents[0].trees[t1].constraints(initializer)
            != parents[1].trees[t2].constraints(initializer)) // uh oh
        state.output.fatal(
              "GP Crossover Pipeline's two tree choices are both specified by the user -- but their GPTreeConstraints are not the same");
      }

      // number of crossover
      state.numOfSGX[state.generation][0] += 1;

      GPIndividual child1 = (GPIndividual) (parents[0].lightClone());
      child1.trees[0].semanticTraining = new double[randomSemanticTraining.length];
      child1.trees[0].semanticTesting = new double[randomSemanticTesting.length];

      GPIndividual child2 = null;
      if (n - (q - start) >= 2 && !tossSecondParent) {
        child2 = (GPIndividual) (parents[1].lightClone());
        child2.trees[0].semanticTraining = new double[randomSemanticTraining.length];
        child2.trees[0].semanticTesting = new double[randomSemanticTesting.length];
      }

      // geometric semantic crossover on training set
      for (int i = 0; i < parents[0].trees[0].semanticTraining.length; i++) {
        child1.trees[0].semanticTraining[i] =
            randomSemanticTraining[i] * parents[0].trees[0].semanticTraining[i]
                + (1 - randomSemanticTraining[i]) * parents[1].trees[0].semanticTraining[i];
        child1.evaluated = false;

        if (child2 != null) {
          child2.trees[0].semanticTraining[i] =
              (1 - randomSemanticTraining[i]) * parents[0].trees[0].semanticTraining[i]
                  + randomSemanticTraining[i] * parents[1].trees[0].semanticTraining[i];
          child2.evaluated = false;
        }
      }

      // geometric semantic crossover on testing set
      for (int i = 0; i < parents[0].trees[0].semanticTesting.length; i++) {
        child1.trees[0].semanticTesting[i] =
            randomSemanticTesting[i] * parents[0].trees[0].semanticTesting[i]
                + (1 - randomSemanticTesting[i]) * parents[1].trees[0].semanticTesting[i];

        if (child2 != null) {
          child2.trees[0].semanticTesting[i] =
              (1 - randomSemanticTesting[i]) * parents[0].trees[0].semanticTesting[i]
                  + randomSemanticTesting[i] * parents[1].trees[0].semanticTesting[i];
        }
      }

      // add the individuals to the population
      inds[q] = child1;
      q++;
      if (q < n + start && !tossSecondParent) {
        inds[q] = child2;
        q++;
      }
    }
    return n;
  }