gtsam  4.0.0
gtsam
DSFMap.h
Go to the documentation of this file.
1 /* ----------------------------------------------------------------------------
2 
3  * GTSAM Copyright 2010, Georgia Tech Research Corporation,
4  * Atlanta, Georgia 30332-0415
5  * All Rights Reserved
6  * Authors: Frank Dellaert, et al. (see THANKS for the full author list)
7 
8  * See LICENSE for the license information
9 
10  * -------------------------------------------------------------------------- */
11 
19 #pragma once
20 
21 #include <cstdlib> // Provides size_t
22 #include <map>
23 #include <set>
24 
25 namespace gtsam {
26 
32 template <class KEY>
33 class DSFMap {
34  protected:
36  struct Entry {
37  typename std::map<KEY, Entry>::iterator parent_;
38  size_t rank_;
39  Entry() {}
40  };
41 
42  typedef typename std::map<KEY, Entry> Map;
43  typedef typename Map::iterator iterator;
44  mutable Map entries_;
45 
47  iterator find__(const KEY& key) const {
48  static const Entry empty;
49  iterator it = entries_.find(key);
50  // if key does not exist, create and return itself
51  if (it == entries_.end()) {
52  it = entries_.insert(std::make_pair(key, empty)).first;
53  it->second.parent_ = it;
54  it->second.rank_ = 0;
55  }
56  return it;
57  }
58 
60  iterator find_(const iterator& it) const {
61  // follow parent pointers until we reach set representative
62  iterator& parent = it->second.parent_;
63  if (parent != it) parent = find_(parent); // not yet, recurse!
64  return parent;
65  }
66 
68  inline iterator find_(const KEY& key) const {
69  iterator initial = find__(key);
70  return find_(initial);
71  }
72 
73  public:
74  typedef std::set<KEY> Set;
75 
77  DSFMap() {}
78 
80  inline KEY find(const KEY& key) const {
81  iterator root = find_(key);
82  return root->first;
83  }
84 
86  void merge(const KEY& x, const KEY& y) {
87  // straight from http://en.wikipedia.org/wiki/Disjoint-set_data_structure
88  iterator xRoot = find_(x);
89  iterator yRoot = find_(y);
90  if (xRoot == yRoot) return;
91 
92  // Merge sets
93  if (xRoot->second.rank_ < yRoot->second.rank_)
94  xRoot->second.parent_ = yRoot;
95  else if (xRoot->second.rank_ > yRoot->second.rank_)
96  yRoot->second.parent_ = xRoot;
97  else {
98  yRoot->second.parent_ = xRoot;
99  xRoot->second.rank_ = xRoot->second.rank_ + 1;
100  }
101  }
102 
104  std::map<KEY, Set> sets() const {
105  std::map<KEY, Set> sets;
106  iterator it = entries_.begin();
107  for (; it != entries_.end(); it++) {
108  iterator root = find_(it);
109  sets[root->first].insert(it->first);
110  }
111  return sets;
112  }
113 };
114 
116 class IndexPair : public std::pair<size_t,size_t> {
117  public:
118  IndexPair(): std::pair<size_t,size_t>(0,0) {}
119  IndexPair(size_t i, size_t j) : std::pair<size_t,size_t>(i,j) {}
120  inline size_t i() const { return first; };
121  inline size_t j() const { return second; };
122 };
123 } // namespace gtsam
std::map< KEY, Set > sets() const
return all sets, i.e. a partition of all elements
Definition: DSFMap.h:104
KEY find(const KEY &key) const
Given key, find the representative key for the set in which it lives.
Definition: DSFMap.h:80
iterator find_(const iterator &it) const
Given iterator to initial entry, find the root Entry.
Definition: DSFMap.h:60
Small utility class for representing a wrappable pairs of ints.
Definition: DSFMap.h:116
DSFMap()
constructor
Definition: DSFMap.h:77
We store the forest in an STL map, but parents are done with pointers.
Definition: DSFMap.h:36
iterator find_(const KEY &key) const
Given key, find the root Entry.
Definition: DSFMap.h:68
iterator find__(const KEY &key) const
Given key, find iterator to initial entry.
Definition: DSFMap.h:47
void merge(const KEY &x, const KEY &y)
Merge two sets.
Definition: DSFMap.h:86
Definition: DSFMap.h:33
Global functions in a separate testing namespace.
Definition: chartTesting.h:28