public void eval( int seed, String parent1Expression, String parent2Expression, String offspringExpression) { EncogProgramContext context = new EncogProgramContext(); StandardExtensions.createNumericOperators(context.getFunctions()); // parent 1 EncogProgram parent1 = new EncogProgram(context); parent1.getVariables().setVariable("x", 1); parent1.compileExpression(parent1Expression); // parent 2 EncogProgram parent2 = new EncogProgram(context); parent2.getVariables().setVariable("x", 1); parent2.compileExpression(parent2Expression); // offspring EncogProgram[] offspring = parent1.allocateOffspring(1); EvolutionaryOperator cross = new SubtreeCrossover(); Genome[] parents = {parent1, parent2}; cross.performOperation(new Random(seed), parents, 0, offspring, 0); offspring[0].getVariables().setVariable("x", 1); RenderCommonExpression render = new RenderCommonExpression(); // Assert.assertEquals(offspringExpression,render.render(offspring[0])); }
/** {@inheritDoc} */ @Override public Object call() { boolean success = false; int tries = this.train.getMaxOperationErrors(); do { try { // choose an evolutionary operation (i.e. crossover or a type of // mutation) to use final EvolutionaryOperator opp = this.train.getOperators().pickMaxParents(this.rnd, this.species.getMembers().size()); this.children[0] = null; // prepare for either sexual or asexual reproduction either way, // we // need at least // one parent, which is the first parent. // // Chose the first parent, there must be at least one genome in // this // species this.parents[0] = chooseParent(); // if the number of individuals in this species is only // one then we can only clone and perhaps mutate, otherwise use // the crossover probability to determine if we are to use // sexual reproduction. if (opp.parentsNeeded() > 1) { int numAttempts = 5; this.parents[1] = chooseParent(); while (this.parents[0] == this.parents[1] && numAttempts-- > 0) { this.parents[1] = chooseParent(); } // success, perform crossover if (this.parents[0] != this.parents[1]) { opp.performOperation(this.rnd, this.parents, 0, this.children, 0); } } else { // clone a child (asexual reproduction) opp.performOperation(this.rnd, this.parents, 0, this.children, 0); this.children[0].setPopulation(this.parents[0].getPopulation()); } // process the new child for (Genome child : this.children) { if (child != null) { child.setPopulation(this.parents[0].getPopulation()); if (this.train.getPopulation().getRules().isValid(child)) { child.setBirthGeneration(this.train.getIteration()); this.train.calculateScore(child); if (!this.train.addChild(child)) { return null; } success = true; } } } } catch (EARuntimeError e) { tries--; if (tries < 0) { throw new EncogError( "Could not perform a successful genetic operaton after " + this.train.getMaxOperationErrors() + " tries."); } } catch (final Throwable t) { if (!this.train.getShouldIgnoreExceptions()) { this.train.reportError(t); } } } while (!success); return null; }