#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/reverse_graph.hpp>
#include <boost/graph/iteration_macros.hpp>
#include <boost/graph/graph_utility.hpp>
// using namespace boost;
typedef boost::adjacency_list < boost::vecS, boost::vecS, boost::undirectedS > Graph;
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);
}
};
template <typename T, typename Compare> std::set<T,Compare> operator-(const std::set<T,Compare>& a, const std::set<T,Compare>& b)
{
std::set<T,Compare> r;
std::set_difference(a.begin(), a.end(),
b.begin(), b.end(),
std::inserter(r, r.end()));
return r;
}
template <typename T,typename Compare> std::set<T,Compare> operator/(const std::set<T,Compare>& a, const std::set<T,Compare>& b)
{
std::set<T,Compare> r;
std::set_intersection(
a.begin(), a.end(),
b.begin(), b.end(),
std::inserter(r, r.end()));
return r;
}
// Overload operator for our specific set type.
template <> std::set<Graph::edge_descriptor,edge_cmp> operator-(const std::set<Graph::edge_descriptor,edge_cmp>& a,
const std::set<Graph::edge_descriptor,edge_cmp>& b)
{
std::set<Graph::edge_descriptor,edge_cmp> r;
std::set_difference(a.begin(), a.end(),
b.begin(), b.end(),
std::inserter(r, r.end()), edge_cmp());
return r;
}
template <> std::set<Graph::edge_descriptor,edge_cmp> operator/(const std::set<Graph::edge_descriptor,edge_cmp>& a,
const std::set<Graph::edge_descriptor,edge_cmp>& b)
{
std::set<Graph::edge_descriptor,edge_cmp> r;
std::set_intersection(
a.begin(), a.end(),
b.begin(), b.end(),
std::inserter(r, r.end()), edge_cmp());
return r;
}
void compare(const Graph& a, const Graph& b)
{
std::set<Graph::vertex_descriptor > av, bv, samev, extrav, missingv;
// Use our comparator here.
edge_cmp comp;
std::set<Graph::edge_descriptor, edge_cmp> ae(comp), be(comp), re(comp), samee(comp), extrae(comp), missinge(comp);
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);
}
I2luY2x1ZGUgPGJvb3N0L2dyYXBoL2FkamFjZW5jeV9saXN0LmhwcD4KI2luY2x1ZGUgPGJvb3N0L2dyYXBoL3JldmVyc2VfZ3JhcGguaHBwPgojaW5jbHVkZSA8Ym9vc3QvZ3JhcGgvaXRlcmF0aW9uX21hY3Jvcy5ocHA+CiNpbmNsdWRlIDxib29zdC9ncmFwaC9ncmFwaF91dGlsaXR5LmhwcD4KCi8vIHVzaW5nIG5hbWVzcGFjZSBib29zdDsKdHlwZWRlZiBib29zdDo6YWRqYWNlbmN5X2xpc3QgPCBib29zdDo6dmVjUywgYm9vc3Q6OnZlY1MsIGJvb3N0Ojp1bmRpcmVjdGVkUyA+IEdyYXBoOwoKc3RydWN0IGVkZ2VfY21wCnsKICBib29sIG9wZXJhdG9yICgpIChjb25zdCBHcmFwaDo6ZWRnZV9kZXNjcmlwdG9yJiBhLCBjb25zdCBHcmFwaDo6ZWRnZV9kZXNjcmlwdG9yJiBiKSBjb25zdAogIHsKICAgIGlmIChhLm1fc291cmNlIDwgYi5tX3NvdXJjZSkgeyByZXR1cm4gdHJ1ZTsgfQogICAgaWYgKGEubV9zb3VyY2UgPiBiLm1fc291cmNlKSB7IHJldHVybiBmYWxzZTsgfQogICAgcmV0dXJuIChhLm1fdGFyZ2V0IDwgYi5tX3RhcmdldCk7CiAgfQp9OwoKdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lIENvbXBhcmU+IHN0ZDo6c2V0PFQsQ29tcGFyZT4gb3BlcmF0b3ItKGNvbnN0IHN0ZDo6c2V0PFQsQ29tcGFyZT4mIGEsIGNvbnN0IHN0ZDo6c2V0PFQsQ29tcGFyZT4mIGIpCnsKICBzdGQ6OnNldDxULENvbXBhcmU+IHI7CiAgc3RkOjpzZXRfZGlmZmVyZW5jZShhLmJlZ2luKCksIGEuZW5kKCksCiAgICAgICAgICAgICAgICAgICAgICBiLmJlZ2luKCksIGIuZW5kKCksCiAgICAgICAgICAgICAgICAgICAgICBzdGQ6Omluc2VydGVyKHIsIHIuZW5kKCkpKTsKCiAgcmV0dXJuIHI7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBULHR5cGVuYW1lIENvbXBhcmU+IHN0ZDo6c2V0PFQsQ29tcGFyZT4gb3BlcmF0b3IvKGNvbnN0IHN0ZDo6c2V0PFQsQ29tcGFyZT4mIGEsIGNvbnN0IHN0ZDo6c2V0PFQsQ29tcGFyZT4mIGIpCnsKICBzdGQ6OnNldDxULENvbXBhcmU+IHI7CiAgc3RkOjpzZXRfaW50ZXJzZWN0aW9uKAogICAgYS5iZWdpbigpLCBhLmVuZCgpLAogICAgYi5iZWdpbigpLCBiLmVuZCgpLAogICAgc3RkOjppbnNlcnRlcihyLCByLmVuZCgpKSk7CgogIHJldHVybiByOwp9CgovLyBPdmVybG9hZCBvcGVyYXRvciBmb3Igb3VyIHNwZWNpZmljIHNldCB0eXBlLgp0ZW1wbGF0ZSA8PiBzdGQ6OnNldDxHcmFwaDo6ZWRnZV9kZXNjcmlwdG9yLGVkZ2VfY21wPiBvcGVyYXRvci0oY29uc3Qgc3RkOjpzZXQ8R3JhcGg6OmVkZ2VfZGVzY3JpcHRvcixlZGdlX2NtcD4mIGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdGQ6OnNldDxHcmFwaDo6ZWRnZV9kZXNjcmlwdG9yLGVkZ2VfY21wPiYgYikKewogIHN0ZDo6c2V0PEdyYXBoOjplZGdlX2Rlc2NyaXB0b3IsZWRnZV9jbXA+IHI7CiAgc3RkOjpzZXRfZGlmZmVyZW5jZShhLmJlZ2luKCksIGEuZW5kKCksCiAgICAgICAgICAgICAgICAgICAgICBiLmJlZ2luKCksIGIuZW5kKCksCiAgICAgICAgICAgICAgICAgICAgICBzdGQ6Omluc2VydGVyKHIsIHIuZW5kKCkpLCBlZGdlX2NtcCgpKTsKICByZXR1cm4gcjsKfQoKdGVtcGxhdGUgPD4gc3RkOjpzZXQ8R3JhcGg6OmVkZ2VfZGVzY3JpcHRvcixlZGdlX2NtcD4gb3BlcmF0b3IvKGNvbnN0IHN0ZDo6c2V0PEdyYXBoOjplZGdlX2Rlc2NyaXB0b3IsZWRnZV9jbXA+JiBhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RkOjpzZXQ8R3JhcGg6OmVkZ2VfZGVzY3JpcHRvcixlZGdlX2NtcD4mIGIpCnsKICBzdGQ6OnNldDxHcmFwaDo6ZWRnZV9kZXNjcmlwdG9yLGVkZ2VfY21wPiByOwogIHN0ZDo6c2V0X2ludGVyc2VjdGlvbigKICAgIGEuYmVnaW4oKSwgYS5lbmQoKSwKICAgIGIuYmVnaW4oKSwgYi5lbmQoKSwKICAgIHN0ZDo6aW5zZXJ0ZXIociwgci5lbmQoKSksIGVkZ2VfY21wKCkpOwoKICByZXR1cm4gcjsKfQoKdm9pZCBjb21wYXJlKGNvbnN0IEdyYXBoJiBhLCBjb25zdCBHcmFwaCYgYikKewogIHN0ZDo6c2V0PEdyYXBoOjp2ZXJ0ZXhfZGVzY3JpcHRvciA+IGF2LCBidiwgc2FtZXYsIGV4dHJhdiwgbWlzc2luZ3Y7CiAgLy8gVXNlIG91ciBjb21wYXJhdG9yIGhlcmUuCiAgZWRnZV9jbXAgY29tcDsKICBzdGQ6OnNldDxHcmFwaDo6ZWRnZV9kZXNjcmlwdG9yLCBlZGdlX2NtcD4gYWUoY29tcCksIGJlKGNvbXApLCByZShjb21wKSwgc2FtZWUoY29tcCksIGV4dHJhZShjb21wKSwgbWlzc2luZ2UoY29tcCk7CgogIEJHTF9GT1JBTExfVkVSVElDRVNfVCh2LCBhLCBHcmFwaCkgYXYuaW5zZXJ0KHYpOwogIEJHTF9GT1JBTExfVkVSVElDRVNfVCh2LCBiLCBHcmFwaCkgYnYuaW5zZXJ0KHYpOwogIHNhbWV2ICAgID0gKGF2IC8gYnYpOwogIGV4dHJhdiAgID0gKGJ2IC0gYXYpOwogIG1pc3Npbmd2ID0gKGF2IC0gYnYpOwoKCiAgQkdMX0ZPUkFMTF9FREdFU19UKGUsIGEsIEdyYXBoKSBhZS5pbnNlcnQoZSk7CiAgQkdMX0ZPUkFMTF9FREdFU19UKGUsIGIsIEdyYXBoKSBiZS5pbnNlcnQoZSk7CgogIHNhbWVlICAgID0gKGFlIC8gYmUpOwogIGV4dHJhZSAgID0gKGJlIC0gYWUpOwogIG1pc3NpbmdlID0gKGFlIC0gYmUpOwoKICAvLyBUT0RPKHNpbGdvbik6IHJldmVyc2VfZ3JhcGgKICAvLyBib29zdDo6cmV2ZXJzZV9ncmFwaDxHcmFwaD4gcihiKTsKICAvLyBCR0xfRk9SQUxMX0VER0VTX1QoZSwgciwgR3JhcGgpIHJlLmluc2VydChlKTsKICBzdGQ6OmNvdXQgPDwgIi0tLS0gVmVydGljZXMgLS0tLVxuIgogICAgICAgICAgICA8PCAic2FtZTogIiA8PCBzYW1ldi5zaXplKCkgPDwgc3RkOjplbmRsCiAgICAgICAgICAgIDw8ICJleHRyYTogIiA8PCBleHRyYXYuc2l6ZSgpIDw8IHN0ZDo6ZW5kbAogICAgICAgICAgICA8PCAibWlzc2luZzogIiA8PCBtaXNzaW5ndi5zaXplKCkgPDwgc3RkOjplbmRsOwoKICBzdGQ6OmNvdXQgPDwgIi0tLS0gRWRnZXMgLS0tLVxuIgogICAgICAgICAgICA8PCAic2FtZTogIiA8PCBzYW1lZS5zaXplKCkgPDwgc3RkOjplbmRsCiAgICAgICAgICAgIDw8ICJleHRyYTogIiA8PCBleHRyYWUuc2l6ZSgpIDw8IHN0ZDo6ZW5kbAogICAgICAgICAgICA8PCAibWlzc2luZzogIiA8PCBtaXNzaW5nZS5zaXplKCkgPDwgc3RkOjplbmRsOwp9CgppbnQgbWFpbigpCnsKICBHcmFwaCBhOwogIHsKICAgIGJvb3N0OjpncmFwaF90cmFpdHM8R3JhcGg+Ojp2ZXJ0ZXhfZGVzY3JpcHRvciB2LCB1LCB5OwogICAgdSA9IGJvb3N0Ojp2ZXJ0ZXgoMSwgYSk7CiAgICB2ID0gYm9vc3Q6OnZlcnRleCgyLCBhKTsKICAgIHkgPSBib29zdDo6dmVydGV4KDMsIGEpOwogICAgYm9vc3Q6OmFkZF9lZGdlKHUsIHYsIGEpOwogIH0KICBHcmFwaCBiOwogIHsKICAgIGJvb3N0OjpncmFwaF90cmFpdHM8R3JhcGg+Ojp2ZXJ0ZXhfZGVzY3JpcHRvciB2LCB1LCB5OwogICAgdSA9IHZlcnRleCgxLCBiKTsKICAgIHYgPSB2ZXJ0ZXgoMiwgYik7CiAgICB5ID0gdmVydGV4KDMsIGIpOwogICAgYm9vc3Q6OmFkZF9lZGdlKHUsIHYsIGIpOwogICAgYm9vc3Q6OmFkZF9lZGdlKHksIHYsIGIpOwogIH0KCiAgY29uc3QgY2hhciogbmFtZSA9ICIxMjM0NTYiOwogIHN0ZDo6Y291dCA8PCAiLS0tR3JhcGgxLS0tIiA8PCAiXG4iOwogIGJvb3N0OjpwcmludF9ncmFwaChhKTsKICBzdGQ6OmNvdXQgPDwgIkVkZ2VzOiAiOwogIGJvb3N0OjpwcmludF9lZGdlcyhhLG5hbWUpOwogIHN0ZDo6Y291dCA8PCAiLS0tR3JhcGgyLS0tIiA8PCAiXG4iOwogIGJvb3N0OjpwcmludF9ncmFwaChiKTsKICBzdGQ6OmNvdXQgPDwgIkVkZ2VzOiAiOwogIGJvb3N0OjpwcmludF9lZGdlcyhiLG5hbWUpOwoKICBjb21wYXJlKGEsYik7Cn0K