了解boost :: disjoint_sets
我需要使用boost :: disjoint_sets,但文档不清楚。 有人可以请解释每个模板参数意味着什么,也许给一个小例子代码创build一个disjoint_sets?
根据请求,我使用disjoint_sets来实现Tarjan的离线最小公共祖先algorithm ,即 – 值types应该是vertex_descriptor。
我能从文档中了解到什么:
不相交需要将一个等级和一个父亲(在森林树中)关联到每个元素。 因为你可能想要处理任何types的数据,例如,你可能并不总是想使用父图的地图:使用整数数组就足够了。 你还需要排名敌人的每个元素(工会find所需的排名)。
你需要两个“属性”:
- 一个将一个整数与每个元素(第一个模板参数)关联起来
- 一个将元素与另一个元素(第二个模板参数)联系起来,父亲
举个例子:
std::vector<int> rank (100); std::vector<int> parent (100); boost::disjoint_sets<int*,int*> ds(&rank[0], &parent[0]);
数组使用&rank[0], &parent[0]
来模板中的types是int*
对于一个更复杂的例子(使用地图),你可以看看Ugo的答案。
你只是给algorithm两个结构来存储他需要的数据(排名/父母)。
disjoint_sets<Rank, Parent, FindCompress>
- Rank PropertyMap用于存储一个集合的大小(element – > std :: size_t)。 按级别查看联盟
- 父 PropertyMap用于存储元素的父元素(元素 – >元素)。 请参阅path压缩
- FindCompress定义查找方法的可选参数。 默认为
find_with_full_path_compression
请看这里 (默认应该是你需要的)。
例:
template <typename Rank, typename Parent> void algo(Rank& r, Parent& p, std::vector<Element>& elements) { boost::disjoint_sets<Rank,Parent> dsets(r, p); for (std::vector<Element>::iterator e = elements.begin(); e != elements.end(); e++) dsets.make_set(*e); ... } int main() { std::vector<Element> elements; elements.push_back(Element(...)); ... typedef std::map<Element,std::size_t> rank_t; // => order on Element typedef std::map<Element,Element> parent_t; rank_t rank_map; parent_t parent_map; boost::associative_property_map<rank_t> rank_pmap(rank_map); boost::associative_property_map<parent_t> parent_pmap(parent_map); algo(rank_pmap, parent_pmap, elements); }
请注意,“Boost属性映射库包含一些适配器,用于转换实现映射操作(如内置数组(指针),迭代器和std :: map)的常用数据结构,以使属性映射接口”
这些适配器的列表(如boost :: associative_property_map)可以在这里find。
对于那些无法负担std::map
开销的人(或者因为在类中没有默认构造函数而无法使用它),但是其数据不像int
那样简单,我写了一个指南到一个使用std::vector
的解决scheme,当您事先知道元素的总数时,这是一种最佳的解决scheme。
该指南包含一个完整的示例代码 ,您可以自行下载和testing。
这里提到的解决scheme假设你有类的代码的控制,所以特别是你可以添加一些属性。 如果这仍然是不可能的,你可以随时添加一个包装:
class Wrapper { UntouchableClass const& mInstance; size_t dsID; size_t dsRank; size_t dsParent; }
而且,如果你知道元素的数量很小,就不需要size_t
,在这种情况下,你可以为UnsignedInt
types添加一些模板,并在运行时决定使用uint8_t
, uint16_t
, uint32_t
或uint64_t
来实例化它,你可以在C ++ 11中用<cstdint>
获得,否则用boost::cstdint
。
template <typename UnsignedInt> class Wrapper { UntouchableClass const& mInstance; UnsignedInt dsID; UnsignedInt dsRank; UnsignedInt dsParent; }
如果您错过了链接,请再次input链接: http : //janoma.cl/post/using-disjoint-sets-with-a-vector/