hash problems with c++ and boost library -
i'm writing code graph mining. here full source code:http://pastebin.com/bpjzpcei
i'm trying use std unordered_set got problems on part :
bool edgeexist(graph const& g, int const& fromid, int const& toid, unsigned const& elabel) { int bn = 0; if (num_edges(g) != 0) { edge_pair ep; (ep = edges(g); ep.first != ep.second; ++ep.first) // ep edge number { vertex_t = source(*ep.first, g); vertex_t = target(*ep.first, g); edge_t edg = edge(from, to, g); if ((g[from].id == fromid) && (g[to].id == toid) && (g[edg.first].label == elabel)) { return true; } } } return false; } std::unordered_set<std::array<int, 3>> edgesdiff(graph const& g1,graph const& g2){ std::unordered_set<edge_iter> v1,v2,diff; std::array<int, 3> t; std::unordered_set<std::array<int, 3>> res; for(auto x:edges(g1)){ vertex_t = source(*x, g1); t[0]=g1[from].id; vertex_t = target(*x, g1); t[1]=g1[to].id; edge_t edg = edge(from, to, g1); t[2]=g1[edg.first].label; if(!edgeexist(g2,t[0],t[1],t[2])){res.insert(t);} } return res; }
when run program on code blocks got message:
/usr/include/c++/4.9/bits/hashtable_policy.h|85|error: no match call ‘(const hashedge) (const boost::detail::undirected_edge_iter<std::_list_iterator<boost::list_edge<unsigned int, edgeproperties> >, boost::detail::edge_desc_impl<boost::undirected_tag, unsigned int>, int>&)’|
what's mean , how can solve problem?
after reading code, hash function of unordered set doesn't take 2 arguments (let alone graph
by value ☹).
you'll need @ least (make readable!!!)
struct hashedge { hashedge(graph const &g) : _g(g) {} size_t operator()(const edge_iter e) const { using namespace boost; size_t seed = 42; hash_combine(seed, _g[source(*e, _g)]); hash_combine(seed, _g[*e].label); hash_combine(seed, _g[target(*e, _g)]); return seed; } private: graph const &_g; };
this uses divide conquer hash bundled properties. define separately:
namespace boost { template <> struct hash<vertexproperties> { size_t operator()(vertexproperties const &v) const { using namespace boost; auto seed = hash_value(v.id); hash_combine(seed, v.label); return seed; } }; template <> struct hash<edgeproperties> { size_t operator()(edgeproperties const &e) const { using namespace boost; auto seed = hash_value(e.id); hash_combine(seed, e.label); return seed; } }; }
that compiles , works.
now have similar issues unordered_set<graph>
. i'm pretty sure you're looking @ wrong end. can compare transitive condensations? can use filtered graphs?
here's partial demo, using edge_descriptor
instead of edge_iterator
(because, why iterator?):
#include <boost/graph/adjacency_list.hpp> #include <iostream> #include <unordered_set> struct vertexproperties { int id; int label; vertexproperties(unsigned = 0, unsigned l = 0) : id(i), label(l) {} }; struct edgeproperties { unsigned id; unsigned label; edgeproperties(unsigned = 0, unsigned l = 0) : id(i), label(l) {} }; namespace boost { template <> struct hash<vertexproperties> { size_t operator()(vertexproperties const &v) const { auto seed = hash_value(v.id); hash_combine(seed, v.label); return seed; } }; template <> struct hash<edgeproperties> { size_t operator()(edgeproperties const &e) const { auto seed = hash_value(e.id); hash_combine(seed, e.label); return seed; } }; } struct graphproperties { unsigned id; unsigned label; graphproperties(unsigned = 0, unsigned l = 0) : id(i), label(l) {} }; // adjacency_list typedef boost::adjacency_list<boost::vecs, boost::vecs, boost::undirecteds, vertexproperties, edgeproperties, graphproperties> graph; typedef boost::graph_traits<graph>::edge_descriptor edge_descriptor; struct hashedge { hashedge(graph const &g) : _g(g) {} size_t operator()(const edge_descriptor e) const { using namespace boost; size_t seed = 42; hash_combine(seed, _g[source(e, _g)]); hash_combine(seed, _g[e].label); hash_combine(seed, _g[target(e, _g)]); return seed; } private: graph const &_g; }; int main() { std::vector<graph> datag; (auto& g : datag) { auto es = edges(g); std::unordered_set<edge_descriptor, hashedge> edgehash(es.first, es.second, 0ul, hashedge(g)); } }
Comments
Post a Comment