Partition.h
Go to the documentation of this file.
1 /* Copyright (C) 2008 National Institute For Space Research (INPE) - Brazil.
2 
3  This file is part of the TerraLib - a Framework for building GIS enabled applications.
4 
5  TerraLib is free software: you can redistribute it and/or modify
6  it under the terms of the GNU Lesser General Public License as published by
7  the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  TerraLib is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public License
16  along with TerraLib. See COPYING. If not, write to
17  TerraLib Team at <terralib-team@terralib.org>.
18  */
19 
20 /*!
21  \file terralib/sam/kdtree/Partition.h
22 
23  \brief Partition algorithms.
24 */
25 
26 #ifndef __TERRALIB_SAM_KDTREE_INTERNAL_PARTITION_H
27 #define __TERRALIB_SAM_KDTREE_INTERNAL_PARTITION_H
28 
29 namespace te
30 {
31  namespace sam
32  {
33  namespace kdtree
34  {
35  /*!
36  \brief This function partition the container in two parts:
37  k-1 elements to the left (elements less than or equals to k-th element) and
38  the right part with all other elements (elements greater than or equal to k-th element).
39 
40  \param A Container of elements to partition.
41  \param kthElement Position of the k-th element, around the container will be pertitionated.
42  \param firstElement Position of the first element.
43  \param lastElement Position of the las element.
44  \param compFunctor Functor to compare elements: implements the function "less than".
45  */
46  template<class CONTAINER, class COMPFUNCTOR>
47  void HoareFind(CONTAINER& A, const std::size_t& kthElement, const std::size_t& firstElement, const std::size_t& lastElement, const COMPFUNCTOR& compFunctor)
48  {
49  std::size_t m = firstElement;
50  std::size_t n = lastElement;
51 
52  // Test if the median is in the bounds
53  if(kthElement < firstElement || kthElement > lastElement)
54  return;
55 
56  // Do Container partition
57  while(m < n)
58  {
59  std::size_t i = m;
60  std::size_t j = n;
61 
62  typename CONTAINER::value_type r = A[kthElement];
63 
64  while(i <= j)
65  {
66  while(compFunctor(A[i], r))
67  ++i;
68 
69  while(compFunctor(r, A[j]))
70  --j;
71 
72  if(i <= j)
73  {
74  typename CONTAINER::value_type w = A[i];
75 
76  A[i] = A[j];
77  A[j] = w;
78 
79  ++i;
80  --j;
81  }
82  }
83 
84  if(kthElement <= j) // if the meet point was to the right, so all points above j are greater than the k-th element
85  n = j;
86  else if(i <= kthElement) // otherwise, if the meeting point was to the left of k-th, so all elements before i are already in the correct location
87  m = i;
88  else
89  break;
90  }
91  }
92 
93  /*!
94  \brief This partition the container like a bidimensional K-d Tree using Hoare algorithms.
95 
96  \param dataSet Container elements to be sorted like a K-d Tree.
97  \param first Position of the first element in container, where the sort will begin.
98  \param last Position of the last element, where the sort ends.
99  \param level Indicates the axis to begin the sort ('x' or 'y') and is used during the recursion process.
100  \param lessThanCompFunctorByX Functor to compare elements along the 'x' axis.
101  \param lessThanCompFunctorByY Functor to compare elements along the 'y' axis.
102 
103  \note The expected complexity is O(N log N), where N is the number of elements in container.
104  */
105  template<class CONTAINER, class LESSTHANX, class LESSTHANY>
106  void kdsort(CONTAINER& dataSet, const std::size_t& first, const std::size_t& last, const char& level, const LESSTHANX& lessThanCompFunctorByX, const LESSTHANY& lessThanCompFunctorByY)
107  {
108  const std::size_t kth = (last - first + 1) / 2;
109 
110  if(level == 'x')
111  {
112  // Move data around X axis
113  HoareFind(dataSet, first + kth, first, last, lessThanCompFunctorByX);
114 
115  // Recursive sort the left half and right half
116  if(first + kth > first)
117  kdsort(dataSet, first, first + kth - 1, 'y', lessThanCompFunctorByX, lessThanCompFunctorByY);
118 
119  if((first + kth) < last)
120  kdsort(dataSet, first + kth + 1, last, 'y', lessThanCompFunctorByX, lessThanCompFunctorByY);
121  }
122  else
123  {
124  // Move data around Y axis
125  HoareFind(dataSet, first + kth, first, last, lessThanCompFunctorByY);
126 
127  // Recursive sort the left half and right half
128  if(first + kth > first)
129  kdsort(dataSet, first, first + kth - 1, 'x', lessThanCompFunctorByX, lessThanCompFunctorByY);
130 
131  if(first + kth < last)
132  kdsort(dataSet, first + kth + 1, last, 'x', lessThanCompFunctorByX, lessThanCompFunctorByY);
133  }
134  }
135 
136  } // end namespace kdtree
137  } // end namespace sam
138 } // end namespace te
139 
140 #endif // __TERRALIB_SAM_KDTREE_INTERNAL_PARTITION_H
void HoareFind(CONTAINER &A, const std::size_t &kthElement, const std::size_t &firstElement, const std::size_t &lastElement, const COMPFUNCTOR &compFunctor)
This function partition the container in two parts: k-1 elements to the left (elements less than or e...
Definition: Partition.h:47
void kdsort(CONTAINER &dataSet, const std::size_t &first, const std::size_t &last, const char &level, const LESSTHANX &lessThanCompFunctorByX, const LESSTHANY &lessThanCompFunctorByY)
This partition the container like a bidimensional K-d Tree using Hoare algorithms.
Definition: Partition.h:106
URI C++ Library.