C Boost图:如何自定义回调函数VF2_PRINT_CALLBACK中的VF2_SUBGRAP_ISO.HPP

C++ Boost Graph: How to customize callback function vf2_print_callback in vf2_subgrap_iso.hpp

本文关键字:VF2 PRINT CALLBACK SUBGRAP HPP ISO 中的 函数 Boost 回调 自定义      更新时间:2023-10-16

背景:

我在VF2_SUB_GRAPH_ISO.HPP中使用boost::vf2_subgraph_iso(graph1, graph2, callback)。在boost提供的样本中,他们使用boost::vf2_print_callback<graph_type, graph_type> callback(graph1, graph2)将顶点对打印到终端。

我做了什么:

我想自定义回调函数,以便一旦boost::vf2_subgraph_iso(graph1, graph2, callback)称呼它,它将调用我的回调函数。我要自定义回调函数的原因是我想将顶点对存储在向量中,而不是在终端中打印它们。

以下是我到目前为止的工作:

#include <utility>
#include <vector>
#include <fstream>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/vf2_sub_graph_iso.hpp>
#include <boost/graph/graphviz.hpp>
template <typename Graph1,
            typename Graph2>
class my_call_back {
public:
    // constructor
    my_call_back(const Graph1& graph1, const Graph2& graph2) : graph1_(graph1), graph2_(graph2) {}
    template <typename CorrespondenceMap1To2, typename CorrespondenceMap2To1>
    bool operator()(CorrespondenceMap1To2 f, CorrespondenceMap2To1) {
        BGL_FORALL_VERTICES_T(v, graph1_, Graph1)
            vertex_iso_map.push_back(std::make_pair( get(boost::vertex_index_t(), graph1_, v) , get(boost::vertex_index_t(), graph2_, get(f, v))));
            set_of_vertex_iso_map.push_back(vertex_iso_map);
            vertex_iso_map.clear();
        return true;
    }
    std::vector <std::vector <std::pair<int, int>>> get_setvmap() { return set_of_vertex_iso_map; }
private:
    const Graph1& graph1_;
    const Graph2& graph2_;
    std::vector <std::vector <std::pair<int, int>>> set_of_vertex_iso_map;
    std::vector <std::pair<int, int>> vertex_iso_map;   
};
int main()
{
    typedef boost::adjacency_list<boost::setS, boost::vecS, boost::undirectedS> GraphType;
    std::ifstream dot_small("small.dot");
    std::ifstream dot_large("large.dot");
    std::ofstream subgraph_iso_output("large1.dot");
    GraphType graph_small, graph_large;
    boost::dynamic_properties dp(boost::ignore_other_properties);
    boost::read_graphviz(dot_small, graph_small, dp);
    boost::read_graphviz(dot_large, graph_large, dp);
    my_call_back<GraphType, GraphType> callback(graph_small, graph_large);
    boost::vf2_subgraph_iso(graph_small, graph_large, callback);
    // get vector from callback
    auto set_of_vertex_iso_map = callback.get_setvmap();
    // output vector size here
    std::cout << set_of_vertex_iso_map.size() << std::endl;
    for (auto set_of_v : set_of_vertex_iso_map)
    {
        for (auto v : set_of_v)
            std::cout << "(" << v.first << ", " << v.second << ")" << " ";
        std::cout << std::endl;
    }
    boost::write_graphviz(subgraph_iso_output, graph_small);
    return 0;
}

我的问题:

调用boost::vf2_subgraph_iso函数后,我决定从对象callback获取向量。但是似乎向量总是空的。我认为与Iteration_macros.hpp中定义的BGL_FORALL_VERTICES_T宏有关系,但是当我查看它时,我找不到任何线索。我猜是:也许vf2_subgraph_iso函数调用的回调使新的my_callback对象并在完成功能时将其销毁。但是该函数如何使新的my_callback对象?我不明白。我该如何解决?(现在,我只能将向量设置为全局变量以使其正常工作,这是一个可怕的选择(

两个问题:

bool operator()(CorrespondenceMap1To2 f, CorrespondenceMap2To1) {
    BGL_FORALL_VERTICES_T(v, graph1_, Graph1)
        vertex_iso_map.push_back(std::make_pair( get(boost::vertex_index_t(), graph1_, v) , get(boost::vertex_index_t(), graph2_, get(f, v))));
        set_of_vertex_iso_map.push_back(vertex_iso_map);
        vertex_iso_map.clear();
    return true;
}

至少修复格式以表达意图:

bool operator()(CorrespondenceMap1To2 f, CorrespondenceMap2To1) {
    BGL_FORALL_VERTICES_T(v, graph1_, Graph1) {
        vertex_iso_map.emplace_back(get(boost::vertex_index_t(), graph1_, v), get(boost::vertex_index_t(), graph2_, get(f, v)));
    }
    set_of_vertex_iso_map.push_back(vertex_iso_map);
    vertex_iso_map.clear();
    return true;
}

真正的问题是:

boost::vf2_subgraph_iso(graph_small, graph_large, callback);

按值通过callback,作用于副本!通过参考:

boost::vf2_subgraph_iso(graph_small, graph_large, std::ref(callback));