我为boost::adjacency_list
写了一个小包装:
template <typename T>
using VertexWithIndexProperty =
boost::property<boost::vertex_index_t, int, T>;
template <typename VertexProperty, typename EdgeProperty =
boost::no_property>
class MutableGraph : public boost::adjacency_list< boost::setS,
boost::listS, boost::undirectedS,
VertexWithIndexProperty<VertexProperty>, EdgeProperty> {
public:
using BoostBase =
boost::adjacency_list<boost::setS, boost::listS, boost::undirectedS,
VertexWithIndexProperty<VertexProperty>,
EdgeProperty>;
MutableGraph() {}
MutableGraph(std::size_t n) : BoostBase(n) {}
MutableGraph(const MutableGraph &rhs) : BoostBase(rhs) {}
MutableGraph &operator=(const MutableGraph &rhs) {
static_cast<BoostBase *>(this)->operator=(rhs);
return *this;
}
};
然后我按如下方式使用它:我收集了一些vertex_descriptor集以创建boost::filtered_graph
:
`
using Graph = MutableGraph<boost::property<vertex_color_t, int>>;
Graph g;
std::set<int> C, H; //vertex_descriptors I collect
...
auto vertex_index_map = get(vertex_index, g);
std::function<bool(vertex_descriptor)> vertexes_filter =
[&vertex_index_map, &C, &H](vertex_descriptor v) {
auto index = vertex_index_map[v];
return C.find(index) != C.end() || H.find(index) != H.end();
};
boost::filtered_graph<Graph, boost::keep_all, decltype(crown_vertexes_filter)>
auxilary(g, boost::keep_all(), crown_vertexes_filter);
一切都很好,但是当我尝试获取顶点的任何property_map时,例如:`
auto auxilary_vertex_index_map
= get(boost::vertex_index, auxilary);
我收到以下错误:
could not convert
boost::adj_list_vertex_property_map<boost::adjacency_list<boost::setS,
boost::listS, boost::undirectedS,
boost::property<boost::vertex_index_t, int,
boost::property<boost::vertex_color_t, int> >,
boost::no_property, boost::no_property, boost::listS>, int,
int&, boost::vertex_index_t>
to
boost::adj_list_vertex_property_map<MutableGraph<
boost::property<boost::vertex_color_t, int> >,
int,
int&,
boost::vertex_index_t>
我在
中遇到此错误template <typename G, typename EP, typename VP, typename Property>
typename property_map<G, Property>::type
get(Property p, filtered_graph<G, EP, VP>& g)
{
return get(p, const_cast<G&>(g.m_g));
}
在filtered_graph.hpp
中。
我不明白为什么会这样,无论是因为我的包装器还是因为我决定使用嵌套属性而不是捆绑属性。
谢谢!
答案 0 :(得分:2)
嵌套属性被称为“内部属性”。他们不是你的问题。
相反,您的问题出在VertexContainerSelector参数(= 0.983802108362677,
)上。导致= 1,
类型为
您已经知道这一点,这就是为什么添加一个属性以用作顶点索引图的原因。但是,您没有想到的是,它使= 0.00201102356142246,
属性映射(= 0.638580957139582,
)的结果类型有所不同,因此= 0.121254171582127,
中的转发包装器不适合不再收费:
= 0.857057426831322,
如果您有足够的能力切换到boost::listS
,我会选择的。否则,请仔细考虑您的要求及其含义。值得注意的是,您选择的vertex_descriptor
vertex_index
会导致boost::property_map<Graph, vertex_index_t>::type
具有参考稳定性和迭代器稳定性。 filter_graph中的任何filtered_graph
对于主图都应有效,反之亦然¹。为什么不保留相同的地图:
template <typename G, typename EP, typename VP, typename Property>
typename property_map<G, Property>::type
get(Property p, filtered_graph<G, EP, VP>& g)
{
return get(p, const_cast<G&>(g.m_g));
}
打印:
vecS
正是您想要的。
请注意代码中的简化。您的VertexContainerSelector
类可以写为:
listS
尽管在此示例中,甚至可以省略这两个成员(vertex_descriptor
仍将由编译器正确生成)。
¹,也许是经过过滤的...
根据评论进行更新:您可以通过专门化vertex_descriptor
特性来“自动”执行类型转发:
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/filtered_graph.hpp>
#include <boost/graph/graph_utility.hpp> // print_graph
template <typename T> using AddIndex = boost::property<boost::vertex_index_t, int, T>;
template <
typename VertexProperty,
typename EdgeProperty = boost::no_property,
typename Base = boost::adjacency_list<boost::setS, boost::listS, boost::undirectedS, AddIndex<VertexProperty>, EdgeProperty> >
struct MutableGraph : Base {
using BoostBase = Base;
MutableGraph(std::size_t n = 0) : BoostBase(n) {}
using BoostBase::operator=;
};
int main() {
using Graph = MutableGraph<boost::property<boost::vertex_color_t, int> >;
using vertex_descriptor = Graph::vertex_descriptor;
Graph g;
auto a = add_vertex({1, 0}, g);
auto b = add_vertex({2, 0}, g);
auto c = add_vertex({3, 0}, g);
auto d = add_vertex({4, 0}, g);
add_edge(a, b, g);
add_edge(a, c, g);
add_edge(b, d, g);
std::set<int> C{1,2}, H{/*3,*/4}; // vertex_descriptors I collect
auto id = get(boost::vertex_index, g);
std::function<bool(vertex_descriptor)> vertexes_filter = [id, &C, &H](vertex_descriptor v) {
auto index = id[v];
return C.count(index) || H.count(index);
};
boost::filtered_graph<Graph, boost::keep_all, decltype(vertexes_filter)> auxilary(g, boost::keep_all(), vertexes_filter);
auto aux_id = id;
print_graph(g, id, std::cout << "\n---- Original\n");
print_graph(auxilary, aux_id, std::cout << "\n---- Filtered\n");
}
仅此而已。现在,您可以从不知道要处理的图形类型的函数中进行打印:
---- Original
1 <--> 2 3
2 <--> 1 4
3 <--> 1
4 <--> 2
---- Filtered
1 <--> 2
2 <--> 1 4
4 <--> 2
MutableGraph
仅因专业而起作用:
template <
typename VertexProperty,
typename EdgeProperty = boost::no_property,
typename Base = boost::adjacency_list<boost::setS, boost::listS, boost::undirectedS, AddIndex<VertexProperty>, EdgeProperty> >
struct MutableGraph : Base {
using BoostBase = Base;
MutableGraph(std::size_t n = 0) : BoostBase(n) {}
using BoostBase::operator=;
};