/** Returns true if inner1 can feasibly be swapped into inner2's position. */ public boolean verifyPoints( final GPInitializer initializer, final GPNode inner1, final GPNode inner2) { // first check to see if inner1 is swap-compatible with inner2 // on a type basis if (!inner1.swapCompatibleWith(initializer, inner2)) return false; // next check to see if inner1 can fit in inner2's spot if (inner1.depth() + inner2.atDepth() > maxDepth) return false; // check for size // NOTE: this is done twice, which is more costly than it should be. But // on the other hand it allows us to toss a child without testing both times // and it's simpler to have it all here in the verifyPoints code. if (maxSize != NO_SIZE_LIMIT) { // first easy check int inner1size = inner1.numNodes(GPNode.NODESEARCH_ALL); int inner2size = inner2.numNodes(GPNode.NODESEARCH_ALL); if (inner1size > inner2size) // need to test further { // let's keep on going for the more complex test GPNode root2 = ((GPTree) (inner2.rootParent())).child; int root2size = root2.numNodes(GPNode.NODESEARCH_ALL); if (root2size - inner2size + inner1size > maxSize) // take root2, remove inner2 and swap in inner1. Is it still small enough? return false; } } // checks done! return true; }
public void checkConstraints( final EvolutionState state, final int tree, final GPIndividual typicalIndividual, final Parameter individualBase) { super.checkConstraints(state, tree, typicalIndividual, individualBase); if (children.length != 0) state.output.error( "Incorrect number of children for node " + toStringForError() + " at " + individualBase); }
public GPNode newRootedTree( final EvolutionState state, GPType type, final int thread, final GPNodeParent parent, final GPFunctionSet set, final int argposition, int requestedSize) { // ptc2 can mess up if there are no available terminals for a given type. If this occurs, // and we find ourselves unable to pick a terminal when we want to do so, we will issue a // warning, // and pick a nonterminal, violating the ptc2 size and depth contracts. This can lead to // pathological situations // where the system will continue to go on and on unable to stop because it can't pick a // terminal, // resulting in running out of memory or some such. But there are cases where we'd want to let // this work itself out. boolean triedTerminals = false; if (!(set instanceof PTCFunctionSetForm)) state.output.fatal( "Set " + set.name + " is not of the class ec.gp.build.PTCFunctionSetForm, and so cannot be used with PTC Nodebuilders."); PTCFunctionSetForm pset = (PTCFunctionSetForm) set; // pick a size from the distribution if (requestedSize == NOSIZEGIVEN) requestedSize = pickSize(state, thread); GPNode root; int t = type.type; GPNode[] terminals = set.terminals[t]; GPNode[] nonterminals = set.nonterminals[t]; GPNode[] nodes = set.nodes[t]; if (nodes.length == 0) errorAboutNoNodeWithType(type, state); // total failure // return a terminal if ((requestedSize == 1 || // Now pick a terminal if our size is 1 warnAboutNonterminal(nonterminals.length == 0, type, false, state)) && // OR if there are NO nonterminals! (triedTerminals = true) && // [first set triedTerminals] terminals.length != 0) // AND if there are available terminals { root = (GPNode) terminals[ RandomChoice.pickFromDistribution( pset.terminalProbabilities(t), state.random[thread].nextFloat(), CHECK_BOUNDARY)] .lightClone(); root.resetNode(state, thread); // give ERCs a chance to randomize root.argposition = (byte) argposition; root.parent = parent; } else // return a nonterminal-rooted tree { if (triedTerminals) warnAboutNoTerminalWithType( type, false, state); // we tried terminals and we're here because there were none! // pick a nonterminal root = (GPNode) nonterminals[ RandomChoice.pickFromDistribution( pset.nonterminalProbabilities(t), state.random[thread].nextFloat(), CHECK_BOUNDARY)] .lightClone(); root.resetNode(state, thread); // give ERCs a chance to randomize root.argposition = (byte) argposition; root.parent = parent; // set the depth, size, and enqueuing, and reset the random dequeue s_size = 0; // pretty critical! int s = 1; GPInitializer initializer = ((GPInitializer) state.initializer); GPType[] childtypes = root.constraints(initializer).childtypes; for (int x = 0; x < childtypes.length; x++) enqueue(root, x, 1); /* depth 1 */ while (s_size > 0) { triedTerminals = false; randomDequeue(state, thread); type = dequeue_node.constraints(initializer).childtypes[dequeue_argpos]; int y = type.type; terminals = set.terminals[y]; nonterminals = set.nonterminals[y]; nodes = set.nodes[y]; if (nodes.length == 0) errorAboutNoNodeWithType(type, state); // total failure // pick a terminal if ((s_size + s >= requestedSize || // if we need no more nonterminal nodes dequeue_depth == maxDepth || // OR if we're at max depth and must pick a terminal warnAboutNonterminal(nonterminals.length == 0, type, false, state)) && // OR if there are NO nonterminals! (triedTerminals = true) && // [first set triedTerminals] terminals.length != 0) // AND if there are available terminals { GPNode n = (GPNode) terminals[ RandomChoice.pickFromDistribution( pset.terminalProbabilities(y), state.random[thread].nextFloat(), CHECK_BOUNDARY)] .lightClone(); dequeue_node.children[dequeue_argpos] = n; n.resetNode(state, thread); // give ERCs a chance to randomize n.argposition = (byte) dequeue_argpos; n.parent = dequeue_node; } // pick a nonterminal and enqueue its children else { if (triedTerminals) warnAboutNoTerminalWithType( type, false, state); // we tried terminals and we're here because there were none! GPNode n = (GPNode) nonterminals[ RandomChoice.pickFromDistribution( pset.nonterminalProbabilities(y), state.random[thread].nextFloat(), CHECK_BOUNDARY)] .lightClone(); dequeue_node.children[dequeue_argpos] = n; n.resetNode(state, thread); // give ERCs a chance to randomize n.argposition = (byte) dequeue_argpos; n.parent = dequeue_node; childtypes = n.constraints(initializer).childtypes; for (int x = 0; x < childtypes.length; x++) enqueue(n, x, dequeue_depth + 1); } s++; } } return root; }
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; }
public void setup(final EvolutionState state, final Parameter base) { super.setup(state, base); Parameter def = defaultBase(); Parameter p = base.push(P_NODESELECTOR).push("0"); Parameter d = def.push(P_NODESELECTOR).push("0"); nodeselect1 = (GPNodeSelector) (state.parameters.getInstanceForParameter(p, d, GPNodeSelector.class)); nodeselect1.setup(state, p); p = base.push(P_NODESELECTOR).push("1"); d = def.push(P_NODESELECTOR).push("1"); if (state.parameters.exists(p, d) && state.parameters.getString(p, d).equals(V_SAME)) // can't just copy it this time; the selectors // use internal caches. So we have to clone it no matter what nodeselect2 = (GPNodeSelector) (nodeselect1.clone()); else { nodeselect2 = (GPNodeSelector) (state.parameters.getInstanceForParameter(p, d, GPNodeSelector.class)); nodeselect2.setup(state, p); } numTries = state.parameters.getInt(base.push(P_NUM_TRIES), def.push(P_NUM_TRIES), 1); if (numTries == 0) state.output.fatal( "GPCrossover Pipeline has an invalid number of tries (it must be >= 1).", base.push(P_NUM_TRIES), def.push(P_NUM_TRIES)); maxDepth = state.parameters.getInt(base.push(P_MAXDEPTH), def.push(P_MAXDEPTH), 1); if (maxDepth == 0) state.output.fatal( "GPCrossover Pipeline has an invalid maximum depth (it must be >= 1).", base.push(P_MAXDEPTH), def.push(P_MAXDEPTH)); maxSize = NO_SIZE_LIMIT; if (state.parameters.exists(base.push(P_MAXSIZE), def.push(P_MAXSIZE))) { maxSize = state.parameters.getInt(base.push(P_MAXSIZE), def.push(P_MAXSIZE), 1); if (maxSize < 1) state.output.fatal("Maximum tree size, if defined, must be >= 1"); } tree1 = TREE_UNFIXED; if (state.parameters.exists(base.push(P_TREE).push("" + 0), def.push(P_TREE).push("" + 0))) { tree1 = state.parameters.getInt(base.push(P_TREE).push("" + 0), def.push(P_TREE).push("" + 0), 0); if (tree1 == -1) state.output.fatal("Tree fixed value, if defined, must be >= 0"); } tree2 = TREE_UNFIXED; if (state.parameters.exists(base.push(P_TREE).push("" + 1), def.push(P_TREE).push("" + 1))) { tree2 = state.parameters.getInt(base.push(P_TREE).push("" + 1), def.push(P_TREE).push("" + 1), 0); if (tree2 == -1) state.output.fatal("Tree fixed value, if defined, must be >= 0"); } tossSecondParent = state.parameters.getBoolean(base.push(P_TOSS), def.push(P_TOSS), false); GPInitializer initializer = ((GPInitializer) state.initializer); fs = initializer.treeConstraints[0].functionset; templateTree = (GPNode) (((GPNode[]) fs.nodesByName.get("+"))[0]).lightClone(); GPNode left = (GPNode) (((GPNode[]) fs.nodesByName.get("*"))[0]).lightClone(); GPNode right = (GPNode) (((GPNode[]) fs.nodesByName.get("*"))[0]).lightClone(); // RegERC ercNode1 = (RegERC)((((GPNode[])fs.nodesByName.get("ERC"))[0]).lightClone()); // // generate TR node that will be replated by random tree // GPNode TRNode = new GPNode(); // ercNode.constraints = 6; // ercNode.children = new GPNode[0]; templateTree.children = new GPNode[2]; templateTree.children[0] = left; templateTree.children[1] = right; left.children = new GPNode[2]; left.children[0] = null; left.children[1] = null; right.children = new GPNode[2]; right.children[0] = null; right.children[1] = null; }