Esempio n. 1
0
        /// <summary>
        /// A private recursive method which builds a FULL-style tree for NewRootedTree(...)
        /// </summary>
        protected internal virtual GPNode FullNode(IEvolutionState state, int current, int max, GPType type, int thread,
                                                   IGPNodeParent parent, int argPosition, GPFunctionSet funcs)
        {
            // fullNode 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 "FULL" 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.
            var triedTerminals = false; // did we try -- and fail -- to fetch a terminal?

            var t            = type.Type;
            var terminals    = funcs.Terminals[t];
            var nonterminals = funcs.Nonterminals[t];
            var nodes        = funcs.Nodes[t];

            if (nodes.Length == 0)
            {
                ErrorAboutNoNodeWithType(type, state); // total failure
            }
            // pick a terminal when we're at max depth or if there are NO nonterminals
            if ((current + 1 >= max || WarnAboutNonterminal(nonterminals.Length == 0, type, false, state))
                // this will freak out the static checkers
                && (triedTerminals = true) &&                                  // [first set triedTerminals]
                terminals.Length != 0)                                         // AND if there are available terminals
            {
                var n = terminals[state.Random[thread].NextInt(terminals.Length)].LightClone();
                n.ResetNode(state, thread); // give ERCs a chance to randomize
                n.ArgPosition = (sbyte)argPosition;
                n.Parent      = parent;
                return(n);
            }
            // else force a nonterminal unless we have no choice
            else
            {
                if (triedTerminals)
                {
                    WarnAboutNoTerminalWithType(type, false, state); // we tried terminals and we're here because there were none!
                }
                var nodesToPick = funcs.Nonterminals[type.Type];
                if (nodesToPick == null || nodesToPick.Length == 0)
                {
                    // no nonterminals, hope the guy knows what he's doing!
                    nodesToPick = funcs.Terminals[type.Type]; // this can only happen with the warning about nonterminals above
                }
                var n = nodesToPick[state.Random[thread].NextInt(nodesToPick.Length)].LightClone();
                n.ResetNode(state, thread); // give ERCs a chance to randomize
                n.ArgPosition = (sbyte)argPosition;
                n.Parent      = parent;

                // Populate the node...
                var childtypes = n.Constraints(((GPInitializer)state.Initializer)).ChildTypes;
                for (var x = 0; x < childtypes.Length; x++)
                {
                    n.Children[x] = FullNode(state, current + 1, max, childtypes[x], thread, n, x, funcs);
                }

                return(n);
            }
        }
Esempio n. 2
0
        public override GPNode NewRootedTree(IEvolutionState state,
                                             GPType type,
                                             int thread,
                                             IGPNodeParent parent,
                                             GPFunctionSet set,
                                             int argPosition,
                                             int requestedSize)
        {
            int t = type.Type;

            GPNode[] terminals    = set.Terminals[t];
            GPNode[] nonterminals = set.Nonterminals[t];

            if (requestedSize == NOSIZEGIVEN)
            {
                requestedSize = PickSize(state, thread);
            }

            GPNode n;

            if (requestedSize == 1)
            {
                // pick a random terminal
                n = terminals[state.Random[thread].NextInt(terminals.Length)].LightClone();
            }
            else
            {
                n = nonterminals[state.Random[thread].NextInt(nonterminals.Length)]
                    .LightClone(); // it's always going to be the Dummy

                // do decomposition
                byte           pos  = 0;                   // THIS WILL HAVE TO BE MODIFIED TO AN INT LATER ON AND THIS WILL AFFECT ARGPOSITIONS!!!
                IList <GPNode> list = new List <GPNode>(); // dunno if this is too expensive

                while (requestedSize >= 1)
                {
                    int amount = state.Random[thread].NextInt(requestedSize) + 1;
                    requestedSize -= amount;
                    GPNode f = NewRootedTree(state, type, thread, parent, set, pos, amount);
                    list.Add(f);
                }

                // shuffle and reassign argument position
                n.Children = list.ToArray();
                n.Children = Shuffle(n.Children, state, thread);

                for (int i = 0; i < n.Children.Length; i++)
                {
                    n.Children[i].ArgPosition = (byte)i;
                }
            }

            n.ResetNode(state, thread); // give ERCs a chance to randomize
            n.ArgPosition = (byte)argPosition;
            n.Parent      = parent;

            return(n);
        }
        /// <summary>
        /// Returns true if inner1 and inner2 do not contain one another
        /// </summary>
        private static bool NoContainment(GPNode inner1, GPNode inner2)
        {
            IGPNodeParent current = inner1;

            while (current != null && current is GPNode)
            {
                if (current == inner2)
                {
                    return(false); // inner2 contains inner1
                }
                current = ((GPNode)current).Parent;
            }
            current = inner2;
            while (current != null && current is GPNode)
            {
                if (current == inner1)
                {
                    return(false); // inner1 contains inner2
                }
                current = ((GPNode)current).Parent;
            }
            return(true);
        }
Esempio n. 4
0
 public override GPNode NewRootedTree(IEvolutionState state, GPType type, int thread, IGPNodeParent parent,
                                      GPFunctionSet funcs, int argPosition, int requestedSize)
 {
     return(FullNode(state, 0, state.Random[thread].NextInt(MaxDepth - MinDepth + 1) + MinDepth, type, thread, parent, argPosition, funcs));
 }
Esempio n. 5
0
        /// <summary>
        /// A private function which recursively returns a GROW tree to NewRootedTree(...)
        /// </summary>
        private GPNode Ptc1(IEvolutionState state, int current, GPType type, int thread, IGPNodeParent parent,
                            int argPosition, GPFunctionSet funcs, IPTCFunctionSet pfuncs, double[] nonterminalSelectProbs)
        {
            // ptc1 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 PTC1 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.
            var triedTerminals = false;

            var t            = type.Type;
            var terminals    = funcs.Terminals[t];
            var nonterminals = funcs.Nonterminals[t];
            var nodes        = funcs.Nodes[t];

            if (nodes.Length == 0)
            {
                ErrorAboutNoNodeWithType(type, state); // total failure
            }
            // Now pick if we're at max depth
            // OR if we're below p_y
            // OR if there are NO nonterminals!
            // [first set triedTerminals]
            // AND if there are available terminals
            if (((current + 1 >= MaxDepth) ||
                 !(state.Random[thread].NextBoolean(nonterminalSelectProbs[t])) ||
                 WarnAboutNonterminal(nonterminals.Length == 0, type, false, state)) &&
                (triedTerminals = true) && terminals.Length != 0)
            {
                var n = terminals[RandomChoice.PickFromDistribution(pfuncs.TerminalProbabilities(t),
                                                                    state.Random[thread].NextDouble())].LightClone();

                n.ResetNode(state, thread); // give ERCs a chance to randomize
                n.ArgPosition = (sbyte)argPosition;
                n.Parent      = parent;
                return(n);
            }
            // above p_y, pick a nonterminal by q_ny probabilities
            else
            {
                if (triedTerminals)
                {
                    WarnAboutNoTerminalWithType(type, false, state); // we tried terminals and we're here because there were none!
                }
                var n = nonterminals[RandomChoice.PickFromDistribution(pfuncs.NonterminalProbabilities(t),
                                                                       state.Random[thread].NextDouble())].LightClone();

                n.ResetNode(state, thread); // give ERCs a chance to randomize
                n.ArgPosition = (sbyte)argPosition;
                n.Parent      = parent;

                // Populate the node...
                var childtypes = n.Constraints((GPInitializer)state.Initializer).ChildTypes;
                for (var x = 0; x < childtypes.Length; x++)
                {
                    n.Children[x] = Ptc1(state, current + 1, childtypes[x], thread, n, x, funcs, pfuncs, nonterminalSelectProbs);
                }

                return(n);
            }
        }
Esempio n. 6
0
        public override GPNode NewRootedTree(IEvolutionState state, GPType type, int thread, IGPNodeParent parent, GPFunctionSet funcs, int ArgPosition, int requestedSize)
        {
            if (!(funcs is IPTCFunctionSet))
            {
                state.Output.Fatal("Set " + funcs.Name + " is not of the form ec.gp.build.IPTCFunctionSet, and so cannot be used with PTC Nodebuilders.");
            }

            // build the tree
            if (requestedSize == NOSIZEGIVEN) // use the default
            {
                return(Ptc1(state, 0, type, thread, parent, ArgPosition, funcs, (IPTCFunctionSet)funcs, ((IPTCFunctionSet)funcs).NonterminalSelectionProbabilities(ExpectedSize)));
            }
            if (requestedSize < 1)
            {
                state.Output.Fatal("ec.gp.build.PTC1 was requested to build a tree, but a requested size was given that is < 1.");
            }
            return(Ptc1(state, 0, type, thread, parent, ArgPosition, funcs, (IPTCFunctionSet)funcs,
                        ((IPTCFunctionSet)funcs).NonterminalSelectionProbabilities(requestedSize)));
        }
Esempio n. 7
0
 /// <summary>
 /// Produces a new rooted tree of GPNodes whose root's return type is
 /// swap-compatible with <i>type</i>.  When you build a brand-new
 /// tree out of GPNodes cloned from the
 /// prototypes stored in the GPNode[] arrays, you must remember
 /// to call resetNode() on each cloned GPNode.  This gives ERCs a chance
 /// to randomize themselves and set themselves up.
 /// <p/>requestedSize is an
 /// optional argument which differs based on the GPNodeBuilder used.
 /// Typically it is set to a tree size that the calling method wants
 /// the GPNodeBuilder to produce; the GPNodeBuilder is not obligated to
 /// produce a tree of this size, but it should attempt to interpret this
 /// argument as appropriate for the given algorithm.  To indicate that
 /// you don't care what size the tree should be, you can pass NOSIZEGIVEN.
 /// However if the algorithm <i>requires</i> you to provide a size, it
 /// will generate a fatal error to let you know.
 /// </summary>
 public abstract GPNode NewRootedTree(IEvolutionState state, GPType type, int thread,
                                      IGPNodeParent parent, GPFunctionSet funcs, int argPosition, int requestedSize);
Esempio n. 8
0
        public override GPNode NewRootedTree(IEvolutionState state, GPType type, int thread,
                                             IGPNodeParent parent, GPFunctionSet funcs, 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.
            var triedTerminals = false;

            if (!(funcs is IPTCFunctionSet))
            {
                state.Output.Fatal("Set " + funcs.Name
                                   + " is not of the class ec.gp.build.IPTCFunctionSet, and so cannot be used with PTC Nodebuilders.");
            }

            var pfuncs = (IPTCFunctionSet)funcs;

            // pick a size from the distribution
            if (requestedSize == NOSIZEGIVEN)
            {
                requestedSize = PickSize(state, thread);
            }

            GPNode root;

            var t            = type.Type;
            var terminals    = funcs.Terminals[t];
            var nonterminals = funcs.Nonterminals[t];
            var nodes        = funcs.Nodes[t];

            if (nodes.Length == 0)
            {
                ErrorAboutNoNodeWithType(type, state); // total failure
            }
            // return a terminal
            // Now pick a terminal if our size is 1
            // OR if there are NO nonterminals!
            // [first set triedTerminals]
            // AND if there are available terminals
            if ((requestedSize == 1 || WarnAboutNonterminal(nonterminals.Length == 0, type, false, state)) &&
                (triedTerminals = true) && terminals.Length != 0)
            {
                root = terminals[RandomChoice.PickFromDistribution(pfuncs.TerminalProbabilities(t),
                                                                   state.Random[thread].NextDouble())].LightClone();

                root.ResetNode(state, thread); // give ERCs a chance to randomize
                root.ArgPosition = (sbyte)argPosition;
                root.Parent      = parent;
            }
            // return a nonterminal-rooted tree
            else
            {
                if (triedTerminals)
                {
                    WarnAboutNoTerminalWithType(type, false, state); // we tried terminals and we're here because there were none!
                }
                // pick a nonterminal
                root = nonterminals[RandomChoice.PickFromDistribution(pfuncs.NonterminalProbabilities(t),
                                                                      state.Random[thread].NextDouble())].LightClone();

                root.ResetNode(state, thread); // give ERCs a chance to randomize
                root.ArgPosition = (sbyte)argPosition;
                root.Parent      = parent;

                // set the depth, size, and enqueuing, and reset the random dequeue

                s_size = 0; // pretty critical!
                var s           = 1;
                var initializer = ((GPInitializer)state.Initializer);
                var childtypes  = root.Constraints(initializer).ChildTypes;

                for (var x = 0; x < childtypes.Length; x++)
                {
                    Enqueue(root, x, 1); /* depth 1 */
                }
                while (s_size > 0)
                {
                    triedTerminals = false;
                    RandomDequeue(state, thread);
                    type = DequeueNode.Constraints(initializer).ChildTypes[DequeueArgpos];

                    var y = type.Type;
                    terminals    = funcs.Terminals[y];
                    nonterminals = funcs.Nonterminals[y];
                    nodes        = funcs.Nodes[y];

                    if (nodes.Length == 0)
                    {
                        ErrorAboutNoNodeWithType(type, state); // total failure
                    }
                    // pick a terminal
                    // if we need no nonterminal nodes
                    // OR if we're at max depth and must pick a terminal
                    // OR if there are NO nonterminals!
                    // [first set triedTerminals]
                    // AND if there are available terminals
                    if ((s_size + s >= requestedSize || DequeueDepth == MaxDepth ||
                         WarnAboutNonterminal(nonterminals.Length == 0, type, false, state)) &&
                        (triedTerminals = true) && terminals.Length != 0)
                    {
                        var n = terminals[RandomChoice.PickFromDistribution(pfuncs.TerminalProbabilities(y),
                                                                            state.Random[thread].NextDouble())].LightClone();

                        DequeueNode.Children[DequeueArgpos] = n;
                        n.ResetNode(state, thread); // give ERCs a chance to randomize
                        n.ArgPosition = (sbyte)DequeueArgpos;
                        n.Parent      = DequeueNode;
                    }
                    // 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!
                        }
                        var n = nonterminals[RandomChoice.PickFromDistribution(pfuncs.NonterminalProbabilities(y),
                                                                               state.Random[thread].NextDouble())].LightClone();

                        DequeueNode.Children[DequeueArgpos] = n;
                        n.ResetNode(state, thread); // give ERCs a chance to randomize
                        n.ArgPosition = (sbyte)DequeueArgpos;
                        n.Parent      = DequeueNode;

                        childtypes = n.Constraints(initializer).ChildTypes;
                        for (var x = 0; x < childtypes.Length; x++)
                        {
                            Enqueue(n, x, DequeueDepth + 1);
                        }
                    }
                    s++;
                }
            }

            return(root);
        }
Esempio n. 9
0
        GPNode MakeSubtree(IList <int> index, IList <int> genome,
                           IEvolutionState es, GPFunctionSet gpfs, GrammarRuleNode rule,
                           int treeNum, int threadNum, IDictionary <int, GPNode> ercMapsForFancyPrint, IGPNodeParent parent, byte argPosition)
        {
            //have we exceeded the length of the genome?  No point in going further.
            if (index[0] >= genome.Count)
            {
                throw new BigTreeException();
            }

            //expand the rule with the chromosome to get a body element
            int i;

            //non existant rule got passed in
            if (rule == null)
            {
                es.Output.Fatal("An undefined rule exists within the grammar.");
            }

            //more than one rule to consider, pick one based off the genome, and consume the current gene
            // avoid mod operation as much as possible
            if (rule.GetNumChoices() > 1)
            {
                i = (genome[index[0]] - (int)GetMinGene(index[0])) % rule.GetNumChoices();
            }
            else
            {
                i = 0;
            }
            index[0]++;
            GrammarNode choice = rule.GetChoice(i);

            // if body is another rule head
            //look up rule
            if (choice is GrammarRuleNode)
            {
                var nextrule = (GrammarRuleNode)choice;
                return(MakeSubtree(index, genome, es, gpfs, nextrule,
                                   treeNum, threadNum, ercMapsForFancyPrint, parent, argPosition));
            }
            else //handle functions
            {
                GrammarFunctionNode funcgrammarnode = (GrammarFunctionNode)choice;

                GPNode validNode = funcgrammarnode.GetGPNodePrototype();

                int numChildren = validNode.Children.Length;
                //index 0 is the node itself
                int numChildrenInGrammar = funcgrammarnode.GetNumArguments();

                //does the grammar contain the correct amount of children that the GPNode requires
                if (numChildren != numChildrenInGrammar)
                {
                    es.Output.Fatal("GPNode " + validNode.ToStringForHumans() + " requires "
                                    + numChildren + " children.  "
                                    + numChildrenInGrammar
                                    + " children found in the grammar.");
                }

                //check to see if it is an ERC node
                if (validNode is ERC)
                {
                    // have we exceeded the length of the genome?  No point in going further.
                    if (index[0] >= genome.Count)
                    {
                        throw new BigTreeException();
                    }

                    // ** do we actually need to maintain two vlaues ? key and originalVal ?
                    // ** there is no problem if we use the originalVal for both ERCBank and
                    // ** ercMapsForFancyPrint, moreover, this will also make the reverse-mapping case
                    // ** easier -- khaled

                    // these below two lines are from the original code --
                    // key for ERC hashtable look ups is the current index within the genome.  Consume it.
                    //int key = genome[index[0]] - (int)GetMinGene(index[0]);
                    //int originalVal = genome[index[0]];

                    // this single line is khaled's mod --
                    int genomeVal = genome[index[0]];
                    index[0]++;

                    validNode = ObtainERC(es, genomeVal, threadNum, validNode, ercMapsForFancyPrint);
                }
                //non ERC node
                else
                {
                    validNode = validNode.LightClone();
                }

                //get the rest.
                for (int j = 0, childNumber = 0; j < funcgrammarnode.GetNumArguments(); j++)
                {
                    //get and link children to the current GPNode
                    validNode.Children[childNumber] = MakeSubtree(index, genome, es, gpfs,
                                                                  (GrammarRuleNode)funcgrammarnode.GetArgument(j), treeNum, threadNum,
                                                                  ercMapsForFancyPrint, validNode, (byte)childNumber);

                    if (validNode.Children[childNumber] == null)
                    {
                        return(null);
                    }
                    childNumber++;
                }
                validNode.ArgPosition = argPosition;
                validNode.Parent      = parent;
                return(validNode);
            }
        }
Esempio n. 10
0
        public override GPNode NewRootedTree(IEvolutionState state, GPType type, int thread, IGPNodeParent parent,
                                             GPFunctionSet funcs, int argPosition, int requestedSize)
        {
            var valid = false;

            var treeSize = PickSize(state, thread);

            if (!AritySetupDone)
            {
                SetupArities(state, funcs);
            }

            var temp = new int[Arities.Length];

            Permutations = new List <int[]>();
            Permute(0, temp, treeSize - 1);
            if (Permutations.Count == 0)
            {
                state.Output.Fatal("Not able to build combination of nodes.");
            }
            var scheme = Select(Permutations, treeSize);
            var word   = BuildDyckWord(treeSize, Arities, scheme, state, thread);
            var cycle  = 0;

            while (!valid)
            {
                valid = CheckDyckWord(word);
                if (!valid)
                {
                    word = String.Concat(word.Substring(word.Length - 1, word.Length),
                                         word.Substring(0, word.Length - 1));
                    cycle++;
                    if (cycle >= (treeSize * 2) - 1)
                    {
                        state.Output.Fatal("Not able to find valid permutation for generated Dyck word: " + word);
                    }
                }
            }
            return(BuildTree(state, thread, parent, argPosition, funcs, word));
        }
Esempio n. 11
0
        /// <summary>
        /// This function parses the dyck word and puts random nodes into their slots.
        /// </summary>
        private static GPNode BuildTree(IEvolutionState state, int thread,
                                        IGPNodeParent parent, int argPosition, GPFunctionSet funcs, string dyckWord)
        {
            var s = new List <GPNode>();

            // Parsing dyck word from left to right and building tree
            for (var counter = 0; counter < dyckWord.Length; counter++)
            {
                char nextChar;
                if (counter < dyckWord.Length - 1)
                {
                    nextChar = dyckWord[counter + 1];
                }
                else
                {
                    nextChar = '*';
                }
                if ((nextChar == 'x') || (nextChar == '*'))
                /* terminal node */
                {
                    var nn = funcs.Terminals[0];
                    var n  = nn[state.Random[thread].NextInt(nn.Length)].LightClone();
                    n.ResetNode(state, thread); // give ERCs a chance to randomize
                    s.Add(n);
                }
                else if (nextChar == 'y')
                /* non-terminal */
                {
                    // finding arity of connection
                    var ycount    = 0; /* arity */
                    var nextCharY = (nextChar == 'y');
                    counter++;
                    while ((counter < dyckWord.Length) && (nextCharY))
                    {
                        if (dyckWord[counter] == 'y')
                        {
                            ycount++;
                        }
                        if (counter < dyckWord.Length - 1)
                        {
                            nextCharY = (dyckWord[counter + 1] == 'y');
                        }
                        counter++;
                    }

                    //Arity found.  Now just choose non terminal at random.
                    var nonTerms = funcs.NodesByArity[0][ycount];
                    var nT       = nonTerms[state.Random[thread].NextInt(nonTerms.Length)].LightClone();
                    // Non terminal chosen, now attaching children
                    var childcount = ycount;
                    while (childcount > 0)
                    {
                        childcount--;
                        if (s.Count == 0)
                        {
                            state.Output.Fatal("Stack underflow when building tree.");
                        }
                        var child = Pop(s);
                        child.Parent            = nT;
                        child.ArgPosition       = (sbyte)childcount;
                        nT.Children[childcount] = child;
                    }
                    nT.ArgPosition = 0;
                    nT.Parent      = null;
                    s.Add(nT);
                    if (counter != dyckWord.Length)
                    {
                        counter--;
                    }
                }
            }
            return(Pop(s));
        }
Esempio n. 12
0
        public override GPNode NewRootedTree(IEvolutionState state, GPType type, int thread, IGPNodeParent parent,
                                             GPFunctionSet funcs, int argPosition, int requestedSize)
        {
            var initializer = ((GPInitializer)state.Initializer);

            if (requestedSize == NOSIZEGIVEN)
            // pick from the distribution
            {
                var BOUNDARY = 20; // if we try 20 times and fail, check to see if it's possible to succeed
                var bound    = 0;

                var fset = (int)FunctionSetsHash[funcs];
                var siz  = PickSize(state, thread, fset, type.Type);
                var typ  = type.Type;

                // this code is confusing.  The idea is:
                // if the number of trees of our arbitrarily-picked size is zero, we try BOUNDARY
                // number of times to find a tree which will work, picking new sizes each
                // time.  If we still haven't found anything, we will continue to search
                // for a working tree only if we know for sure that one exists in the distribution.

                var checkState = false; // BRS : Can't call this "checked" as in ECJ because of the compiler keyword
                while (ROOT_D_ZERO[fset][typ][siz])
                {
                    if (++bound == BOUNDARY)
                    {
                        if (!checkState)
                        {
                            checkState = true;
                            for (var x = 0; x < ROOT_D_ZERO[fset][typ].Length; x++)
                            {
                                if (!ROOT_D_ZERO[fset][typ][x])
                                {
                                    goto check_brk; // BRS : TODO : This is different from ECJ "break check;" Is it equivalent?
                                } // found a non-zero
                            }
                            // uh oh, we're all zeroes
                            state.Output.Fatal("ec.gp.build.Uniform was asked to build a tree with functionset " + funcs
                                               + " rooted with type " + type + ", but cannot because for some reason there are no trees"
                                               + " of any valid size (within the specified size range) which exist for this function set and type.");
                        }
                        check_brk :;
                    }
                    siz = PickSize(state, thread, fset, typ);
                }

                // okay, now we have a valid size.
                var n = CreateTreeOfType(state, thread, initializer, fset, typ, siz, state.Random[thread]);
                n.Parent      = parent;
                n.ArgPosition = (sbyte)argPosition;
                return(n);
            }
            else if (requestedSize < 1)
            {
                state.Output.Fatal("ec.gp.build.Uniform requested to build a tree, but a requested size was given that is < 1.");
                return(null); // never happens
            }
            else
            {
                var fset = (int)FunctionSetsHash[funcs];
                var typ  = type.Type;
                var siz  = requestedSize;

                // if the number of trees of the requested size is zero, we first march up until we
                // find a tree size with non-zero numbers of trees.  Failing that, we march down to
                // find one.  If that still fails, we issue an error.  Otherwise we use the size
                // we discovered.

                if (ROOT_D_ZERO[fset][typ][siz])
                {
                    // march up
                    for (var x = siz + 1; x < ROOT_D_ZERO[fset][typ].Length; x++)
                    {
                        if (ROOT_D_ZERO[fset][typ][siz])
                        {
                            siz = x;
                            goto determineSize_brk;
                        }
                    }
                    // march down
                    for (var x = siz - 1; x >= 0; x--)
                    {
                        if (ROOT_D_ZERO[fset][typ][siz])
                        {
                            siz = x;
                            goto determineSize_brk;
                        }
                    }
                    // issue an error
                    state.Output.Fatal("ec.gp.build.Uniform was asked to build a tree with functionset " + funcs + " rooted with type "
                                       + type + ", and of size " + requestedSize + ", but cannot because for some reason there are no trees of any"
                                       + " valid size (within the specified size range) which exist for this function set and type.");
                }

                determineSize_brk :;


                var n = CreateTreeOfType(state, thread, initializer, fset, typ, siz, state.Random[thread]);
                n.Parent      = parent;
                n.ArgPosition = (sbyte)argPosition;
                return(n);
            }
        }
Esempio n. 13
0
        private GPNode randomBranch(IEvolutionState state, GPType type, int maxLength, int thread, IGPNodeParent parent, int argPosition, GPFunctionSet funcs)
        {
            // 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.
            var triedTerminals = false;

            var t            = type.Type;
            var terminals    = funcs.Terminals[t];
            var nonterminals = funcs.Nonterminals[t];
            var nodes        = funcs.Nodes[t];

            if (nodes.Length == 0)
            {
                ErrorAboutNoNodeWithType(type, state); // total failure
            }
            // if the desired length is 1
            // OR if there are NO nonterminals!
            // [first set triedTerminals]
            // AND if there are available terminals
            if ((maxLength == 1 || WarnAboutNonterminal(nonterminals.Length == 0, type, false, state))
                // this will freak out the static checkers
                && (triedTerminals = true) &&
                terminals.Length != 0)
            {
                var n = terminals[state.Random[thread].NextInt(terminals.Length)].LightClone();
                n.ResetNode(state, thread); // give ERCs a chance to randomize
                n.ArgPosition = (sbyte)argPosition;
                n.Parent      = parent;
                return(n);
            }

            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
            var len = funcs.NonterminalsUnderArity[type.Type].Length - 1;

            if (len > maxLength - 1)
            {
                len = maxLength - 1;
            }
            var okayNonterms = funcs.NonterminalsUnderArity[type.Type][len];

            if (okayNonterms.Length == 0)
            // no nodes, pick a terminal
            {
                if (terminals.Length == 0)
                {
                    ErrorAboutNoNodeWithType(type, state); // total failure
                }
                var n = terminals[state.Random[thread].NextInt(terminals.Length)].LightClone();
                n.ResetNode(state, thread); // give ERCs a chance to randomize
                n.ArgPosition = (sbyte)argPosition;
                n.Parent      = parent;
                return(n);
            }
            // we've got nonterminals, pick one at random
            else
            {
                var n = okayNonterms[state.Random[thread].NextInt(okayNonterms.Length)].LightClone();
                n.ResetNode(state, thread); // give ERCs a chance to randomize
                n.ArgPosition = (sbyte)argPosition;
                n.Parent      = parent;

                // Populate the node...
                var childtypes = n.Constraints((GPInitializer)state.Initializer).ChildTypes;
                for (var x = 0; x < childtypes.Length; x++)
                {
                    n.Children[x] = randomBranch(state, childtypes[x], (maxLength - 1) / childtypes.Length, thread, n, x, funcs);
                }
                return(n);
            }
        }
Esempio n. 14
0
 public override GPNode NewRootedTree(IEvolutionState state, GPType type, int thread, IGPNodeParent parent,
                                      GPFunctionSet funcs, int argPosition, int requestedSize)
 {
     if (requestedSize == NOSIZEGIVEN)
     {
         // pick from the distribution
         return(randomBranch(state, type, PickSize(state, thread), thread, parent, argPosition, funcs));
     }
     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, funcs));
 }