12 #ifndef MLPACK_CORE_TREE_RECTANGLE_TREE_R_PLUS_TREE_SPLIT_IMPL_HPP 13 #define MLPACK_CORE_TREE_RECTANGLE_TREE_R_PLUS_TREE_SPLIT_IMPL_HPP 23 template<
typename SplitPolicyType,
24 template<
typename>
class SweepType>
25 template<
typename TreeType>
29 typedef typename TreeType::ElemType ElemType;
31 if (tree->Count() == 1)
36 TreeType* node = tree->Parent();
40 if (node->NumChildren() == node->MaxNumChildren() + 1)
46 node = node->Parent();
50 else if (tree->Count() <= tree->MaxLeafSize())
58 if (tree->Parent() == NULL)
61 TreeType* copy =
new TreeType(*tree,
false);
62 copy->Parent() = tree;
66 tree->children[(tree->NumChildren())++] = copy;
67 assert(tree->NumChildren() == 1);
73 size_t cutAxis = tree->Bound().Dim();
74 ElemType cut = std::numeric_limits<ElemType>::lowest();
77 if (!PartitionNode(tree, cutAxis, cut))
81 if (cutAxis == tree->Bound().Dim())
83 tree->MaxLeafSize()++;
84 tree->points.resize(tree->MaxLeafSize() + 1);
85 Log::Warn <<
"Could not find an acceptable partition." 86 "The size of the node will be increased.";
90 TreeType* treeOne =
new TreeType(tree->Parent(), tree->MaxNumChildren());
91 TreeType* treeTwo =
new TreeType(tree->Parent(), tree->MaxNumChildren());
92 treeOne->MinLeafSize() = 0;
93 treeOne->MinNumChildren() = 0;
94 treeTwo->MinLeafSize() = 0;
95 treeTwo->MinNumChildren() = 0;
98 SplitLeafNodeAlongPartition(tree, treeOne, treeTwo, cutAxis, cut);
100 TreeType* parent = tree->Parent();
102 while (parent->children[i] != tree)
105 assert(i < parent->NumChildren());
108 parent->children[i] = treeOne;
109 parent->children[parent->NumChildren()++] = treeTwo;
111 assert(parent->NumChildren() <= parent->MaxNumChildren() + 1);
114 if (parent->NumChildren() == parent->MaxNumChildren() + 1)
120 template<
typename SplitPolicyType,
121 template<
typename>
class SweepType>
122 template<
typename TreeType>
126 typedef typename TreeType::ElemType ElemType;
130 if (tree->Parent() == NULL)
133 TreeType* copy =
new TreeType(*tree,
false);
135 copy->Parent() = tree;
136 tree->NumChildren() = 0;
138 tree->children[(tree->NumChildren())++] = copy;
143 size_t cutAxis = tree->Bound().Dim();
144 ElemType cut = std::numeric_limits<ElemType>::lowest();
147 if ( !PartitionNode(tree, cutAxis, cut))
151 if (cutAxis == tree->Bound().Dim())
153 tree->MaxNumChildren()++;
154 tree->children.resize(tree->MaxNumChildren() + 1);
155 Log::Warn <<
"Could not find an acceptable partition." 156 "The size of the node will be increased.";
160 TreeType* treeOne =
new TreeType(tree->Parent(), tree->MaxNumChildren());
161 TreeType* treeTwo =
new TreeType(tree->Parent(), tree->MaxNumChildren());
162 treeOne->MinLeafSize() = 0;
163 treeOne->MinNumChildren() = 0;
164 treeTwo->MinLeafSize() = 0;
165 treeTwo->MinNumChildren() = 0;
168 SplitNonLeafNodeAlongPartition(tree, treeOne, treeTwo, cutAxis, cut);
170 TreeType* parent = tree->Parent();
172 while (parent->children[i] != tree)
175 assert(i < parent->NumChildren());
178 parent->children[i] = treeOne;
179 parent->children[parent->NumChildren()++] = treeTwo;
183 assert(parent->NumChildren() <= parent->MaxNumChildren() + 1);
186 if (parent->NumChildren() == parent->MaxNumChildren() + 1)
192 template<
typename SplitPolicyType,
193 template<
typename>
class SweepType>
194 template<
typename TreeType>
199 const size_t cutAxis,
200 const typename TreeType::ElemType cut)
203 tree->AuxiliaryInfo().SplitAuxiliaryInfo(treeOne, treeTwo, cutAxis, cut);
206 if (treeOne->MaxLeafSize() < tree->NumPoints())
208 treeOne->MaxLeafSize() = tree->NumPoints();
209 treeOne->points.resize(treeOne->MaxLeafSize() + 1);
212 if (treeTwo->MaxLeafSize() < tree->NumPoints())
214 treeTwo->MaxLeafSize() = tree->NumPoints();
215 treeTwo->points.resize(treeTwo->MaxLeafSize() + 1);
219 for (
size_t i = 0; i < tree->NumPoints(); ++i)
221 if (tree->Dataset().col(tree->Point(i))[cutAxis] <= cut)
223 treeOne->Point(treeOne->Count()++) = tree->Point(i);
224 treeOne->Bound() |= tree->Dataset().col(tree->Point(i));
228 treeTwo->Point(treeTwo->Count()++) = tree->Point(i);
229 treeTwo->Bound() |= tree->Dataset().col(tree->Point(i));
233 treeOne->numDescendants = treeOne->Count();
234 treeTwo->numDescendants = treeTwo->Count();
236 assert(treeOne->Count() <= treeOne->MaxLeafSize());
237 assert(treeTwo->Count() <= treeTwo->MaxLeafSize());
239 assert(tree->Count() == treeOne->Count() + treeTwo->Count());
240 assert(treeOne->Bound()[cutAxis].Hi() < treeTwo->Bound()[cutAxis].Lo());
243 template<
typename SplitPolicyType,
244 template<
typename>
class SweepType>
245 template<
typename TreeType>
250 const size_t cutAxis,
251 const typename TreeType::ElemType cut)
254 tree->AuxiliaryInfo().SplitAuxiliaryInfo(treeOne, treeTwo, cutAxis, cut);
257 for (
size_t i = 0; i < tree->NumChildren(); ++i)
259 TreeType* child = tree->children[i];
260 int policy = SplitPolicyType::GetSplitPolicy(*child, cutAxis, cut);
262 if (policy == SplitPolicyType::AssignToFirstTree)
264 InsertNodeIntoTree(treeOne, child);
265 child->Parent() = treeOne;
267 else if (policy == SplitPolicyType::AssignToSecondTree)
269 InsertNodeIntoTree(treeTwo, child);
270 child->Parent() = treeTwo;
275 TreeType* childOne =
new TreeType(treeOne);
276 TreeType* childTwo =
new TreeType(treeTwo);
277 treeOne->MinLeafSize() = 0;
278 treeOne->MinNumChildren() = 0;
279 treeTwo->MinLeafSize() = 0;
280 treeTwo->MinNumChildren() = 0;
284 SplitLeafNodeAlongPartition(child, childOne, childTwo, cutAxis, cut);
286 SplitNonLeafNodeAlongPartition(child, childOne, childTwo, cutAxis, cut);
288 InsertNodeIntoTree(treeOne, childOne);
289 InsertNodeIntoTree(treeTwo, childTwo);
295 assert(treeOne->NumChildren() + treeTwo->NumChildren() != 0);
298 if (treeOne->NumChildren() == 0)
299 AddFakeNodes(treeTwo, treeOne);
300 else if (treeTwo->NumChildren() == 0)
301 AddFakeNodes(treeOne, treeTwo);
303 assert(treeOne->NumChildren() <= treeOne->MaxNumChildren());
304 assert(treeTwo->NumChildren() <= treeTwo->MaxNumChildren());
307 template<
typename SplitPolicyType,
308 template<
typename>
class SweepType>
309 template<
typename TreeType>
313 size_t numDescendantNodes = tree->TreeDepth() - 1;
315 TreeType* node = emptyTree;
316 for (
size_t i = 0; i < numDescendantNodes; ++i)
318 TreeType* child =
new TreeType(node);
319 node->children[node->NumChildren()++] = child;
325 template<
typename SplitPolicyType,
326 template<
typename>
class SweepType>
327 template<
typename TreeType>
330 typename TreeType::ElemType& minCut)
332 if ((node->NumChildren() <= node->MaxNumChildren() && !node->IsLeaf()) ||
333 (node->Count() <= node->MaxLeafSize() && node->IsLeaf()))
338 SweepType<SplitPolicyType>::template SweepCost<TreeType>::type
341 SweepCostType minCost = std::numeric_limits<SweepCostType>::max();
342 minCutAxis = node->Bound().Dim();
345 for (
size_t k = 0; k < node->Bound().Dim(); ++k)
347 typename TreeType::ElemType cut;
351 cost = SweepType<SplitPolicyType>::SweepLeafNode(k, node, cut);
353 cost = SweepType<SplitPolicyType>::SweepNonLeafNode(k, node, cut);
366 template<
typename SplitPolicyType,
367 template<
typename>
class SweepType>
368 template<
typename TreeType>
372 destTree->Bound() |= srcNode->Bound();
373 destTree->numDescendants += srcNode->numDescendants;
374 destTree->children[destTree->NumChildren()++] = srcNode;
380 #endif // MLPACK_CORE_TREE_RECTANGLE_TREE_R_PLUS_TREE_SPLIT_IMPL_HPP The RPlusTreeSplit class performs the split process of a node on overflow.
Definition: r_plus_tree_split.hpp:32
Linear algebra utility functions, generally performed on matrices or vectors.
Definition: cv.hpp:1
static void SplitLeafNode(TreeType *tree, std::vector< bool > &relevels)
Split a leaf node using the "default" algorithm.
Definition: r_plus_tree_split_impl.hpp:27
static MLPACK_EXPORT util::PrefixedOutStream Warn
Prints warning messages prefixed with [WARN ].
Definition: log.hpp:87
static bool SplitNonLeafNode(TreeType *tree, std::vector< bool > &relevels)
Split a non-leaf node using the "default" algorithm.
Definition: r_plus_tree_split_impl.hpp:124