/** 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()); } }
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); }
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; }