/*
  Copyright 2006 by Sean Luke
  Licensed under the Academic Free License version 3.0
  See the file "LICENSE" for more information
*/


package ec.gp.build;
import ec.gp.*;
import ec.*;
import ec.util.*;

/* 
 * RandomBranch.java
 * 
 * Created: Mon Dec 13 14:26:02 1999
 * By: Sean Luke
 */

/**
 * RandomBranch implements the Random_Branch tree generation
 * method described in 
 *
 * 

Chellapilla, K. 1998. Evolving Modular Programs without Crossover. * in Proceedings of the Third Annual Genetic Programming Conference * (GP98), J.R. Koza et al, editors. San Fransisco: Morgan Kaufmann. * 23--31. * *

This algorithm attempts to create a tree of size requestedSize, * or "slightly less". * * If the pipeline does not specify a size it wants (it uses NOSIZEGIVEN), * the algorithm picks a size at random from either [minSize...maxSize] or from * sizeDistribution (one of the two must be defined), and attempts to create * a tree of that size or "slightly less". * * @author Sean Luke * @version 1.0 */ public class RandomBranch extends GPNodeBuilder { public static final String P_RANDOMBRANCH = "random-branch"; public Parameter defaultBase() { return GPBuildDefaults.base().push(P_RANDOMBRANCH); } public void setup(final EvolutionState state, final Parameter base) { super.setup(state,base); // we use size distributions -- did the user specify any? if (!canPick()) state.output.fatal("RandomBranch requires some kind of size distribution set, either with " + P_MINSIZE + "/" + P_MAXSIZE + ", or with " + P_NUMSIZES + ".", base, defaultBase()); } public GPNode newRootedTree(final EvolutionState state, final GPType type, final int thread, final GPNodeParent parent, final GPFunctionSet set, final int argposition, final int requestedSize) { if (requestedSize == NOSIZEGIVEN) // pick from the distribution return randomBranch(state,type,pickSize(state,thread),thread,parent,argposition,set); if (requestedSize < 1) state.output.fatal("ec.gp.build.RandomBranch requested to build a tree, but a requested size was given that is < 1."); return randomBranch(state,type,requestedSize,thread,parent,argposition,set); } private GPNode randomBranch(final EvolutionState state, final GPType type, final int maxLength, final int thread, final GPNodeParent parent, final int argposition, final GPFunctionSet set) { // randomBranch 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 maximum-size contract. 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; 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 if (( maxLength == 1 || // if the desired length is 1 warnAboutNonterminal(nonterminals.length==0, type, false, state)) && // OR if there are NO nonterminals! // this will freak out the static checkers (triedTerminals = true) && // [first set triedTerminals] terminals.length != 0) // AND if there are available terminals { GPNode n = (GPNode)(terminals[state.random[thread].nextInt(terminals.length)].lightClone()); n.resetNode(state,thread); // give ERCs a chance to randomize n.argposition = (byte)argposition; n.parent = parent; return n; } else { if (triedTerminals) warnAboutNoTerminalWithType(type, false, state); // we tried terminals and we're here because there were none! // grab all the nodes whose arity is <= maxlength-1 int len = set.nonterminalsUnderArity[type.type].length-1; if (len > maxLength-1) len = maxLength-1; GPNode[] okayNonterms = set.nonterminalsUnderArity[type.type][len]; if (okayNonterms.length == 0) // no nodes, pick a terminal { if (terminals.length == 0) errorAboutNoNodeWithType(type, state); // total failure GPNode n = (GPNode)(terminals[state.random[thread].nextInt(terminals.length)].lightClone()); n.resetNode(state,thread); // give ERCs a chance to randomize n.argposition = (byte)argposition; n.parent = parent; return n; } else // we've got nonterminals, pick one at random { GPNode n = (GPNode)(okayNonterms[state.random[thread].nextInt(okayNonterms.length)].lightClone()); n.resetNode(state,thread); // give ERCs a chance to randomize n.argposition = (byte)argposition; n.parent = parent; // Populate the node... GPType[] childtypes = n.constraints(((GPInitializer)state.initializer)).childtypes; for(int x=0;x

Ads help maintain this website.