Example #1
0
/*----------------------------------------------------------------------------------------------------------------------
|   Randomly chooses a node to serve as node Z (the bottom of the three nodes involved in a Larget-Simon move). The
|   supplied node `middle' is the node serving as Y. In the figure below, the nodes labeled Z are all possible
|   candidates for the return value of this function. The node selected as Z should be the owner of the lowermost edge
|   involved in the move (X owns the uppermost edge and Y owns the middle edge).
|>
|	     X  X  X
|	      \ | /
|          \|/
|	  Z  Z  Y
|	   \ | /
|	    \|/
|	     Z
|	     |
|>
*/
TreeNode * LargetSimonMove::chooseZ(
  TreeNode * middle)    /**< is the middle node (Y) */
    {
    TreeNode * nd = NULL;
	TreeNode * U = middle->GetParent();
	PHYCAS_ASSERT(U != NULL);
	unsigned uchildren = U->CountChildren();
	unsigned which_child = rng->SampleUInt(uchildren);
	if (which_child == 0)
		{
		// Selected "child" is actually U's parent
		nd = U;
		}
	else
		{
		// Selected child is one of U's actual children (but cannot be equal to middle)
		unsigned k = 1;
		for (nd = U->GetLeftChild(); nd != NULL; nd = nd->GetRightSib())
			{
			if (nd == middle)
				continue;
			else
				{
				if (k == which_child)
					break;
				++k;
				}
			}
		PHYCAS_ASSERT(nd != NULL);
		}
    return nd;
    }
Example #2
0
/*----------------------------------------------------------------------------------------------------------------------
|	
*/
inline void effective_postorder_edge_iterator::BuildStackFromNodeAndSiblings(TreeNode * curr, const TreeNode * nodeToSkip)
	{
	// Handle case in which curr equals nodeToSkip
	if (nodeToSkip != NULL && curr == nodeToSkip)
		curr = curr->GetRightSib();
	if (curr == NULL)
		return;

	// Create a temporary stack of nodes to remember
	std::stack<TreeNode *> ndStack;

	// Visit all nodes in the subtree extending up from curr's parent (with the exception 
	// of the subtree whose root is nodeToSkip)
	for (;;)
		{
		TreeNode * par = curr->GetParent();
		if ((!isValidChecker.empty()) && isValidChecker(curr, par))
			{
			// edge was valid:
			//   - let curr be curr's next sibling
			curr = curr->GetRightSib();
			if (nodeToSkip != NULL && curr == nodeToSkip)
				curr = curr->GetRightSib();
			}
		else
			{
			// edge was not valid:
			//   - push edge onto edge stack
			//   - if curr has a sibling, push that sibling onto ndStack (i.e. remember it so we can deal with it later)
			//   - let curr be curr's left child
			edgeStack.push(EdgeEndpoints(curr, par));
			TreeNode * r = curr->GetRightSib();
			if (r != NULL && r == nodeToSkip)
				r = r->GetRightSib();
			if (r != NULL)
				ndStack.push(r);
			curr = curr->GetLeftChild();
			}

		if (curr == NULL)
			{
			// we've come to the end of the road for this subtree
			// let curr be node on top of ndStack
			if (ndStack.empty())
				break;
			curr = ndStack.top();
			ndStack.pop();
			}
		}
	}
Example #3
0
/*----------------------------------------------------------------------------------------------------------------------
|   Selects a child of the supplied `nd' at random from a discrete uniform distribution.
*/
TreeNode * LargetSimonMove::randomChild(
  TreeNode * nd)    /**< is the parent node whose children are candidates */
    {
	unsigned ychildren = nd->CountChildren();
	unsigned which_child = rng->SampleUInt(ychildren);
	unsigned k = 0;
    TreeNode * child = nd->GetLeftChild();
	for (; child != NULL; child = child->GetRightSib())
		{
		if (k == which_child)
			break;
		++k;
		}
	PHYCAS_ASSERT(child != NULL);
    return child;
    }