libcrn  3.9.5
A document image processing library
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CRNIterativeClustering.h
Go to the documentation of this file.
1 /* Copyright 2012-2014 INSA-Lyon, CoReNum
2  *
3  * This file is part of libcrn.
4  *
5  * libcrn 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, or
8  * (at your option) any later version.
9  *
10  * libcrn 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 libcrn. If not, see <http://www.gnu.org/licenses/>.
17  *
18  * file: CRNIterativeClustering.h
19  * \author Yann LEYDIER
20  */
21 
22 #ifndef CRNIterativeClustering_HEADER
23 #define CRNIterativeClustering_HEADER
24 
25 #include <CRNString.h>
26 #include <vector>
27 #include <set>
28 
29 namespace crn
30 {
42  template<
43  typename T,
44  typename std::enable_if<
45  // operator=
46  std::is_copy_assignable<T>::value &&
47  // operator<
48  traits::HasLT<T>::value
49  , int>::type = 0
50  >
52  {
53  public:
54  IterativeClustering() = default;
55  IterativeClustering(const IterativeClustering&) = default;
59 
63  inline const std::vector<std::set<T>>& GetClusters() const { return clusters; }
64 
65  enum class Operation { None, Create, Add, Merge };
66 
72  Operation Associate(const T &v1, const T &v2)
73  {
74  auto ret = Operation::None;
75  auto found = size_t{0};
76  auto leftover = v1;
77  for (auto cluster = size_t(0); cluster < clusters.size(); ++cluster)
78  { // for each cluster
79  if (clusters[cluster].find(v1) != clusters[cluster].end())
80  { // found v1
81  if (clusters[cluster].insert(v2).second)
82  {
83  ret = Operation::Add;
84  found = cluster;
85  leftover = v2;
86  break;
87  }
88  else // not inserted: was already in
89  return Operation::None;
90  }
91  if (clusters[cluster].find(v2) != clusters[cluster].end())
92  { // found v2
93  if (clusters[cluster].insert(v1).second)
94  {
95  ret = Operation::Add;
96  found = cluster;
97  leftover = v1;
98  break;
99  }
100  else // not inserted: was already in
101  return Operation::None;
102  }
103  }
104  if (ret == Operation::None)
105  { // create new cluster
106  clusters.push_back(std::set<T>());
107  clusters.back().insert(v1);
108  clusters.back().insert(v2);
109  return Operation::Create;
110  }
111  // check if we need to merge
112  for (auto cluster = found + 1; cluster < clusters.size(); ++cluster)
113  {
114  if (clusters[cluster].find(leftover) != clusters[cluster].end())
115  { // merge
116  clusters[found].insert(clusters[cluster].begin(), clusters[cluster].end());
117  clusters.erase(clusters.begin() + cluster);
118  return Operation::Merge;
119  }
120  }
121  return ret;
122  }
123 
129  {
130  auto s = crn::String{};
131  for (const auto &c : clusters)
132  {
133  s += U"{ ";
134  for (const auto& v : c)
135  {
136  s += v;
137  s += U" ";
138  }
139  s += U"} ";
140  }
141  return s;
142  }
143 
144  private:
145  std::vector<std::set<T>> clusters;
146  };
147 
148 }
149 
150 #endif
151 
152 
Operation Associate(const T &v1, const T &v2)
Associates two elements and merges clusters if needed.
crn::String ToString() const
Prints the clusters to a string.
IterativeClustering & operator=(const IterativeClustering &)=default
A UTF32 character string class.
Definition: CRNString.h:61
const std::vector< std::set< T > > & GetClusters() const
Gets the current clusters.
A utility class to create clusters iteratively.