10#include <boost/functional/hash.hpp>
13#include <unordered_set>
16template <
typename T> std::pair<T, T> ordered_pair(
const T &a,
const T &b) {
17 T min = std::min(a, b);
18 T max = std::max(a, b);
19 return std::pair<T, T>(min, max);
34 using GroupType = std::list<std::unordered_set<size_t>>;
56 const size_t &aLabel = a.
getRoot();
57 const size_t &bLabel = b.
getRoot();
64 if (cluster.find(aLabel) != cluster.end()) {
65 containingAny.emplace_back(cluster);
66 }
else if (cluster.find(bLabel) != cluster.end()) {
67 containingAny.emplace_back(cluster);
69 containingNone.emplace_back(cluster);
75 if (containingAny.empty()) {
77 GroupType::value_type newSet;
78 newSet.insert(aLabel);
79 newSet.insert(bLabel);
87 GroupType::value_type masterSet;
88 masterSet.insert(aLabel);
89 masterSet.insert(bLabel);
90 for (
auto &childSet : containingAny) {
91 masterSet.insert(childSet.begin(),
94 temp.emplace_back(masterSet);
106 std::list<std::shared_ptr<CompositeCluster>> composites;
108 auto composite = std::make_shared<CompositeCluster>();
109 for (
auto j : labelSet) {
110 std::shared_ptr<ICluster> &cluster =
m_register[j];
111 composite->add(cluster);
113 composites.emplace_back(composite);
134 m_Impl->m_register.emplace(label, cluster);
135 m_Impl->m_unique.emplace(label, cluster);
145 const int &aId = a.
getId();
146 const int &bId = b.
getId();
148 size_t hash =
m_Impl->m_labelHasher(ordered_pair(aId, bId));
149 if (
m_Impl->m_labelHash.find(hash) ==
m_Impl->m_labelHash.end())
153 m_Impl->m_unique.erase(aId);
154 m_Impl->m_unique.erase(bId);
155 m_Impl->m_labelHash.insert(hash);
166 temp.insert(
m_Impl->m_unique.begin(),
m_Impl->m_unique.end());
167 auto mergedClusters =
m_Impl->makeCompositeClusters();
168 for (
const auto &merged : mergedClusters) {
169 temp.emplace(merged->getLabel(), merged);
182 temp.insert(
m_Impl->m_unique.begin(),
m_Impl->m_unique.end());
183 auto mergedClusters =
m_Impl->makeCompositeClusters();
184 for (
auto &merged : mergedClusters) {
185 merged->toUniformMinimum(elements);
186 temp.emplace(merged->getLabel(), merged);
void add(const size_t &label, const std::shared_ptr< ICluster > &cluster)
Add clusters.
MapCluster clusters() const
Get all combined clusters.
std::map< size_t, std::shared_ptr< ICluster > > MapCluster
Cluster map.
virtual ~ClusterRegister()
Destructor.
ClusterRegister()
Constructor.
boost::scoped_ptr< ImplClusterRegister > m_Impl
Pointer to implementation.
void merge(const DisjointElement &a, const DisjointElement &b) const
Merge clusters on the basis of known pairs of disjoint elements.
DisjointElement : Cluster item used in a disjoint-set data structure.
bool isEmpty() const
Is empty.
int getRoot() const
Get root id.
GroupType m_groups
Groups of labels to maintain.
boost::hash< std::pair< int, int > > m_labelHasher
Label hasher.
bool insert(const DisjointElement &a, const DisjointElement &b)
Inserts a pair of disjoint elements.
ClusterRegister::MapCluster m_unique
Clusters that do not need merging.
LabelHash m_labelHash
Hash of labels merged.
std::unordered_set< size_t > LabelHash
Type for identifying labels already seen.
std::list< std::shared_ptr< CompositeCluster > > makeCompositeClusters()
Make composite clusters from the merged groups.
ClusterRegister::MapCluster m_register
All registered input clusters.
std::list< std::unordered_set< size_t > > GroupType
Type for identifying label groups.