Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Tiago Peixoto
graph-tool
Commits
d6899abe
Commit
d6899abe
authored
Jun 07, 2014
by
Tiago Peixoto
Browse files
Fix similarity() to accept non-integer properties
parent
3d2ea9f7
Changes
3
Hide whitespace changes
Inline
Side-by-side
src/graph/topology/graph_similarity.cc
View file @
d6899abe
...
...
@@ -13,6 +13,9 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include
"graph_python_interface.hh"
#include
"graph.hh"
#include
"graph_filtering.hh"
#include
"graph_properties.hh"
...
...
@@ -20,8 +23,6 @@
#include
"graph_similarity.hh"
#include
<boost/python.hpp>
using
namespace
std
;
using
namespace
boost
;
using
namespace
graph_tool
;
...
...
@@ -45,11 +46,26 @@ size_t similarity(GraphInterface& gi1, GraphInterface& gi2, boost::any label1,
(
gi1
,
std
::
bind
(
get_similarity
(),
placeholders
::
_1
,
placeholders
::
_2
,
placeholders
::
_3
,
label2
,
std
::
ref
(
s
)),
get_pointers
::
apply
<
graph_tool
::
detail
::
all_graph_views
>::
type
(),
vertex_scalar_properties
())(
gi2
.
GetGraphView
(),
label1
);
writable_vertex_properties
())
(
gi2
.
GetGraphView
(),
label1
);
return
s
;
}
size_t
similarity_fast
(
GraphInterface
&
gi1
,
GraphInterface
&
gi2
,
boost
::
any
label1
,
boost
::
any
label2
)
{
size_t
s
=
0
;
run_action
<
graph_tool
::
detail
::
all_graph_views
,
boost
::
mpl
::
true_
>
()
(
gi1
,
std
::
bind
(
get_similarity_fast
(),
placeholders
::
_1
,
placeholders
::
_2
,
placeholders
::
_3
,
label2
,
std
::
ref
(
s
)),
get_pointers
::
apply
<
graph_tool
::
detail
::
all_graph_views
>::
type
(),
vertex_integer_properties
())
(
gi2
.
GetGraphView
(),
label1
);
return
s
;
}
void
export_similarity
()
{
python
::
def
(
"similarity"
,
&
similarity
);
python
::
def
(
"similarity_fast"
,
&
similarity_fast
);
};
src/graph/topology/graph_similarity.hh
View file @
d6899abe
...
...
@@ -18,20 +18,21 @@
#include
<unordered_set>
namespace
graph_tool
{
using
namespace
std
;
using
namespace
boost
;
template
<
class
Keys
,
class
Set
>
size_t
intersection_size
(
Keys
&
ks
,
Set
&
s1
,
Set
&
s2
)
template
<
class
Keys
,
class
Set
1
,
class
Set2
>
size_t
intersection_size
(
Keys
&
ks
,
Set
1
&
s1
,
Set
2
&
s2
)
{
size_t
s
=
0
;
for
(
typeof
(
ks
.
begin
())
k
=
ks
.
begin
();
k
!=
ks
.
end
();
++
k
)
for
(
auto
k
:
ks
)
{
int
c1
=
s1
.
count
(
*
k
);
int
c2
=
s2
.
count
(
*
k
);
int
c1
=
s1
.
count
(
k
);
int
c2
=
s2
.
count
(
k
);
s
+=
max
(
c1
,
c2
)
-
abs
(
c1
-
c2
);
}
return
s
;
...
...
@@ -42,51 +43,111 @@ struct get_similarity
{
template
<
class
Graph1
,
class
Graph2
,
class
LabelMap
>
void
operator
()(
const
Graph1
&
g1
,
const
Graph2
*
g2p
,
LabelMap
l1
,
any
l2
a
,
size_t
&
s
)
const
boost
::
any
a
l2
,
size_t
&
s
)
const
{
LabelMap
l2
=
any_cast
<
LabelMap
>
(
l2a
);
const
Graph2
&
g2
=
*
g2p
;
LabelMap
l2
=
boost
::
any_cast
<
typename
LabelMap
::
checked_t
>
(
al2
).
get_unchecked
(
num_vertices
(
g2
));
typedef
typename
property_traits
<
LabelMap
>::
value_type
label_t
;
std
::
unordered_map
<
label_t
,
typename
graph_traits
<
Graph1
>::
vertex_descriptor
>
std
::
unordered_map
<
label_t
,
typename
graph_traits
<
Graph1
>::
vertex_descriptor
,
boost
::
hash
<
label_t
>>
lmap1
;
std
::
unordered_map
<
label_t
,
typename
graph_traits
<
Graph2
>::
vertex_descriptor
>
std
::
unordered_map
<
label_t
,
typename
graph_traits
<
Graph2
>::
vertex_descriptor
,
boost
::
hash
<
label_t
>>
lmap2
;
typename
graph_traits
<
Graph1
>::
vertex_iterator
v1
,
v1_end
;
for
(
tie
(
v1
,
v1_end
)
=
vertices
(
g1
);
v1
!=
v1_end
;
++
v1
)
lmap1
[
get
(
l1
,
*
v1
)]
=
*
v1
;
typename
graph_traits
<
Graph2
>::
vertex_iterator
v2
,
v2_end
;
for
(
tie
(
v2
,
v2_end
)
=
vertices
(
g2
);
v2
!=
v2_end
;
++
v2
)
lmap2
[
get
(
l2
,
*
v2
)]
=
*
v2
;
for
(
auto
v
:
vertices_range
(
g1
))
lmap1
[
get
(
l1
,
v
)]
=
v
;
for
(
auto
v
:
vertices_range
(
g2
))
lmap2
[
get
(
l2
,
v
)]
=
v
;
s
=
0
;
for
(
typeof
(
lmap1
.
begin
())
li
=
lmap1
.
begin
();
li
!=
lmap1
.
end
();
++
li
)
for
(
auto
&
lv1
:
lmap1
)
{
typename
graph_traits
<
Graph1
>::
vertex_descrip
to
r
v1
=
l
i
->
second
;
au
to
v1
=
l
v1
.
second
;
typeof
(
lmap2
.
begin
())
li2
=
lmap2
.
find
(
l
i
->
first
);
auto
li2
=
lmap2
.
find
(
l
v1
.
first
);
if
(
li2
==
lmap2
.
end
())
continue
;
typename
graph_traits
<
Graph2
>::
vertex_descriptor
v2
=
li2
->
second
;
auto
v2
=
li2
->
second
;
std
::
unordered_set
<
label_t
,
boost
::
hash
<
label_t
>>
keys
;
std
::
unordered_multiset
<
label_t
,
boost
::
hash
<
label_t
>>
adj1
;
std
::
unordered_multiset
<
label_t
,
boost
::
hash
<
label_t
>>
adj2
;
for
(
auto
a1
:
adjacent_vertices_range
(
v1
,
g1
))
{
adj1
.
insert
(
get
(
l1
,
a1
));
keys
.
insert
(
get
(
l1
,
a1
));
}
for
(
auto
a2
:
adjacent_vertices_range
(
v2
,
g2
))
{
adj2
.
insert
(
get
(
l2
,
a2
));
keys
.
insert
(
get
(
l2
,
a2
));
}
s
+=
intersection_size
(
keys
,
adj1
,
adj2
);
}
}
};
struct
get_similarity_fast
{
template
<
class
Graph1
,
class
Graph2
,
class
LabelMap
>
void
operator
()(
const
Graph1
&
g1
,
const
Graph2
*
g2p
,
LabelMap
l1
,
boost
::
any
al2
,
size_t
&
s
)
const
{
const
Graph2
&
g2
=
*
g2p
;
LabelMap
l2
=
boost
::
any_cast
<
LabelMap
>
(
al2
);
typedef
typename
property_traits
<
LabelMap
>::
value_type
label_t
;
vector
<
typename
graph_traits
<
Graph1
>::
vertex_descriptor
>
lmap1
;
vector
<
typename
graph_traits
<
Graph1
>::
vertex_descriptor
>
lmap2
;
for
(
auto
v
:
vertices_range
(
g1
))
{
size_t
i
=
get
(
l1
,
v
);
if
(
lmap1
.
size
()
<=
i
)
lmap1
.
resize
(
i
+
1
);
lmap1
[
i
]
=
v
;
}
for
(
auto
v
:
vertices_range
(
g2
))
{
size_t
i
=
get
(
l2
,
v
);
if
(
lmap2
.
size
()
<=
i
)
lmap2
.
resize
(
i
+
1
);
lmap2
[
i
]
=
v
;
}
s
=
0
;
int
i
,
N
=
lmap1
.
size
();
#pragma omp parallel for default(shared) private(i) schedule(static) if (N > 100)
for
(
i
=
0
;
i
<
N
;
++
i
)
{
auto
v1
=
lmap1
[
i
];
auto
v2
=
lmap2
[
i
];
std
::
unordered_set
<
label_t
>
keys
;
std
::
unordered_multiset
<
label_t
>
adj1
;
std
::
unordered_multiset
<
label_t
>
adj2
;
typename
graph_traits
<
Graph1
>::
adjacency_iterator
a1
,
a1_end
;
for
(
tie
(
a1
,
a1_end
)
=
adjacent_vertices
(
v1
,
g1
);
a1
!=
a1_end
;
++
a1
)
for
(
auto
a1
:
adjacent_vertices_range
(
v1
,
g1
))
{
adj1
.
insert
(
get
(
l1
,
*
a1
));
keys
.
insert
(
get
(
l1
,
*
a1
));
adj1
.
insert
(
get
(
l1
,
a1
));
keys
.
insert
(
get
(
l1
,
a1
));
}
typename
graph_traits
<
Graph2
>::
adjacency_iterator
a2
,
a2_end
;
for
(
tie
(
a2
,
a2_end
)
=
adjacent_vertices
(
v2
,
g2
);
a2
!=
a2_end
;
++
a2
)
for
(
auto
a2
:
adjacent_vertices_range
(
v2
,
g2
))
{
adj2
.
insert
(
get
(
l2
,
*
a2
));
keys
.
insert
(
get
(
l2
,
*
a2
));
adj2
.
insert
(
get
(
l2
,
a2
));
keys
.
insert
(
get
(
l2
,
a2
));
}
s
+=
intersection_size
(
keys
,
adj1
,
adj2
);
...
...
src/graph_tool/topology/__init__.py
View file @
d6899abe
...
...
@@ -137,10 +137,24 @@ def similarity(g1, g2, label1=None, label2=None, norm=True):
if
label2
is
None
:
label2
=
g2
.
vertex_index
if
label1
.
value_type
()
!=
label2
.
value_type
():
raise
ValueError
(
"label property maps must be of the same type"
)
s
=
libgraph_tool_topology
.
\
similarity
(
g1
.
_Graph__graph
,
g2
.
_Graph__graph
,
_prop
(
"v"
,
g1
,
label1
),
_prop
(
"v"
,
g1
,
label2
))
try
:
label2
=
label2
.
copy
(
label1
.
value_type
())
except
ValueError
:
label1
=
label1
.
copy
(
label2
.
value_type
())
try
:
_check_prop_scalar
(
label1
,
floating
=
False
)
_check_prop_scalar
(
label2
,
floating
=
False
)
if
label1
.
fa
is
not
None
and
label1
.
fa
.
max
()
>=
g1
.
num_vertices
():
raise
ValueError
()
if
label2
.
fa
is
not
None
and
label2
.
fa
.
max
()
>=
g2
.
num_vertices
():
raise
ValueError
()
s
=
libgraph_tool_topology
.
\
similarity_fast
(
g1
.
_Graph__graph
,
g2
.
_Graph__graph
,
_prop
(
"v"
,
g1
,
label1
),
_prop
(
"v"
,
g2
,
label2
))
except
ValueError
:
s
=
libgraph_tool_topology
.
\
similarity
(
g1
.
_Graph__graph
,
g2
.
_Graph__graph
,
_prop
(
"v"
,
g1
,
label1
),
_prop
(
"v"
,
g2
,
label2
))
if
not
g1
.
is_directed
()
or
not
g2
.
is_directed
():
s
/=
2
if
norm
:
...
...
Tiago Peixoto
@count0
mentioned in issue
#148 (closed)
·
Aug 06, 2014
mentioned in issue
#148 (closed)
mentioned in issue #148
Toggle commit list
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment