mlpack
r_star_tree_descent_heuristic_impl.hpp
Go to the documentation of this file.
1 
13 #ifndef MLPACK_CORE_TREE_RECTANGLE_TREE_R_STAR_TREE_DESCENT_HEURISTIC_IMPL_HPP
14 #define MLPACK_CORE_TREE_RECTANGLE_TREE_R_STAR_TREE_DESCENT_HEURISTIC_IMPL_HPP
15 
17 
18 namespace mlpack {
19 namespace tree {
20 
21 template<typename TreeType>
23  const TreeType* node,
24  const size_t point)
25 {
26  // Convenience typedef.
27  typedef typename TreeType::ElemType ElemType;
28 
29  bool tiedOne = false;
30  std::vector<ElemType> originalScores(node->NumChildren());
31  ElemType origMinScore = std::numeric_limits<ElemType>::max();
32 
33  if (node->Child(0).IsLeaf())
34  {
35  // If its children are leaf nodes, use minimum overlap to choose.
36  size_t bestIndex = 0;
37 
38  for (size_t i = 0; i < node->NumChildren(); ++i)
39  {
40  ElemType sc = 0;
41  for (size_t j = 0; j < node->NumChildren(); ++j)
42  {
43  if (j != i)
44  {
45  ElemType overlap = 1.0;
46  ElemType newOverlap = 1.0;
47  for (size_t k = 0; k < node->Bound().Dim(); ++k)
48  {
49  ElemType newHigh = std::max(node->Dataset().col(point)[k],
50  node->Child(i).Bound()[k].Hi());
51  ElemType newLow = std::min(node->Dataset().col(point)[k],
52  node->Child(i).Bound()[k].Lo());
53  overlap *= node->Child(i).Bound()[k].Hi() <
54  node->Child(j).Bound()[k].Lo() ||
55  node->Child(i).Bound()[k].Lo() >
56  node->Child(j).Bound()[k].Hi() ? 0 :
57  std::min(node->Child(i).Bound()[k].Hi(),
58  node->Child(j).Bound()[k].Hi()) -
59  std::max(node->Child(i).Bound()[k].Lo(),
60  node->Child(j).Bound()[k].Lo());
61 
62  newOverlap *= newHigh < node->Child(j).Bound()[k].Lo() ||
63  newLow > node->Child(j).Bound()[k].Hi() ? 0 :
64  std::min(newHigh, node->Child(j).Bound()[k].Hi()) -
65  std::max(newLow, node->Child(j).Bound()[k].Lo());
66  }
67  sc += newOverlap - overlap;
68  }
69  }
70 
71  originalScores[i] = sc;
72  if (sc < origMinScore)
73  {
74  origMinScore = sc;
75  bestIndex = i;
76  }
77  else if (sc == origMinScore)
78  {
79  tiedOne = true;
80  }
81  }
82 
83  if (!tiedOne)
84  return bestIndex;
85  }
86 
87  // We do this if it is not on the second level or if there was a tie.
88  std::vector<ElemType> scores(node->NumChildren());
89  if (tiedOne)
90  {
91  // If the first heuristic was tied, we need to eliminate garbage values.
92  for (size_t i = 0; i < scores.size(); ++i)
93  scores[i] = std::numeric_limits<ElemType>::max();
94  }
95 
96  std::vector<ElemType> vols(node->NumChildren());
97  ElemType minScore = std::numeric_limits<ElemType>::max();
98  size_t bestIndex = 0;
99  bool tied = false;
100 
101  for (size_t i = 0; i < node->NumChildren(); ++i)
102  {
103  if (!tiedOne || originalScores[i] == origMinScore)
104  {
105  ElemType v1 = 1.0;
106  ElemType v2 = 1.0;
107  for (size_t j = 0; j < node->Bound().Dim(); ++j)
108  {
109  v1 *= node->Child(i).Bound()[j].Width();
110  v2 *= node->Child(i).Bound()[j].Contains(
111  node->Dataset().col(point)[j]) ?
112  node->Child(i).Bound()[j].Width() :
113  (node->Child(i).Bound()[j].Hi() < node->Dataset().col(point)[j] ?
114  (node->Dataset().col(point)[j] - node->Child(i).Bound()[j].Lo()) :
115  (node->Child(i).Bound()[j].Hi() - node->Dataset().col(point)[j]));
116  }
117 
118  assert(v2 - v1 >= 0);
119  vols[i] = v1;
120  scores[i] = v2 - v1;
121 
122  if (v2 - v1 < minScore)
123  {
124  minScore = v2 - v1;
125  bestIndex = i;
126  }
127  else if (v2 - v1 == minScore)
128  {
129  tied = true;
130  }
131  }
132  }
133 
134  if (tied)
135  {
136  // We break ties by choosing the smallest bound.
137  ElemType minVol = std::numeric_limits<ElemType>::max();
138  bestIndex = 0;
139  for (size_t i = 0; i < scores.size(); ++i)
140  {
141  if (scores[i] == minScore)
142  {
143  if (vols[i] < minVol)
144  {
145  minVol = vols[i];
146  bestIndex = i;
147  }
148  }
149  }
150  }
151 
152  return bestIndex;
153 }
154 
162 template<typename TreeType>
164  const TreeType* node,
165  const TreeType* insertedNode)
166 {
167  // Convenience typedef.
168  typedef typename TreeType::ElemType ElemType;
169 
170  std::vector<ElemType> scores(node->NumChildren());
171  std::vector<ElemType> vols(node->NumChildren());
172  ElemType minScore = std::numeric_limits<ElemType>::max();
173  size_t bestIndex = 0;
174  bool tied = false;
175 
176  for (size_t i = 0; i < node->NumChildren(); ++i)
177  {
178  ElemType v1 = 1.0;
179  ElemType v2 = 1.0;
180  for (size_t j = 0; j < node->Child(i).Bound().Dim(); ++j)
181  {
182  v1 *= node->Child(i).Bound()[j].Width();
183  v2 *= node->Child(i).Bound()[j].Contains(insertedNode->Bound()[j]) ?
184  node->Child(i).Bound()[j].Width() :
185  (insertedNode->Bound()[j].Contains(node->Child(i).Bound()[j]) ?
186  insertedNode->Bound()[j].Width() :
187  (insertedNode->Bound()[j].Lo() < node->Child(i).Bound()[j].Lo() ?
188  (node->Child(i).Bound()[j].Hi() - insertedNode->Bound()[j].Lo()) :
189  (insertedNode->Bound()[j].Hi() - node->Child(i).Bound()[j].Lo())));
190  }
191 
192  assert(v2 - v1 >= 0);
193  vols[i] = v1;
194  scores[i] = v2 - v1;
195 
196  if (v2 - v1 < minScore)
197  {
198  minScore = v2 - v1;
199  bestIndex = i;
200  }
201  else if (v2 - v1 == minScore)
202  {
203  tied = true;
204  }
205  }
206 
207  if (tied)
208  {
209  // We break ties by choosing the smallest bound.
210  ElemType minVol = std::numeric_limits<ElemType>::max();
211  bestIndex = 0;
212  for (size_t i = 0; i < scores.size(); ++i)
213  {
214  if (scores[i] == minScore)
215  {
216  if (vols[i] < minVol)
217  {
218  minVol = vols[i];
219  bestIndex = i;
220  }
221  }
222  }
223  }
224 
225  return bestIndex;
226 }
227 
228 } // namespace tree
229 } // namespace mlpack
230 
231 #endif
Linear algebra utility functions, generally performed on matrices or vectors.
Definition: cv.hpp:1
static size_t ChooseDescentNode(const TreeType *node, const size_t point)
Evaluate the node using a heuristic.
Definition: r_star_tree_descent_heuristic_impl.hpp:22