C++ Boost图在子图中查找边

C++ Boost图在子图中查找边,c++,boost,graph,subgraph,C++,Boost,Graph,Subgraph,有一个图G0和子图G1…G7,我想找到子图G1…G7集合中G7的出现,在这种特殊情况下,输出应该是G7,在5中, 七国集团在7国集团 但它不起作用,输出是G7在4位, G7在第6位, G7是在7。 我真的不明白错误在哪里。(可能是循环) #包括 #包括 #包括 #包括 #包括 #包括 使用名称空间boost; typedef子图图形; int阈值=3; _数据库的int size_=7; int main(int,char*[]) { 常数int N=6; 图G0(N); 枚举{A,B,C,D,

有一个图G0和子图G1…G7,我想找到子图G1…G7集合中G7的出现,在这种特殊情况下,输出应该是G7,在5中, 七国集团在7国集团 但它不起作用,输出是G7在4位, G7在第6位, G7是在7。 我真的不明白错误在哪里。(可能是循环)

#包括
#包括
#包括
#包括
#包括
#包括
使用名称空间boost;
typedef子图<邻接列表,属性>>图形;
int阈值=3;
_数据库的int size_=7;
int main(int,char*[])
{
常数int N=6;
图G0(N);
枚举{A,B,C,D,E,F};//用于方便地引用G0中的顶点
图&G1=G0。创建_子图();
图&G2=G0。创建_子图();
图形&G3=G0。创建_子图();
Graph&G4=G0.create_子图();
Graph&G5=G0.create_子图();
图形&G6=G0。创建_子图();
Graph&G7=G0.create_子图();
枚举{A1,B1,C1};//用于方便地引用G1中的顶点
枚举{A2,B2};//用于方便地引用G2中的顶点
枚举{A3,B3};
枚举{A4,B4,C4};
枚举{A5,B5};
枚举{A6,B6,C6};
枚举{A7,B7};
添加_顶点(C,G1);//全局顶点C成为G1的局部A1
添加_顶点(E,G1);//全局顶点E成为G1的局部B1
添加_顶点(F,G1);//全局顶点F成为G1的局部C1
添加_顶点(A,G2);//全局顶点A变为G2的局部A1
添加_顶点(B,G2);//全局顶点B成为G2的局部B1
添加_顶点(B,G3);/…-| |-。。。
添加_顶点(C,G3);
添加_顶点(A,G4);
添加_顶点(B,G4);
添加_顶点(E,G4);
添加_顶点(F,G5);
添加_顶点(D,G5);
添加_顶点(B,G6);
添加_顶点(D,G6);
添加_顶点(E,G6);
添加_顶点(F,G7);
添加_顶点(D,G7);
添加_边(A、B、G0);
添加_边(B、C、G0);
添加_边(B、D、G0);
添加_边(E、B、G0);
添加_边(E、F、G0);
添加_边(F、D、G0);
加法边(F,C,G1);/(A1,C1)是(C,F)的子图G1局部索引。
图::子迭代器ci,ci_end;
图::边迭代器ei,ei\u end;
int nj=0;
int g_n=1;
for(tie(ci,ci_end)=G0.children();ci!=ci_end;++ci){
对于(连接(ei,ei_端)=边(G7);ei!=ei_端;++ei){
if(边(G7.局部到全局(源(*ei,G7)),G7.局部到全局(目标(*ei,G7)),*ci).second)nj++;
};

如果(nj==num_edges(G7))std::cout我想您应该计算包含G7中边的子图的数量

线路

if (edge(G7.local_to_global(source(*ei, G7)), G7.local_to_global(target(*ei, G7)), *ci).second)
似乎出错了,因为它使用全局顶点ID在
*ci
中查找边,这是它的任何子图

每个子图都有自己的顶点和边描述符,我们称之为局部描述符。我们将根图的顶点和边描述符称为全局描述符

这将更接近您的预期:

auto gs = G7.local_to_global(source(*ei, G7));
auto gt = G7.local_to_global(target(*ei, G7));

auto ls = ci->global_to_local(gs);
auto lt = ci->global_to_local(gt);

std::cout << "global (" << gs << "," << gt << ") local (" << ls << "," << gt << ")\n";

if (edge(ls, lt, *ci).second)
    nj++;

演示 对样式进行了轻微重构:

#include <boost/config.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graph_utility.hpp>
#include <boost/graph/lookup_edge.hpp>
#include <boost/graph/subgraph.hpp>
#include <iostream>

using namespace boost;

typedef subgraph<adjacency_list<vecS, vecS, directedS, property<vertex_color_t, int>, property<edge_index_t, int>>>
    Graph;

int constexpr threshold = 3;
int constexpr size_of_database = 7;

template <typename G>
bool is_subgraph_present(G const& g, G const& other) {
    Graph::edge_iterator ei, ei_end;
    unsigned nj = 0;
    for (tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) {

        auto gs = g.local_to_global(source(*ei, g));
        auto gt = g.local_to_global(target(*ei, g));
        //std::cout << "global (" << gs << "," << gt << ")\n";

        auto ls = other.find_vertex(gs);
        auto lt = other.find_vertex(gt);

        if (ls.second && lt.second) {
            //std::cout << "global (" << gs << "," << gt << ") local (" << ls.first << "," << lt.first << ")\n";

            if (edge(ls.first, lt.first, other).second)
                nj++;
        }
    }
    return nj == num_edges(g);
}


int main() {
    const int N = 6;
    enum { A, B, C, D, E, F }; // for conveniently refering to vertices in G0

    Graph G0(N);
    Graph& G1 = G0.create_subgraph();
    Graph& G2 = G0.create_subgraph();
    Graph& G3 = G0.create_subgraph();
    Graph& G4 = G0.create_subgraph();
    Graph& G5 = G0.create_subgraph();
    Graph& G6 = G0.create_subgraph();
    Graph& G7 = G0.create_subgraph();

    enum { A1, B1, C1 }; // for conveniently refering to vertices in G1
    enum { A2, B2 };     // for conveniently refering to vertices in G2
    enum { A3, B3 };
    enum { A4, B4, C4 };
    enum { A5, B5 };
    enum { A6, B6, C6 };
    enum { A7, B7 };

    add_vertex(C, G1); // global vertex C becomes local A1 for G1
    add_vertex(E, G1); // global vertex E becomes local B1 for G1
    add_vertex(F, G1); // global vertex F becomes local C1 for G1

    add_vertex(A, G2); // global vertex A becomes local A1 for G2
    add_vertex(B, G2); // global vertex B becomes local B1 for G2

    add_vertex(B, G3); // ...-||-...
    add_vertex(C, G3);

    add_vertex(A, G4);
    add_vertex(B, G4);
    add_vertex(E, G4);

    add_vertex(F, G5);
    add_vertex(D, G5);

    add_vertex(B, G6);
    add_vertex(D, G6);
    add_vertex(E, G6);

    add_vertex(F, G7);
    add_vertex(D, G7);

    add_edge(A, B, G0);
    add_edge(B, C, G0);
    add_edge(B, D, G0);
    add_edge(E, B, G0);
    add_edge(E, F, G0);
    add_edge(F, D, G0);

    //add_edge(F, C, G1); // (A1,C1) is subgraph G1 local indices for (C,F).

    Graph::children_iterator ci, ci_end;

    int g_n = 1;

    for (tie(ci, ci_end) = G0.children(); ci != ci_end; ++ci) {
        if (is_subgraph_present(G7, *ci)) {
            std::cout << "G7 is in G" << g_n << std::endl;
        }
        g_n++;
    }

    std::cout << "G0:" << std::endl;
    print_graph(G0, get(vertex_index, G0));
    print_edges2(G0, get(vertex_index, G0), get(edge_index, G0));
    std::cout << std::endl;

    int num = 1;
    for (boost::tie(ci, ci_end) = G0.children(); ci != ci_end; ++ci) {
        std::cout << "G" << num++ << ":" << std::endl;
        print_graph(*ci, get(vertex_index, *ci));
        print_edges2(*ci, get(vertex_index, *ci), get(edge_index, *ci));
        std::cout << std::endl;
    }
}

你是什么意思,“G7在n中”-一个子图在“一个数字”中?这并不是说G7在Gn中,很抱歉这一行
add_edge(F,C,G1);
是错误的(正如valgrind或ubsan/asan会告诉你的),所以对于G7来说,输出应该是G7在G5中,G7在G7中,这意味着G7是G5的子图,也是G7的子图(琐碎)应该是add_edge(C1、A1、G1),还是它错了?添加了一个固定版本的实时演示是的,它工作得很好,但我不确定auto做什么。你能推荐一些研究Boost图形库的文献吗?
auto
推断类型(所以你不必键入
Graph::vertex\u descriptor
或例如
std::pair ls;
我正在努力使用mcgregor\u common\u子图函数,我想找到子图集合中最大的公共子图。所以有一个图G0和一组子图G1…G7,我想找到G1…G7中最大的公共子图,可以吗你能帮忙吗?
auto gs = G7.local_to_global(source(*ei, G7));
auto gt = G7.local_to_global(target(*ei, G7));
std::cout << "global (" << gs << "," << gt << ")\n";

auto ls = ci->find_vertex(gs);
auto lt = ci->find_vertex(gt);

if (ls.second && lt.second) {
    std::cout << "global (" << gs << "," << gt << ") local (" << ls.first << "," << lt.first << ")\n";

    if (edge(ls.first, lt.first, *ci).second)
        nj++;
}
#include <boost/config.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graph_utility.hpp>
#include <boost/graph/lookup_edge.hpp>
#include <boost/graph/subgraph.hpp>
#include <iostream>

using namespace boost;

typedef subgraph<adjacency_list<vecS, vecS, directedS, property<vertex_color_t, int>, property<edge_index_t, int>>>
    Graph;

int constexpr threshold = 3;
int constexpr size_of_database = 7;

template <typename G>
bool is_subgraph_present(G const& g, G const& other) {
    Graph::edge_iterator ei, ei_end;
    unsigned nj = 0;
    for (tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) {

        auto gs = g.local_to_global(source(*ei, g));
        auto gt = g.local_to_global(target(*ei, g));
        //std::cout << "global (" << gs << "," << gt << ")\n";

        auto ls = other.find_vertex(gs);
        auto lt = other.find_vertex(gt);

        if (ls.second && lt.second) {
            //std::cout << "global (" << gs << "," << gt << ") local (" << ls.first << "," << lt.first << ")\n";

            if (edge(ls.first, lt.first, other).second)
                nj++;
        }
    }
    return nj == num_edges(g);
}


int main() {
    const int N = 6;
    enum { A, B, C, D, E, F }; // for conveniently refering to vertices in G0

    Graph G0(N);
    Graph& G1 = G0.create_subgraph();
    Graph& G2 = G0.create_subgraph();
    Graph& G3 = G0.create_subgraph();
    Graph& G4 = G0.create_subgraph();
    Graph& G5 = G0.create_subgraph();
    Graph& G6 = G0.create_subgraph();
    Graph& G7 = G0.create_subgraph();

    enum { A1, B1, C1 }; // for conveniently refering to vertices in G1
    enum { A2, B2 };     // for conveniently refering to vertices in G2
    enum { A3, B3 };
    enum { A4, B4, C4 };
    enum { A5, B5 };
    enum { A6, B6, C6 };
    enum { A7, B7 };

    add_vertex(C, G1); // global vertex C becomes local A1 for G1
    add_vertex(E, G1); // global vertex E becomes local B1 for G1
    add_vertex(F, G1); // global vertex F becomes local C1 for G1

    add_vertex(A, G2); // global vertex A becomes local A1 for G2
    add_vertex(B, G2); // global vertex B becomes local B1 for G2

    add_vertex(B, G3); // ...-||-...
    add_vertex(C, G3);

    add_vertex(A, G4);
    add_vertex(B, G4);
    add_vertex(E, G4);

    add_vertex(F, G5);
    add_vertex(D, G5);

    add_vertex(B, G6);
    add_vertex(D, G6);
    add_vertex(E, G6);

    add_vertex(F, G7);
    add_vertex(D, G7);

    add_edge(A, B, G0);
    add_edge(B, C, G0);
    add_edge(B, D, G0);
    add_edge(E, B, G0);
    add_edge(E, F, G0);
    add_edge(F, D, G0);

    //add_edge(F, C, G1); // (A1,C1) is subgraph G1 local indices for (C,F).

    Graph::children_iterator ci, ci_end;

    int g_n = 1;

    for (tie(ci, ci_end) = G0.children(); ci != ci_end; ++ci) {
        if (is_subgraph_present(G7, *ci)) {
            std::cout << "G7 is in G" << g_n << std::endl;
        }
        g_n++;
    }

    std::cout << "G0:" << std::endl;
    print_graph(G0, get(vertex_index, G0));
    print_edges2(G0, get(vertex_index, G0), get(edge_index, G0));
    std::cout << std::endl;

    int num = 1;
    for (boost::tie(ci, ci_end) = G0.children(); ci != ci_end; ++ci) {
        std::cout << "G" << num++ << ":" << std::endl;
        print_graph(*ci, get(vertex_index, *ci));
        print_edges2(*ci, get(vertex_index, *ci), get(edge_index, *ci));
        std::cout << std::endl;
    }
}
7 is in G5
G7 is in G7
G0:
0 --> 1 
1 --> 2 3 
2 --> 
3 --> 
4 --> 1 5 
5 --> 3 
0(0,1) 1(1,2) 2(1,3) 3(4,1) 4(4,5) 5(5,3) 

G1:
0 --> 
1 --> 2 
2 --> 
4(1,2) 

G2:
0 --> 1 
1 --> 
0(0,1) 

G3:
0 --> 1 
1 --> 
1(0,1) 

G4:
0 --> 1 
1 --> 
2 --> 1 
0(0,1) 3(2,1) 

G5:
0 --> 1 
1 --> 
5(0,1) 

G6:
0 --> 1 
1 --> 
2 --> 0 
2(0,1) 3(2,0) 

G7:
0 --> 1 
1 --> 
5(0,1)