简体   繁体   English

Boost Graph边缘比较不起作用

[英]Boost Graph edge comparison not working

I'm trying to do some statistics with graphs (comparing 2 graphs). 我正在尝试对图形进行一些统计(比较2个图形)。 But have a problem when I compare the edges. 但是当我比较边缘时会有问题。

So, I create two graphs with some edges and then some templates for the vertices and edges operations. 因此,我创建了两个带有一些边的图形,然后创建了一些用于顶点和边操作的模板。 For the vertices it's working apperently well, but for the edges it's not working properly. 对于顶点,它工作得很好,但是对于边缘,则工作不正常。

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/reverse_graph.hpp>
#include <boost/graph/iteration_macros.hpp>
#include <boost/graph/graph_utility.hpp>
typedef boost::adjacency_list < boost::vecS, boost::vecS,
                            boost::undirectedS > Graph;

template <typename T> std::set<T> operator-(const std::set<T>& a,
                                            const std::set<T>& b)
{
    std::set<T> r;
    std::set_difference(
                        a.begin(), a.end(),
                        b.begin(), b.end(),
                        std::inserter(r, r.end()));

    return r;
}

template <typename T> std::set<T> operator/(const std::set<T>& a,
                                            const std::set<T>& b)
{
    std::set<T> r;
    std::set_intersection(
                          a.begin(), a.end(),
                          b.begin(), b.end(),
                          std::inserter(r, r.end()));

    return r;
}



void compare(const Graph& a, const Graph& b)
{
    std::set<Graph::vertex_descriptor > av, bv, samev, extrav, missingv;
    std::set<Graph::edge_descriptor> ae, be, re, samee, extrae, missinge;

    BGL_FORALL_VERTICES_T(v, a, Graph) av.insert(v);
    BGL_FORALL_VERTICES_T(v, b, Graph) bv.insert(v);
    samev    = (av / bv);
    extrav   = (bv - av);
    missingv = (av - bv);


    BGL_FORALL_EDGES_T(e, a, Graph) ae.insert(e);
    BGL_FORALL_EDGES_T(e, b, Graph) be.insert(e);

    samee    = (ae / be);
    extrae   = (be - ae);
    missinge = (ae - be);

    // TODO(silgon): reverse_graph
    // boost::reverse_graph<Graph> r(b);
    // BGL_FORALL_EDGES_T(e, r, Graph) re.insert(e);
    std::cout << "---- Vertices ----\n"
              << "same: " << samev.size() << std::endl
              << "extra: " << extrav.size() << std::endl
              << "missing: " << missingv.size() << std::endl;

    std::cout << "---- Edges ----\n"
              << "same: " << samee.size() << std::endl
              << "extra: " << extrae.size() << std::endl
              << "missing: " << missinge.size() << std::endl;
}

int main()
{
    Graph a;
    {
        boost::graph_traits<Graph>::vertex_descriptor v, u, y;
        u = boost::vertex(1, a);
        v = boost::vertex(2, a);
        y = boost::vertex(3, a);
        boost::add_edge(u, v, a);
    }
    Graph b;
    {
        boost::graph_traits<Graph>::vertex_descriptor v, u, y;
        u = vertex(1, b);
        v = vertex(2, b);
        y = vertex(3, b);
        boost::add_edge(u, v, b);
        boost::add_edge(y, v, b);
    }

    const char* name = "123456";
    std::cout << "---Graph1---" << "\n";
    boost::print_graph(a);
    std::cout << "Edges: ";
    boost::print_edges(a,name);
    std::cout << "---Graph2---" << "\n";
    boost::print_graph(b);
    std::cout << "Edges: ";
    boost::print_edges(b,name);

    compare(a,b);
}

As for the result of the program it's the following: 至于程序的结果如下:

---Graph1---
0 <--> 
1 <--> 2 
2 <--> 1 
Edges: (2,3) 
---Graph2---
0 <--> 
1 <--> 2 
2 <--> 1 3 
3 <--> 2 
Edges: (2,3) (4,3) 
---- Vertices ----
same: 3
extra: 1
missing: 0
---- Edges ----
same: 0
extra: 2
missing: 1

You can see that one of the edges is the same (2,3), but when doing the operations it's not taking it into account so in the results it say same:0, and either extra or missing results are not working. 您可以看到边之一相同(2,3),但是在执行操作时并未考虑到边,因此在结果中将其说为same:0,并且多余或缺失的结果均不起作用。

Digging into Boost's edge_descriptor implementation (in boost/graph/detail/edge.hpp , we find that every edge descriptor stores the source and target vertex_descriptor s, but also a pointer to an edge property. This pointer is different for the two edges whose vertex_descriptor s are otherwise identical. 深入研究Boost的edge_descriptor实现(在boost/graph/detail/edge.hpp ,我们发现每个边缘描述符都存储源和目标vertex_descriptor ,还存储着edge属性的指针。该指针对于其vertex_descriptor的两个边缘是不同的否则相同。

This means that you need to define your own edge_descriptor comparator which you use for your std::set s and for the set_intersection / set_difference operations, eg like this: 这意味着您需要定义自己的edge_descriptor比较器,该比较器用于std::setset_intersection / set_difference操作,例如:

struct edge_cmp
{
  bool operator () (const Graph::edge_descriptor& a, const Graph::edge_descriptor& b) const
  {
    if (a.m_source < b.m_source) { return true; }
    if (a.m_source > b.m_source) { return false; }
    return (a.m_target < b.m_target);
  }
};

A comparator object of this type must be passed to all the sets you construct, and to the intersection/difference calls. 必须将这种类型的比较器对象传递给您构造的所有集合以及交集/差异调用。

I've forked your code on ideone and modified it accordingly. 我已经在ideone上分叉了您的代码,并进行了相应的修改。 The output: 输出:

---- Vertices ----
same: 3
extra: 1
missing: 0
---- Edges ----
same: 1
extra: 1
missing: 0

As a temporary solution to my problem, instead of: 作为我的问题的临时解决方案,而不是:

std::set<Graph::edge_descriptor> ae
BGL_FORALL_EDGES_T(e, a, Graph) ae.insert(e)

I did the following code for edges. 我为边缘做了以下代码。

std::set<std::pair<unsigned long, unsigned long> > ae;
BGL_FORALL_EDGES_T(e, ga, Graph) gae.insert(std::make_pair(e.m_source, 
                                                           e.m_target));

The problem is that the edges of boost graph have the "m_eproperty" which I don't really know why is there, and it contains values like 0x125d0c0 . 问题在于,boost图形的边缘具有“ m_eproperty”,我不知道为什么会出现它,并且包含诸如0x125d0c0值。 Then I created a pair based on the source and the target of an edge and then I evaluated the same way as above (with the templates). 然后,我基于边的源和目标创建了一对,然后以与上面相同的方式(使用模板)进行了评估。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM