Split DSFVector into two classes
parent
0dbd016ca9
commit
ddd7c6663f
|
@ -26,33 +26,55 @@ using namespace std;
|
|||
namespace gtsam {
|
||||
|
||||
/* ************************************************************************* */
|
||||
DSFVector::DSFVector(const size_t numNodes) {
|
||||
DSFBase::DSFBase(const size_t numNodes) {
|
||||
v_ = boost::make_shared < V > (numNodes);
|
||||
int index = 0;
|
||||
keys_.reserve(numNodes);
|
||||
for (V::iterator it = v_->begin(); it != v_->end(); it++, index++) {
|
||||
for (V::iterator it = v_->begin(); it != v_->end(); it++, index++)
|
||||
*it = index;
|
||||
keys_.push_back(index);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
DSFBase::DSFBase(const boost::shared_ptr<V>& v_in) {
|
||||
v_ = v_in;
|
||||
int index = 0;
|
||||
for (V::iterator it = v_->begin(); it != v_->end(); it++, index++)
|
||||
*it = index;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
size_t DSFBase::findSet(size_t key) const {
|
||||
size_t parent = (*v_)[key];
|
||||
// follow parent pointers until we reach set representative
|
||||
while (parent != key) {
|
||||
key = parent;
|
||||
parent = (*v_)[key];
|
||||
}
|
||||
return parent;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
void DSFBase::makeUnionInPlace(const size_t& i1, const size_t& i2) {
|
||||
(*v_)[findSet(i2)] = findSet(i1);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
DSFVector::DSFVector(const size_t numNodes) :
|
||||
DSFBase(numNodes) {
|
||||
keys_.reserve(numNodes);
|
||||
for (size_t index = 0; index < numNodes; index++)
|
||||
keys_.push_back(index);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
DSFVector::DSFVector(const std::vector<size_t>& keys) :
|
||||
keys_(keys) {
|
||||
size_t maxKey = *(std::max_element(keys.begin(), keys.end()));
|
||||
v_ = boost::make_shared < V > (maxKey + 1);
|
||||
BOOST_FOREACH(const size_t key, keys)
|
||||
(*v_)[key] = key;
|
||||
DSFBase(1 + *std::max_element(keys.begin(), keys.end())), keys_(keys) {
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
DSFVector::DSFVector(const boost::shared_ptr<V>& v_in,
|
||||
const std::vector<size_t>& keys) :
|
||||
keys_(keys) {
|
||||
DSFBase(v_in), keys_(keys) {
|
||||
assert(*(std::max_element(keys.begin(), keys.end()))<v_in->size());
|
||||
v_ = v_in;
|
||||
BOOST_FOREACH(const size_t key, keys)
|
||||
(*v_)[key] = key;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -94,10 +116,5 @@ std::map<size_t, std::vector<size_t> > DSFVector::arrays() const {
|
|||
return arrays;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
void DSFVector::makeUnionInPlace(const size_t& i1, const size_t& i2) {
|
||||
(*v_)[findSet(i2)] = findSet(i1);
|
||||
}
|
||||
|
||||
} // namespace gtsam
|
||||
|
||||
|
|
|
@ -28,16 +28,39 @@ namespace gtsam {
|
|||
|
||||
/**
|
||||
* A fast implementation of disjoint set forests that uses vector as underly data structure.
|
||||
* This is the absolute minimal DSF data structure, and only allows size_t keys
|
||||
* @addtogroup base
|
||||
*/
|
||||
class GTSAM_EXPORT DSFVector {
|
||||
class GTSAM_EXPORT DSFBase {
|
||||
|
||||
public:
|
||||
typedef std::vector<size_t> V; ///< Vector of ints
|
||||
|
||||
private:
|
||||
boost::shared_ptr<V> v_;///< Stores parent pointers, representative iff v[i]==i
|
||||
std::vector<size_t> keys_;///< stores keys
|
||||
|
||||
public:
|
||||
/// constructor that allocate new memory, allows for keys 0...numNodes-1
|
||||
DSFBase(const size_t numNodes);
|
||||
|
||||
/// constructor that uses the existing memory
|
||||
DSFBase(const boost::shared_ptr<V>& v_in);
|
||||
|
||||
/// find the label of the set in which {key} lives
|
||||
size_t findSet(size_t key) const;
|
||||
|
||||
/// the in-place version of makeUnion
|
||||
void makeUnionInPlace(const size_t& i1, const size_t& i2);
|
||||
};
|
||||
|
||||
/**
|
||||
* A fast implementation of disjoint set forests that uses vector as underly data structure.
|
||||
* @addtogroup base
|
||||
*/
|
||||
class GTSAM_EXPORT DSFVector: public DSFBase {
|
||||
|
||||
private:
|
||||
std::vector<size_t> keys_;///< stores keys to support more expensive operations
|
||||
|
||||
public:
|
||||
/// constructor that allocate new memory, uses sequential keys 0...numNodes-1
|
||||
|
@ -49,17 +72,6 @@ public:
|
|||
/// constructor that uses the existing memory
|
||||
DSFVector(const boost::shared_ptr<V>& v_in, const std::vector<size_t>& keys);
|
||||
|
||||
/// find the label of the set in which {key} lives
|
||||
inline size_t findSet(size_t key) const {
|
||||
size_t parent = (*v_)[key];
|
||||
// follow parent pointers until we reach set representative
|
||||
while (parent != key) {
|
||||
key = parent;
|
||||
parent = (*v_)[key];
|
||||
}
|
||||
return parent;
|
||||
}
|
||||
|
||||
/// find whether there is one and only one occurrence for the given {label}
|
||||
bool isSingleton(const size_t& label) const;
|
||||
|
||||
|
@ -71,9 +83,6 @@ public:
|
|||
|
||||
/// return all sets, i.e. a partition of all elements
|
||||
std::map<size_t, std::vector<size_t> > arrays() const;
|
||||
|
||||
/// the in-place version of makeUnion
|
||||
void makeUnionInPlace(const size_t& i1, const size_t& i2);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -186,9 +186,6 @@ TEST(DSFVector, mergePairwiseMatches) {
|
|||
BOOST_FOREACH(const Match& m, matches)
|
||||
dsf.makeUnionInPlace(m.first,m.second);
|
||||
|
||||
cout << endl;
|
||||
map<size_t, set<size_t> > sets1 = dsf.sets();
|
||||
|
||||
// Each point is now associated with a set, represented by one of its members
|
||||
size_t rep1 = 1, rep2 = 4;
|
||||
EXPECT_LONGS_EQUAL(rep1,dsf.findSet(1));
|
||||
|
@ -199,16 +196,13 @@ TEST(DSFVector, mergePairwiseMatches) {
|
|||
EXPECT_LONGS_EQUAL(rep2,dsf.findSet(6));
|
||||
|
||||
// Check that we have two connected components, 1,2,3 and 4,5,6
|
||||
cout << endl;
|
||||
map<size_t, set<size_t> > sets = dsf.sets();
|
||||
LONGS_EQUAL(2, sets.size());
|
||||
set<size_t> expected1; expected1 += 1,2,3;
|
||||
set<size_t> actual1 = sets[rep1];
|
||||
BOOST_FOREACH(size_t i, actual1) cout << i << " ";
|
||||
EXPECT(expected1 == actual1);
|
||||
set<size_t> expected2; expected2 += 4,5,6;
|
||||
set<size_t> actual2 = sets[rep2];
|
||||
BOOST_FOREACH(size_t i, actual2) cout << i << " ";
|
||||
EXPECT(expected2 == actual2);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue