c++ - 比较两个具有相同顶点的提升图

标签 c++ boost-graph

可能是新手问题,我需要你的帮助来比较两个图,它们具有相同的顶点数和名称。

我的主题大纲是:

Graph origG, computedG;
...
...
int nmbrSameEdges, nmbrExteraEdges, nmbrMissingEdges, nmbrIncorrectEdges;

void compareGraph(origG, computedG, nmbrSameEdges, nmbrExteraEdges, nmbrMissingEdges, nmbrIncorrectEdges);

提前致谢。

最佳答案

我想我会喜欢在这里做手指练习:

Warning As far as I can see, the output is not entirely as I'd expect it. I assume it is because of the comparison as defined for edge descritors not working as I expected.

Should you run into any trouble with that, you might, instead use the isomorphism algorithm

使用演示

int main()
{
    typedef adjacency_list<> Graph;

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

    diff<Graph> comparison;
    compare(a,b, comparison);

    std::cout << comparison;

/*
 *    std::cout << "edge_stats.same:      " << comparison.edge_stats.same.size()      << std::endl;
 *    std::cout << "edge_stats.extra:     " << comparison.edge_stats.extra.size()     << std::endl;
 *    std::cout << "edge_stats.missing:   " << comparison.edge_stats.missing.size()   << std::endl;
 *    std::cout << "edge_stats.reversed:  " << comparison.edge_stats.reversed.size()  << std::endl;
 *    std::cout << "vertex_stats.same:    " << comparison.vertex_stats.same.size()    << std::endl;
 *    std::cout << "vertex_stats.extra:   " << comparison.vertex_stats.extra.size()   << std::endl;
 *    std::cout << "vertex_stats.missing: " << comparison.vertex_stats.missing.size() << std::endl;
 */

}

输出(使用 Boost Spirit):

Diff stats: 
--------------
Vertices
    Same:    3 (0, 1, 2)
    Extra:   1 (3)
    Missing: 0 ()
Edges
    Same:    0
    Extra:   1
    Missing: 1
    Reversed:1

请注意,注释示例代码显示了如何在不使用 Boost Spirit 的情况下打印差异结果。

实现

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/reverse_graph.hpp>
#include <boost/graph/iteration_macros.hpp>
#include <boost/spirit/include/karma.hpp>
using namespace boost;

namespace setops
{
    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;
    }
}

template <typename descriptor>
    struct stats 
    { 
        std::set<descriptor> same, extra, missing; 
    };
template <typename descriptor>
    struct directed_stats : stats<descriptor>
    { 
        std::set<descriptor> reversed; 
    };

template <typename G>
    struct diff
    {
        typedef typename graph_traits<G>::vertex_descriptor vdesc;
        typedef typename graph_traits<G>::edge_descriptor   edesc;

        stats<vdesc> vertex_stats;
        directed_stats<edesc> edge_stats;

        template <typename G2>
        friend std::ostream& operator<<(std::ostream& os, const diff<G2>& d)
        {
            using namespace boost::spirit::karma;

            os << "Diff stats: \n"
                  "--------------\n"
                  "Vertices\n"
               << format("\tSame:    " << int_ << " (" << -(auto_ % ", ") << ")" << eol, d.vertex_stats.same.size(), d.vertex_stats.same)
               << format("\tExtra:   " << int_ << " (" << -(auto_ % ", ") << ")" << eol, d.vertex_stats.extra.size(), d.vertex_stats.extra)
               << format("\tMissing: " << int_ << " (" << -(auto_ % ", ") << ")" << eol, d.vertex_stats.missing.size(), d.vertex_stats.missing);
            os << "Edges\n"
               << format("\tSame:    " << int_ << eol, d.edge_stats.same.size())
               << format("\tExtra:   " << int_ << eol, d.edge_stats.extra.size())
               << format("\tMissing: " << int_ << eol, d.edge_stats.missing.size())
               << format("\tReversed:" << int_ << eol, d.edge_stats.missing.size());
            return os;
        }
    };

template <typename G>
void compare(const G& a, const G& b, diff<G>& result)
{
    std::set<typename diff<G>::vdesc> av, bv;
    std::set<typename diff<G>::edesc> ae, be, re;

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

    // reverse adapt b:
    reverse_graph<G> r(b);
    BGL_FORALL_EDGES_T(e, r, G) re.insert(e);

    using namespace setops;
    result.edge_stats.same    = (ae / be);
    result.edge_stats.extra   = (be - ae);
    result.edge_stats.missing = (ae - be);
    result.edge_stats.reversed= (ae / re);

    BGL_FORALL_VERTICES_T(v, a, G) av.insert(v);
    BGL_FORALL_VERTICES_T(v, b, G) bv.insert(v);
    result.vertex_stats.same    = (av / bv);
    result.vertex_stats.extra   = (bv - av);
    result.vertex_stats.missing = (av - bv);
}

关于c++ - 比较两个具有相同顶点的提升图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8175933/

相关文章:

c++ - 离开范围时,我的 boost managed_shared_memory 似乎没有从内存空间取消映射

c++ - 享受两个世界 : vector With insert/erase efficiency of list

c++ - 关于静态变量的访问问题

c++ - 从图中删除边

c++ - 提升图宽度优先搜索前身编译错误

c++ - GCC vs VC++ 模板语法错误(为什么不能在两者上编译?)

c++ - 我可以在堆栈展开期间使用 std::current_exception 吗?

c++ - 如何使用自定义 Vertex 属性读取 GraphML 文件以进行 Boost Graph?

c++ - 从 8 个连接的像素列表中提取片段

c++ - bgl 中的 edge_descriptor 映射