void BinarySpaceTree<MetricType, StatisticType, MatType, BoundType, SplitType>:: SingleTreeTraverser<RuleType>::Traverse( const size_t queryIndex, BinarySpaceTree<MetricType, StatisticType, MatType, BoundType, SplitType>& referenceNode) { // If we are a leaf, run the base case as necessary. if (referenceNode.IsLeaf()) { const size_t refEnd = referenceNode.Begin() + referenceNode.Count(); for (size_t i = referenceNode.Begin(); i < refEnd; ++i) rule.BaseCase(queryIndex, i); } else { // If either score is DBL_MAX, we do not recurse into that node. double leftScore = rule.Score(queryIndex, *referenceNode.Left()); double rightScore = rule.Score(queryIndex, *referenceNode.Right()); if (leftScore < rightScore) { // Recurse to the left. Traverse(queryIndex, *referenceNode.Left()); // Is it still valid to recurse to the right? rightScore = rule.Rescore(queryIndex, *referenceNode.Right(), rightScore); if (rightScore != DBL_MAX) Traverse(queryIndex, *referenceNode.Right()); // Recurse to the right. else ++numPrunes; } else if (rightScore < leftScore) { // Recurse to the right. Traverse(queryIndex, *referenceNode.Right()); // Is it still valid to recurse to the left? leftScore = rule.Rescore(queryIndex, *referenceNode.Left(), leftScore); if (leftScore != DBL_MAX) Traverse(queryIndex, *referenceNode.Left()); // Recurse to the left. else ++numPrunes; } else // leftScore is equal to rightScore. { if (leftScore == DBL_MAX) { numPrunes += 2; // Pruned both left and right. } else { // Choose the left first. Traverse(queryIndex, *referenceNode.Left()); // Is it still valid to recurse to the right? rightScore = rule.Rescore(queryIndex, *referenceNode.Right(), rightScore); if (rightScore != DBL_MAX) Traverse(queryIndex, *referenceNode.Right()); else ++numPrunes; } } } }
void BinarySpaceTree<MetricType, StatisticType, MatType, BoundType, SplitType>:: DualTreeTraverser<RuleType>::Traverse( BinarySpaceTree<MetricType, StatisticType, MatType, BoundType, SplitType>& queryNode, BinarySpaceTree<MetricType, StatisticType, MatType, BoundType, SplitType>& referenceNode) { // Increment the visit counter. ++numVisited; // Store the current traversal info. traversalInfo = rule.TraversalInfo(); // If both are leaves, we must evaluate the base case. if (queryNode.IsLeaf() && referenceNode.IsLeaf()) { // Loop through each of the points in each node. const size_t queryEnd = queryNode.Begin() + queryNode.Count(); const size_t refEnd = referenceNode.Begin() + referenceNode.Count(); for (size_t query = queryNode.Begin(); query < queryEnd; ++query) { // See if we need to investigate this point (this function should be // implemented for the single-tree recursion too). Restore the traversal // information first. rule.TraversalInfo() = traversalInfo; const double childScore = rule.Score(query, referenceNode); if (childScore == DBL_MAX) continue; // We can't improve this particular point. for (size_t ref = referenceNode.Begin(); ref < refEnd; ++ref) rule.BaseCase(query, ref); numBaseCases += referenceNode.Count(); } } else if (((!queryNode.IsLeaf()) && referenceNode.IsLeaf()) || (queryNode.NumDescendants() > 3 * referenceNode.NumDescendants() && !queryNode.IsLeaf() && !referenceNode.IsLeaf())) { // We have to recurse down the query node. In this case the recursion order // does not matter. const double leftScore = rule.Score(*queryNode.Left(), referenceNode); ++numScores; if (leftScore != DBL_MAX) Traverse(*queryNode.Left(), referenceNode); else ++numPrunes; // Before recursing, we have to set the traversal information correctly. rule.TraversalInfo() = traversalInfo; const double rightScore = rule.Score(*queryNode.Right(), referenceNode); ++numScores; if (rightScore != DBL_MAX) Traverse(*queryNode.Right(), referenceNode); else ++numPrunes; } else if (queryNode.IsLeaf() && (!referenceNode.IsLeaf())) { // We have to recurse down the reference node. In this case the recursion // order does matter. Before recursing, though, we have to set the // traversal information correctly. double leftScore = rule.Score(queryNode, *referenceNode.Left()); typename RuleType::TraversalInfoType leftInfo = rule.TraversalInfo(); rule.TraversalInfo() = traversalInfo; double rightScore = rule.Score(queryNode, *referenceNode.Right()); numScores += 2; if (leftScore < rightScore) { // Recurse to the left. Restore the left traversal info. Store the right // traversal info. traversalInfo = rule.TraversalInfo(); rule.TraversalInfo() = leftInfo; Traverse(queryNode, *referenceNode.Left()); // Is it still valid to recurse to the right? rightScore = rule.Rescore(queryNode, *referenceNode.Right(), rightScore); if (rightScore != DBL_MAX) { // Restore the right traversal info. rule.TraversalInfo() = traversalInfo; Traverse(queryNode, *referenceNode.Right()); } else ++numPrunes; } else if (rightScore < leftScore) { // Recurse to the right. Traverse(queryNode, *referenceNode.Right()); // Is it still valid to recurse to the left? leftScore = rule.Rescore(queryNode, *referenceNode.Left(), leftScore); if (leftScore != DBL_MAX) { // Restore the left traversal info. rule.TraversalInfo() = leftInfo; Traverse(queryNode, *referenceNode.Left()); } else ++numPrunes; } else // leftScore is equal to rightScore. { if (leftScore == DBL_MAX) { numPrunes += 2; } else { // Choose the left first. Restore the left traversal info. Store the // right traversal info. traversalInfo = rule.TraversalInfo(); rule.TraversalInfo() = leftInfo; Traverse(queryNode, *referenceNode.Left()); rightScore = rule.Rescore(queryNode, *referenceNode.Right(), rightScore); if (rightScore != DBL_MAX) { // Restore the right traversal info. rule.TraversalInfo() = traversalInfo; Traverse(queryNode, *referenceNode.Right()); } else ++numPrunes; } } } else { // We have to recurse down both query and reference nodes. Because the // query descent order does not matter, we will go to the left query child // first. Before recursing, we have to set the traversal information // correctly. double leftScore = rule.Score(*queryNode.Left(), *referenceNode.Left()); typename RuleType::TraversalInfoType leftInfo = rule.TraversalInfo(); rule.TraversalInfo() = traversalInfo; double rightScore = rule.Score(*queryNode.Left(), *referenceNode.Right()); typename RuleType::TraversalInfoType rightInfo; numScores += 2; if (leftScore < rightScore) { // Recurse to the left. Restore the left traversal info. Store the right // traversal info. rightInfo = rule.TraversalInfo(); rule.TraversalInfo() = leftInfo; Traverse(*queryNode.Left(), *referenceNode.Left()); // Is it still valid to recurse to the right? rightScore = rule.Rescore(*queryNode.Left(), *referenceNode.Right(), rightScore); if (rightScore != DBL_MAX) { // Restore the right traversal info. rule.TraversalInfo() = rightInfo; Traverse(*queryNode.Left(), *referenceNode.Right()); } else ++numPrunes; } else if (rightScore < leftScore) { // Recurse to the right. Traverse(*queryNode.Left(), *referenceNode.Right()); // Is it still valid to recurse to the left? leftScore = rule.Rescore(*queryNode.Left(), *referenceNode.Left(), leftScore); if (leftScore != DBL_MAX) { // Restore the left traversal info. rule.TraversalInfo() = leftInfo; Traverse(*queryNode.Left(), *referenceNode.Left()); } else ++numPrunes; } else { if (leftScore == DBL_MAX) { numPrunes += 2; } else { // Choose the left first. Restore the left traversal info and store the // right traversal info. rightInfo = rule.TraversalInfo(); rule.TraversalInfo() = leftInfo; Traverse(*queryNode.Left(), *referenceNode.Left()); // Is it still valid to recurse to the right? rightScore = rule.Rescore(*queryNode.Left(), *referenceNode.Right(), rightScore); if (rightScore != DBL_MAX) { // Restore the right traversal information. rule.TraversalInfo() = rightInfo; Traverse(*queryNode.Left(), *referenceNode.Right()); } else ++numPrunes; } } // Restore the main traversal information. rule.TraversalInfo() = traversalInfo; // Now recurse down the right query node. leftScore = rule.Score(*queryNode.Right(), *referenceNode.Left()); leftInfo = rule.TraversalInfo(); rule.TraversalInfo() = traversalInfo; rightScore = rule.Score(*queryNode.Right(), *referenceNode.Right()); numScores += 2; if (leftScore < rightScore) { // Recurse to the left. Restore the left traversal info. Store the right // traversal info. rightInfo = rule.TraversalInfo(); rule.TraversalInfo() = leftInfo; Traverse(*queryNode.Right(), *referenceNode.Left()); // Is it still valid to recurse to the right? rightScore = rule.Rescore(*queryNode.Right(), *referenceNode.Right(), rightScore); if (rightScore != DBL_MAX) { // Restore the right traversal info. rule.TraversalInfo() = rightInfo; Traverse(*queryNode.Right(), *referenceNode.Right()); } else ++numPrunes; } else if (rightScore < leftScore) { // Recurse to the right. Traverse(*queryNode.Right(), *referenceNode.Right()); // Is it still valid to recurse to the left? leftScore = rule.Rescore(*queryNode.Right(), *referenceNode.Left(), leftScore); if (leftScore != DBL_MAX) { // Restore the left traversal info. rule.TraversalInfo() = leftInfo; Traverse(*queryNode.Right(), *referenceNode.Left()); } else ++numPrunes; } else { if (leftScore == DBL_MAX) { numPrunes += 2; } else { // Choose the left first. Restore the left traversal info. Store the // right traversal info. rightInfo = rule.TraversalInfo(); rule.TraversalInfo() = leftInfo; Traverse(*queryNode.Right(), *referenceNode.Left()); // Is it still valid to recurse to the right? rightScore = rule.Rescore(*queryNode.Right(), *referenceNode.Right(), rightScore); if (rightScore != DBL_MAX) { // Restore the right traversal info. rule.TraversalInfo() = rightInfo; Traverse(*queryNode.Right(), *referenceNode.Right()); } else ++numPrunes; } } } }
void BinarySpaceTree<MetricType, StatisticType, MatType, BoundType, SplitType>:: BreadthFirstDualTreeTraverser<RuleType>::Traverse( BinarySpaceTree<MetricType, StatisticType, MatType, BoundType, SplitType>& queryNode, std::priority_queue<QueueFrameType>& referenceQueue) { // Store queues for the children. We will recurse into the children once our // queue is empty. std::priority_queue<QueueFrameType> leftChildQueue; std::priority_queue<QueueFrameType> rightChildQueue; while (!referenceQueue.empty()) { QueueFrameType currentFrame = referenceQueue.top(); referenceQueue.pop(); BinarySpaceTree& queryNode = *currentFrame.queryNode; BinarySpaceTree& referenceNode = *currentFrame.referenceNode; typename RuleType::TraversalInfoType ti = currentFrame.traversalInfo; rule.TraversalInfo() = ti; const size_t queryDepth = currentFrame.queryDepth; double score = rule.Score(queryNode, referenceNode); ++numScores; if (score == DBL_MAX) { ++numPrunes; continue; } // If both are leaves, we must evaluate the base case. if (queryNode.IsLeaf() && referenceNode.IsLeaf()) { // Loop through each of the points in each node. const size_t queryEnd = queryNode.Begin() + queryNode.Count(); const size_t refEnd = referenceNode.Begin() + referenceNode.Count(); for (size_t query = queryNode.Begin(); query < queryEnd; ++query) { // See if we need to investigate this point (this function should be // implemented for the single-tree recursion too). Restore the // traversal information first. // const double childScore = rule.Score(query, referenceNode); // if (childScore == DBL_MAX) // continue; // We can't improve this particular point. for (size_t ref = referenceNode.Begin(); ref < refEnd; ++ref) rule.BaseCase(query, ref); numBaseCases += referenceNode.Count(); } } else if ((!queryNode.IsLeaf()) && referenceNode.IsLeaf()) { // We have to recurse down the query node. QueueFrameType fl = { queryNode.Left(), &referenceNode, queryDepth + 1, score, rule.TraversalInfo() }; leftChildQueue.push(fl); QueueFrameType fr = { queryNode.Right(), &referenceNode, queryDepth + 1, score, ti }; rightChildQueue.push(fr); } else if (queryNode.IsLeaf() && (!referenceNode.IsLeaf())) { // We have to recurse down the reference node. In this case the recursion // order does matter. Before recursing, though, we have to set the // traversal information correctly. QueueFrameType fl = { &queryNode, referenceNode.Left(), queryDepth, score, rule.TraversalInfo() }; referenceQueue.push(fl); QueueFrameType fr = { &queryNode, referenceNode.Right(), queryDepth, score, ti }; referenceQueue.push(fr); } else { // We have to recurse down both query and reference nodes. Because the // query descent order does not matter, we will go to the left query child // first. Before recursing, we have to set the traversal information // correctly. QueueFrameType fll = { queryNode.Left(), referenceNode.Left(), queryDepth + 1, score, rule.TraversalInfo() }; leftChildQueue.push(fll); QueueFrameType flr = { queryNode.Left(), referenceNode.Right(), queryDepth + 1, score, rule.TraversalInfo() }; leftChildQueue.push(flr); QueueFrameType frl = { queryNode.Right(), referenceNode.Left(), queryDepth + 1, score, rule.TraversalInfo() }; rightChildQueue.push(frl); QueueFrameType frr = { queryNode.Right(), referenceNode.Right(), queryDepth + 1, score, rule.TraversalInfo() }; rightChildQueue.push(frr); } } // Now, recurse into the left and right children queues. The order doesn't // matter. if (leftChildQueue.size() > 0) Traverse(*queryNode.Left(), leftChildQueue); if (rightChildQueue.size() > 0) Traverse(*queryNode.Right(), rightChildQueue); }