/*
Copyright 2006 by Sean Luke
Licensed under the Academic Free License version 3.0
See the file "LICENSE" for more information
*/
package ec.gp.breed;
import ec.*;
import ec.util.*;
import ec.gp.*;
/*
* MutateAllNodesPipeline.java
*
* Created: Wed Dec 15 21:41:30 1999
* By: Sean Luke
*/
/**
* MutateAllNodesPipeline implements the AllNodes mutation algorithm described
* in Kumar Chellapilla,
* "A Preliminary Investigation into Evolving Modular Programs without Subtree
* Crossover", GP98.
*
* MutateAllNodesPipeline chooses a subtree and for each node n
* in that subtree, it replaces n with a randomly-picked node of the same
* arity and type constraints. Thus the original topological structure is
* the same but the nodes are different.
*
Typical Number of Individuals Produced Per produce(...) call
...as many as the source produces
Number of Sources
1
Parameters
base.ns.0
classname, inherits and != GPNodeSelector
(GPNodeSelector for tree)
base.tree.0
0 < int < (num trees in individuals), if exists
(tree chosen for mutation; if parameter doesn't exist, tree is picked at random)
Default Base
gp.breed.mutate-all-nodes
Parameter bases
base.ns
The GPNodeSelector selector
* @author Sean Luke
* @version 1.0
*/
public class MutateAllNodesPipeline extends GPBreedingPipeline
{
private static final long serialVersionUID = 1;
public static final String P_MUTATEALLNODES = "mutate-all-nodes";
public static final int NUM_SOURCES = 1;
/** How the pipeline chooses a subtree to mutate */
public GPNodeSelector nodeselect;
/** Is our tree fixed? If not, this is -1 */
int tree;
public Parameter defaultBase()
{
return GPBreedDefaults.base().push(P_MUTATEALLNODES);
}
public int numSources() { return NUM_SOURCES; }
public Object clone()
{
MutateAllNodesPipeline c = (MutateAllNodesPipeline)(super.clone());
// deep-cloned stuff
c.nodeselect = (GPNodeSelector)(nodeselect.clone());
return c;
}
public void setup(final EvolutionState state, final Parameter base)
{
super.setup(state,base);
Parameter def = defaultBase();
Parameter p = base.push(P_NODESELECTOR).push(""+0);
nodeselect = (GPNodeSelector)
(state.parameters.getInstanceForParameter(
p,def.push(P_NODESELECTOR).push(""+0),
GPNodeSelector.class));
nodeselect.setup(state,p);
tree = TREE_UNFIXED;
if (state.parameters.exists(base.push(P_TREE).push(""+0),
def.push(P_TREE).push(""+0)))
{
tree = state.parameters.getInt(base.push(P_TREE).push(""+0),
def.push(P_TREE).push(""+0),0);
if (tree==-1)
state.output.fatal("Tree fixed value, if defined, must be >= 0");
}
}
/** Returns a node which is swap-compatible with returntype, and whose arguments are swap-compatible with the current children of original. You need to clone this node. */
private GPNode pickCompatibleNode(
final GPNode original, final GPFunctionSet set,
final EvolutionState state, final GPType returntype, final int thread)
{
// an expensive procedure: we will linearly search for a valid node
int numValidNodes = 0;
int type = returntype.type;
GPInitializer initializer = ((GPInitializer)state.initializer);
int len = original.constraints(initializer).childtypes.length;
boolean failed;
if (initializer.numAtomicTypes +
initializer.numSetTypes == 1) // easy
numValidNodes = set.nodesByArity[type][len].length;
else for(int x=0;x= i.trees.length))
// uh oh
state.output.fatal("MutateAllNodesPipeline 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");
int t;
// pick random tree
if (tree==TREE_UNFIXED)
if (i.trees.length>1) t = state.random[thread].nextInt(i.trees.length);
else t = 0;
else t = tree;
// prepare the nodeselector
nodeselect.reset();
// pick a node
GPNode p1=null; // the node we pick
GPNode p2=null;
// pick a node in individual 1
p1 = nodeselect.pickNode(state,subpopulation,thread,i,i.trees[t]);
// generate a tree with a new root but the same children,
// which we will replace p1 with
GPType type;
type = p1.parentType(initializer);
p2 = generateCompatibleTree(p1,i.trees[t].constraints(initializer).functionset,state,type,thread);
// we'll need to set p2.argposition and p2.parent further down
GPIndividual j;
if (sources[0] instanceof BreedingPipeline)
// it's already a copy, so just smash the tree in
{
j=i;
p2.parent = p1.parent;
p2.argposition = p1.argposition;
if (p2.parent instanceof GPNode)
((GPNode)(p2.parent)).children[p2.argposition] = p2;
else ((GPTree)(p2.parent)).child = p2;
j.evaluated = false; // we've modified it
}
else // need to copy it in
{
j = (GPIndividual)(i.lightClone());
// Fill in various tree information that didn't get filled in there
j.trees = new GPTree[i.trees.length];
for(int x=0;x
Ads help maintain this website.