示例#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;
    }
示例#2
0
/*----------------------------------------------------------------------------------------------------------------------
|	
*/
inline effective_postorder_edge_iterator::effective_postorder_edge_iterator(
  TreeNode * effRoot, 		/**< "focal" node of the iteration (order of nodes will be postorder if this node were the root) */
  NodeValidityChecker f)	/**< functor that takes two Node pointers and returns true if the iteration in this subtree should be stopped) */
  : isValidChecker(f), effectiveRoot(effRoot)
	{
	PHYCAS_ASSERT(!isValidChecker.empty());
	PHYCAS_ASSERT(effectiveRoot != NULL);

	// Build that part of edge_stack based on nodes above effectiveRoot
	BuildStackFromNodeAndSiblings(effectiveRoot->GetLeftChild(), NULL);

	// Now finish the job by considering nodes below effectiveRoot
	TreeNode * currAvoidNode = effectiveRoot;
	for (TreeNode * currAnc = effectiveRoot->GetParent(); currAnc != NULL; currAnc = currAnc->GetParent())
		{
#if 0
		if (!isValidChecker.empty() && isValidChecker(currAnc, currAvoidNode))
			break;
#else
		if (!isValidChecker.empty())
            {
            bool ok = isValidChecker(currAnc, currAvoidNode);
            if (ok)
			    break;
            }
#endif

		// 
		edgeStack.push(EdgeEndpoints(currAnc, currAvoidNode));
		BuildStackFromNodeAndSiblings(currAnc->GetLeftChild(), currAvoidNode);
		currAvoidNode = currAnc;
		}

	// Make sure we look like a default-constructed object if there are no edges in edgeStack
	// This allows the iterator to determine when it has reached the end
	if (edgeStack.empty())
		effectiveRoot = NULL;
	}
示例#3
0
/*----------------------------------------------------------------------------------------------------------------------
|   Selects an internal node at random from a discrete uniform distribution with the constraint that the returned node
|   is not equal to the subroot (the sole child of the tip node serving as the root).
*/
TreeNode * LargetSimonMove::randomInternalAboveSubroot()
    {
	// Avoiding the "subroot" node (only child of the tip serving as the root), so the number of
	// acceptable nodes is one fewer than the number of internal nodes
	unsigned numAcceptableNodes = tree->GetNInternals() - 1;

	unsigned ypos = rng->SampleUInt(numAcceptableNodes);
	unsigned i = 0;
    TreeNode * nd = tree->GetFirstPreorder();
	for (; nd != NULL; nd = nd->GetNextPreorder())
		{
		if (nd->IsInternal() && !nd->GetParentConst()->IsTipRoot())
			{
			if (i == ypos)
				break;
			++i;
			}
		}
	PHYCAS_ASSERT(nd->GetLeftChild() != NULL);
	PHYCAS_ASSERT(nd->GetParentConst() != NULL);
	PHYCAS_ASSERT(!nd->GetParent()->IsTipRoot());
    return nd;
    }