Example #1
0
        // --------------------------------------------------------------------------------------------
        static void ProcessNode(PositionEvalCache cache, MCTSNode node, float weightEmpirical,
                                bool saveToCache, bool rewriteNodeInTree)
        {
            Span <MCTSNodeStructChild> children = node.Ref.Children;

            // TODO: optimize this away if saveToCache is false
            ushort[] probabilities = new ushort[node.NumPolicyMoves];
            ushort[] indices       = new ushort[node.NumPolicyMoves];

            // Compute empirical visit distribution
            float[] nodeFractions = new float[node.NumPolicyMoves];
            for (int i = 0; i < node.NumChildrenExpanded; i++)
            {
                nodeFractions[i] = (float)node.ChildAtIndex(i).N / (float)node.N;
            }

            // Determine P of first unexpanded node
            // We can't allow any child to have a new P less than this
            // since we need to keep them in order by P and the resorting logic below
            // can only operate over expanded nodes
            float minP = 0;

            if (node.NumChildrenExpanded < node.NumPolicyMoves)
            {
                minP = node.ChildAtIndexInfo(node.NumChildrenExpanded).p;
            }

            // Add each move to the policy vector with blend of prior and empirical values
            for (int i = 0; i < node.NumChildrenExpanded; i++)
            {
                (MCTSNode node, EncodedMove move, FP16 p)info = node.ChildAtIndexInfo(i);
                indices[i] = (ushort)info.move.IndexNeuralNet;

                float newValue = (1.0f - weightEmpirical) * info.p
                                 + weightEmpirical * nodeFractions[i];
                if (newValue < minP)
                {
                    newValue = minP;
                }
                probabilities[i] = CompressedPolicyVector.EncodedProbability(newValue);

                if (rewriteNodeInTree && weightEmpirical != 0)
                {
                    MCTSNodeStructChild thisChild = children[i];
                    if (thisChild.IsExpanded)
                    {
                        ref MCTSNodeStruct childNodeRef = ref thisChild.ChildRef;
                        thisChild.ChildRef.P = (FP16)newValue;
                    }
                    else
                    {
                        node.Ref.ChildAtIndex(i).SetUnexpandedPolicyValues(thisChild.Move, (FP16)newValue);
                    }
                }
            }
        internal static void Repack(MCTSNode node, ref CompressedPolicyVector policy)
        {
            Span <ushort> indicies      = stackalloc ushort[node.NumPolicyMoves];
            Span <ushort> probabilities = stackalloc ushort[node.NumPolicyMoves];

            for (int i = 0; i < node.NumPolicyMoves; i++)
            {
                ref MCTSNodeStructChild childRef = ref node.ChildAtIndexRef(i);
                indicies[i]      = (ushort)childRef.Move.IndexNeuralNet;
                probabilities[i] = CompressedPolicyVector.EncodedProbability(childRef.P);
            }