Commit 51c0fc29 authored by Tiago Peixoto's avatar Tiago Peixoto
Browse files

Implement perfect_prop_hash()

parent 9da39d0c
......@@ -391,6 +391,13 @@ void edge_difference(GraphInterface& gi, boost::any prop,
boost::any eprop);
void mark_edges(GraphInterface& gi, boost::any prop);
void perfect_ehash(GraphInterface& gi, boost::any prop, boost::any hprop,
boost::any& dict);
void perfect_vhash(GraphInterface& gi, boost::any prop, boost::any hprop,
boost::any& dict);
void export_python_interface();
void export_openmp();
......@@ -505,6 +512,8 @@ BOOST_PYTHON_MODULE(libgraph_tool_core)
def("infect_vertex_property", &infect_vertex_property);
def("edge_difference", &edge_difference);
def("mark_edges", &mark_edges);
def("perfect_ehash", &perfect_ehash);
def("perfect_vhash", &perfect_vhash);
class_<LibInfo>("mod_info")
.add_property("name", &LibInfo::GetName)
......
......@@ -282,3 +282,82 @@ void mark_edges(GraphInterface& gi, boost::any prop)
run_action<graph_tool::detail::always_directed>()(gi, bind<void>(do_mark_edges(), _1, _2),
writable_edge_scalar_properties())(prop);
}
struct do_perfect_vhash
{
template <class Graph, class VertexPropertyMap, class HashProp>
void operator()(Graph& g, VertexPropertyMap prop, HashProp hprop,
boost::any& adict) const
{
typedef typename property_traits<VertexPropertyMap>::value_type val_t;
typedef typename property_traits<HashProp>::value_type hash_t;
typedef unordered_map<val_t, hash_t, boost::hash<val_t>> dict_t;
if (adict.empty())
adict = dict_t();
dict_t& dict = any_cast<dict_t&>(adict);
for (auto v : vertices_range(g))
{
auto val = prop[v];
auto iter = dict.find(val);
hash_t h;
if (iter == dict.end())
h = dict[val] = dict.size() - 1;
else
h = iter->second;
hprop[v] = h;
}
}
};
void perfect_vhash(GraphInterface& gi, boost::any prop, boost::any hprop,
boost::any& dict)
{
run_action<graph_tool::detail::always_directed>()
(gi, std::bind<void>(do_perfect_vhash(), std::placeholders::_1,
std::placeholders::_2, std::placeholders::_3, std::ref(dict)),
vertex_properties(), writable_vertex_scalar_properties())
(prop, hprop);
}
struct do_perfect_ehash
{
template <class Graph, class EdgePropertyMap, class HashProp>
void operator()(Graph& g, EdgePropertyMap prop, HashProp hprop,
boost::any& adict) const
{
typedef typename property_traits<EdgePropertyMap>::value_type val_t;
typedef typename property_traits<HashProp>::value_type hash_t;
typedef unordered_map<val_t, hash_t, boost::hash<val_t>> dict_t;
if (adict.empty())
adict = dict_t();
dict_t& dict = any_cast<dict_t&>(adict);
for (auto e : edges_range(g))
{
auto val = prop[e];
auto iter = dict.find(val);
hash_t h;
if (iter == dict.end())
h = dict[val] = dict.size() - 1;
else
h = iter->second;
hprop[e] = h;
}
}
};
void perfect_ehash(GraphInterface& gi, boost::any prop, boost::any hprop,
boost::any& dict)
{
run_action<graph_tool::detail::always_directed>()
(gi, std::bind<void>(do_perfect_ehash(), std::placeholders::_1,
std::placeholders::_2, std::placeholders::_3, std::ref(dict)),
edge_properties(), writable_edge_scalar_properties())
(prop, hprop);
}
......@@ -39,6 +39,7 @@ Summary
ungroup_vector_property
infect_vertex_property
edge_difference
perfect_prop_hash
value_types
show_config
......@@ -117,9 +118,9 @@ __all__ = ["Graph", "GraphView", "Vertex", "Edge", "Vector_bool",
"Vector_int16_t", "Vector_int32_t", "Vector_int64_t", "Vector_double",
"Vector_long_double", "Vector_string", "value_types", "load_graph",
"PropertyMap", "group_vector_property", "ungroup_vector_property",
"infect_vertex_property", "edge_difference", "seed_rng", "show_config",
"PropertyArray", "openmp_enabled", "openmp_get_num_threads",
"openmp_set_num_threads", "openmp_get_schedule",
"infect_vertex_property", "edge_difference", "perfect_prop_hash",
"seed_rng", "show_config", "PropertyArray", "openmp_enabled",
"openmp_get_num_threads", "openmp_set_num_threads", "openmp_get_schedule",
"openmp_set_schedule", "__author__", "__copyright__", "__URL__",
"__version__"]
......@@ -1024,6 +1025,41 @@ def edge_difference(g, prop, ediff=None):
_prop("e", g, ediff))
return ediff
@_limit_args({"htype": ["int8_t", "int32_t", "int64_t"]})
def perfect_prop_hash(props, htype="int32_t"):
"""Given a list of property maps `props` of the same type, a derived list of
property maps with integral type `htype` is retured, where each value is
replaced by a perfect (i.e. unique) hash value.
.. note::
The hash value is deterministic, but it will not be necessarily the same
for different values of `props`.
"""
val_types = set([p.value_type() for p in props])
if len(val_types) > 1:
raise ValueError("All properties must have the same value type")
hprops = [p.get_graph().new_property(p.key_type(), htype) for p in props]
eprops = [p for p in props if p.key_type() == "e"]
heprops = [p for p in hprops if p.key_type() == "e"]
vprops = [p for p in props if p.key_type() == "v"]
hvprops = [p for p in hprops if p.key_type() == "v"]
hdict = libcore.any()
for eprop, heprop in zip(eprops, heprops):
g = eprop.get_graph()
libcore.perfect_ehash(g._Graph__graph, _prop('e', g, eprop),
_prop('e', g, heprop), hdict)
for vprop, hvprop in zip(vprops, hvprops):
g = vprop.get_graph()
libcore.perfect_vhash(g._Graph__graph, _prop('v', g, vprop),
_prop('v', g, hvprop), hdict)
return hprops
class PropertyDict(dict):
"""Wrapper for the dict of vertex, graph or edge properties, which sets the
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment