如何使用 boost::vf2_subgraph_iso 获取边缘映射
How to get the edge mapping with boost::vf2_subgraph_iso
boost::vf2_subgraph_iso
应该在给定的大图中找到给定的小图的诱导子图。传递给它的回调将获得一个映射作为输入。
template <typename CorrespondenceMap1To2, typename CorrespondenceMap2To1>
bool operator()(CorrespondenceMap1To2 f, CorrespondenceMap2To1 g) const{
// boost::get(f, u) maps u in small to v in large
}
但是文档只提到了顶点映射。我知道可以通过映射每条边的源和目标来理解边映射。但我需要映射边的捆绑属性。
似乎 boost::get
不适用于映射和边缘描述符。 boost::get(f, e)
产生以下错误消息。
error: no match for ‘operator[]’ (operand types are ‘const boost::iterator_property_map<__gnu_cxx::__normal_iterator<long unsigned int*, std::vector<long unsigned int, std::allocator<long unsigned int> > >, boost::vec_adj_list_vertex_id_map<bya::util::isomorphism::vertex_data, long unsigned int>, long unsigned int, long unsigned int&>’ and ‘const boost::detail::edge_desc_impl<boost::bidirectional_tag, long unsigned int>’)
是的,映射不适用于边描述符,因为它们不是顶点描述符。
我建议在 "other" 图中查找边缘。所以,例如
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/vf2_sub_graph_iso.hpp>
using namespace boost;
struct VBundle { std::string name; };
struct EBundle { int data = 0; };
using G = adjacency_list<vecS, vecS, bidirectionalS, VBundle, EBundle>;
using Edge = G::edge_descriptor;
int main() {
G small(4), large(5);
small[0].name = "zero";
small[1].name = "one";
small[2].name = "two";
small[3].name = "three";
add_edge(0, 1, {33}, small);
add_edge(1, 3, {44}, small);
add_edge(2, 3, {55}, small);
add_edge(4, 2, large); // 0->4, 1->2, 3->0, 2->3
add_edge(2, 0, large);
add_edge(3, 0, large);
auto cb = [&](auto&& f, auto&&) {
for (auto small_vd: make_iterator_range(vertices(small))) {
auto large_vd = get(f, small_vd);
std::cout << '(' << small_vd << ", " << large_vd << ") ";
large[large_vd] = small[small_vd];
for (Edge small_ed: make_iterator_range(out_edges(small_vd, small))) {
auto large_src = get(f, source(small_ed, small));
auto large_tgt = get(f, target(small_ed, small));
auto [large_ed, found] = edge(large_src, large_tgt, large);
assert(found);
// e.g. copy edge bundle to the smaller graph
large[large_ed] = small[small_ed];
}
}
std::cout << std::endl;
return true;
};
bool ok = vf2_subgraph_iso(small, large, cb);
std::cout << std::boolalpha << ok << "\n";
}
这会打印
(0, 4) (1, 2) (2, 3) (3, 0)
true
但也将相应的顶点和边束从小图复制到大图。
boost::vf2_subgraph_iso
应该在给定的大图中找到给定的小图的诱导子图。传递给它的回调将获得一个映射作为输入。
template <typename CorrespondenceMap1To2, typename CorrespondenceMap2To1>
bool operator()(CorrespondenceMap1To2 f, CorrespondenceMap2To1 g) const{
// boost::get(f, u) maps u in small to v in large
}
但是文档只提到了顶点映射。我知道可以通过映射每条边的源和目标来理解边映射。但我需要映射边的捆绑属性。
似乎 boost::get
不适用于映射和边缘描述符。 boost::get(f, e)
产生以下错误消息。
error: no match for ‘operator[]’ (operand types are ‘const boost::iterator_property_map<__gnu_cxx::__normal_iterator<long unsigned int*, std::vector<long unsigned int, std::allocator<long unsigned int> > >, boost::vec_adj_list_vertex_id_map<bya::util::isomorphism::vertex_data, long unsigned int>, long unsigned int, long unsigned int&>’ and ‘const boost::detail::edge_desc_impl<boost::bidirectional_tag, long unsigned int>’)
是的,映射不适用于边描述符,因为它们不是顶点描述符。
我建议在 "other" 图中查找边缘。所以,例如
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/vf2_sub_graph_iso.hpp>
using namespace boost;
struct VBundle { std::string name; };
struct EBundle { int data = 0; };
using G = adjacency_list<vecS, vecS, bidirectionalS, VBundle, EBundle>;
using Edge = G::edge_descriptor;
int main() {
G small(4), large(5);
small[0].name = "zero";
small[1].name = "one";
small[2].name = "two";
small[3].name = "three";
add_edge(0, 1, {33}, small);
add_edge(1, 3, {44}, small);
add_edge(2, 3, {55}, small);
add_edge(4, 2, large); // 0->4, 1->2, 3->0, 2->3
add_edge(2, 0, large);
add_edge(3, 0, large);
auto cb = [&](auto&& f, auto&&) {
for (auto small_vd: make_iterator_range(vertices(small))) {
auto large_vd = get(f, small_vd);
std::cout << '(' << small_vd << ", " << large_vd << ") ";
large[large_vd] = small[small_vd];
for (Edge small_ed: make_iterator_range(out_edges(small_vd, small))) {
auto large_src = get(f, source(small_ed, small));
auto large_tgt = get(f, target(small_ed, small));
auto [large_ed, found] = edge(large_src, large_tgt, large);
assert(found);
// e.g. copy edge bundle to the smaller graph
large[large_ed] = small[small_ed];
}
}
std::cout << std::endl;
return true;
};
bool ok = vf2_subgraph_iso(small, large, cb);
std::cout << std::boolalpha << ok << "\n";
}
这会打印
(0, 4) (1, 2) (2, 3) (3, 0)
true
但也将相应的顶点和边束从小图复制到大图。