【发布时间】:2021-03-24 14:42:06
【问题描述】:
我知道如何在 Boost 中计算连接组件的总数,但是有没有一种有效的方法可以使用 boost 的图形库来计算最大连接组件的大小。
【问题讨论】:
-
你有什么东西可以表明你的问题是关于什么的吗? 你知道如何做相关的事情不是/那个/信息。
标签: boost boost-graph
我知道如何在 Boost 中计算连接组件的总数,但是有没有一种有效的方法可以使用 boost 的图形库来计算最大连接组件的大小。
【问题讨论】:
标签: boost boost-graph
我认为最有效的方法是将component map 替换为自定义类型。
我创建了一个小的WritePropertyMap 来做到这一点:
template <typename V>
struct Mapper {
using Id = int; // component id
using Cardinality = int;
using Map = boost::container::flat_map<Id, Cardinality>;
using Value = Map::value_type;
Map& storage;
friend void put(Mapper& m, V const& /*v*/, Id id) { m.storage[id] += 1; }
Value largest() const {
return not storage.empty()
? *max_element(begin(storage), end(storage),
[](Value const& a, Value const& b) {
return a.second < b.second;
})
: Value{};
}
};
我们需要告诉 Boost 我们的属性图:
template <typename V> struct boost::property_traits<Mapper<V>> {
using category = boost::writable_property_map_tag;
using key_type = V;
using value_type = int;
};
注意
存储和属性映射之间的分离是因为属性映射是按值传递的 - 并且复制起来应该很便宜。
现在我们可以使用它了,稍微修改一下library example:
Mapper<V>::Map result;
Mapper<V> mapper{result};
int num = connected_components(g, mapper);
auto [id, cardinality] = mapper.largest();
std::cout << "Largest component #" << id << " (out of " << num
<< " components) has " << cardinality << " vertices\n";
打印
Largest component #0 (out of 3 components) has 3 vertices
这符合预期的输出。
如果您有预期数量的组件,您可以通过使用 small_vector/static_vector 来优化存储,例如
using Value = std::pair<Id, Cardinality>;
using Map = boost::container::flat_map<
Id, Cardinality, std::less<>,
boost::container::small_vector<Value, 10>>;
这样,除非您拥有超过 10 个组件,否则您将永远不会看到映射器存储的动态分配。
【讨论】: