/*---------------------------------------------------------------------------------------------------------------------- | 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; }
/*---------------------------------------------------------------------------------------------------------------------- | */ 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; }
/*---------------------------------------------------------------------------------------------------------------------- | 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; }