Ejemplo n.º 1
0
        /// <summary>
        /// If the argument node has been visited at least T times, the node is expanded by advancing the PositionGenerator (or creating one if it is undefined) and adding the new child to the node.
        /// </summary>
        /// <param name="context">The context of the search.</param>
        /// <param name="node">The node that is to be expanded.</param>
        /// <param name="state">The state to expand from.</param>
        /// <returns>The argument node if it has been visited less than T time, or if no more expansion is possible, otherwise the newly created child node.</returns>
        public TreeSearchNode <P, A> Expand(SearchContext <D, P, A, S, Sol> context, TreeSearchNode <P, A> node, P state)
        {
            // No expansion before T visits, except for the root.
            if (node.Visits < T && !node.IsRoot())
            {
                return(node);
            }

            // Create a position generator if there is not one set in the node yet.
            var positionGenerator = node.PositionGenerator;

            if (positionGenerator == null)
            {
                var expansion = context.Expansion;
                positionGenerator      = expansion.Expand(context, state);
                node.PositionGenerator = positionGenerator;
            }

            // Move the PositionGenerator to the next item, if available (note: PositionGenerator initialises to before the first item).
            if (!positionGenerator.MoveNext())
            {
                return(node);
            }
            var child = new TreeSearchNode <P, A>(positionGenerator.Current);

            node.AddChild(child);
            child.Parent = node;
            return(child);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Selects an Action by using the NaïveSampling method and expands the tree with this action if it is not already present.
        /// </summary>
        /// <param name="context">The current search context.</param>
        /// <param name="node">The node from which to expand the tree.</param>
        /// <param name="gMAB">The global Multi-Armed-Bandit collection.</param>
        /// <param name="endTime">When running on a time budget, this indicates when the search should stop.</param>
        /// <param name="it">The iteration count of the main search.</param>
        /// <returns>A <see cref="TreeSearchNode{S,A}"/> from which represents the selected node for the Simulation phase.</returns>
        private TreeSearchNode <P, A> NaïveSelectAndExpand(SearchContext <D, P, A, S, Sol> context, TreeSearchNode <P, A> node, IDictionary <long, Dictionary <int, LocalArm> > gMAB, DateTime endTime, ref int it)
        {
            // a = NaïveSampling(node.state, node.state.currentPlayer)
            // if `a' leads to a child of `node'
            // then
            //      return SelectAndExpand(node.GetChild(a))
            // else
            //      newNode = Apply(node.state, a)
            //      node.AddChild(newNode, a)
            //      return newNode

            // Find an action through the NaïveSampling process
            var action     = NaïveSampling(context, node.State, gMAB);
            var actionHash = action.GetHashCode();

            // Check if any of the children of the current node have the sampled action as their payload
            var existingChild = node.Children.FirstOrDefault(i => i.PayloadHash == actionHash);

            if (existingChild != null)
            {
                // Move down the tree unless we have reached a terminal node, or are out of time
                if (existingChild.State.IsTerminal() || (Time != Constants.NO_LIMIT_ON_THINKING_TIME && DateTime.Now >= endTime))
                {
                    return(existingChild);
                }
                // Increase the iteration count, since we'll be doing more sampling and simulating
                it++;
                return(NaïveSelectAndExpand(context, existingChild, gMAB, endTime, ref it));
            }

            // If none of the current children on the node have the action as payload, create a new child
            var newState = context.Application.Apply(context, context.Cloner.Clone(node.State), action);
            var newNode  = new TreeSearchNode <P, A>(node, newState, action);

            // Add it to the node's children and return the child
            node.AddChild(newNode);
            return(newNode);
        }