Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
graph-tool
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
40
Issues
40
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Tiago Peixoto
graph-tool
Commits
4296b96e
Commit
4296b96e
authored
Jul 10, 2013
by
Tiago Peixoto
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement optional faster O(1) removal of edges
parent
e16c781f
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
115 additions
and
15 deletions
+115
-15
src/graph/graph.hh
src/graph/graph.hh
+3
-0
src/graph/graph_adjacency.hh
src/graph/graph_adjacency.hh
+78
-11
src/graph/graph_bind.cc
src/graph/graph_bind.cc
+2
-0
src/graph_tool/__init__.py
src/graph_tool/__init__.py
+32
-4
No files found.
src/graph/graph.hh
View file @
4296b96e
...
...
@@ -86,6 +86,9 @@ public:
bool
GetDirected
()
{
return
_directed
;}
void
SetReversed
(
bool
reversed
)
{
_reversed
=
reversed
;}
bool
GetReversed
()
{
return
_reversed
;}
void
SetKeepEpos
(
bool
keep
)
{
_mg
->
set_keep_epos
(
keep
);}
bool
GetKeepEpos
()
{
return
_mg
->
get_keep_epos
();}
// graph filtering
void
SetVertexFilterProperty
(
boost
::
any
prop
,
bool
invert
);
...
...
src/graph/graph_adjacency.hh
View file @
4296b96e
...
...
@@ -250,6 +250,28 @@ public:
_last_idx
));
_last_idx
++
;
}
if
(
_keep_epos
)
rebuild_epos
();
}
void
set_keep_epos
(
bool
keep
)
{
if
(
keep
)
{
if
(
!
_keep_epos
)
rebuild_epos
();
}
else
{
_epos
.
clear
();
}
_keep_epos
=
keep
;
}
bool
get_keep_epos
()
{
return
_keep_epos
;
}
size_t
get_last_index
()
const
{
return
_last_idx
;}
...
...
@@ -266,6 +288,27 @@ private:
// for new edges to avoid very large
// indexes, and unnecessary property map
// memory use
bool
_keep_epos
;
std
::
vector
<
std
::
pair
<
int32_t
,
int32_t
>
>
_epos
;
void
rebuild_epos
()
{
_epos
.
resize
(
_last_idx
+
1
);
for
(
size_t
i
=
0
;
i
<
_out_edges
.
size
();
++
i
)
{
for
(
size_t
j
=
0
;
j
<
_out_edges
[
i
].
size
();
++
j
)
{
size_t
idx
=
_out_edges
[
i
][
j
].
second
;
_epos
[
idx
].
first
=
j
;
}
for
(
size_t
j
=
0
;
j
<
_in_edges
[
i
].
size
();
++
j
)
{
size_t
idx
=
_in_edges
[
i
][
j
].
second
;
_epos
[
idx
].
second
=
j
;
}
}
}
// manipulation functions
friend
std
::
pair
<
vertex_iterator
,
vertex_iterator
>
...
...
@@ -631,6 +674,14 @@ add_edge(Vertex s, Vertex t, adj_list<Vertex>& g)
g
.
_in_edges
[
t
].
push_back
(
std
::
make_pair
(
s
,
idx
));
g
.
_n_edges
++
;
if
(
g
.
_keep_epos
)
{
if
(
idx
>=
g
.
_epos
.
size
())
g
.
_epos
.
resize
(
idx
+
1
);
g
.
_epos
[
idx
].
first
=
g
.
_out_edges
[
s
].
size
()
-
1
;
g
.
_epos
[
idx
].
second
=
g
.
_in_edges
[
t
].
size
()
-
1
;
}
return
std
::
make_pair
(
std
::
tr1
::
make_tuple
(
s
,
t
,
idx
),
true
);
}
...
...
@@ -665,24 +716,40 @@ inline void remove_edge(const typename adj_list<Vertex>::edge_descriptor& e,
Vertex
t
=
get
<
1
>
(
e
);
Vertex
idx
=
get
<
2
>
(
e
);
typename
adj_list
<
Vertex
>::
edge_list_t
&
oes
=
g
.
_out_edges
[
s
];
for
(
size_t
i
=
0
;
i
<
oes
.
size
();
++
i
)
typename
adj_list
<
Vertex
>::
edge_list_t
&
ies
=
g
.
_in_edges
[
t
];
if
(
!
g
.
_keep_epos
)
// O(k_s + k_t)
{
if
(
t
==
oes
[
i
].
first
&&
idx
==
oes
[
i
].
second
)
for
(
size_t
i
=
0
;
i
<
oes
.
size
();
++
i
)
{
oes
.
erase
(
oes
.
begin
()
+
i
);
break
;
if
(
t
==
oes
[
i
].
first
&&
idx
==
oes
[
i
].
second
)
{
oes
.
erase
(
oes
.
begin
()
+
i
);
break
;
}
}
}
typename
adj_list
<
Vertex
>::
edge_list_t
&
ies
=
g
.
_in_edges
[
t
];
for
(
size_t
i
=
0
;
i
<
ies
.
size
();
++
i
)
{
if
(
s
==
ies
[
i
].
first
&&
idx
==
ies
[
i
].
second
)
for
(
size_t
i
=
0
;
i
<
ies
.
size
();
++
i
)
{
ies
.
erase
(
ies
.
begin
()
+
i
);
break
;
if
(
s
==
ies
[
i
].
first
&&
idx
==
ies
[
i
].
second
)
{
ies
.
erase
(
ies
.
begin
()
+
i
);
break
;
}
}
}
else
// O(1)
{
const
std
::
pair
<
int32_t
,
int32_t
>&
pos
=
g
.
_epos
[
idx
];
g
.
_epos
[
oes
.
back
().
second
].
first
=
pos
.
first
;
oes
[
pos
.
first
]
=
oes
.
back
();
oes
.
pop_back
();
g
.
_epos
[
ies
.
back
().
second
].
second
=
pos
.
second
;
ies
[
pos
.
second
]
=
ies
.
back
();
ies
.
pop_back
();
}
g
.
_free_indexes
.
push_back
(
idx
);
g
.
_n_edges
--
;
}
...
...
src/graph/graph_bind.cc
View file @
4296b96e
...
...
@@ -373,6 +373,8 @@ BOOST_PYTHON_MODULE(libgraph_tool_core)
.
def
(
"GetDirected"
,
&
GraphInterface
::
GetDirected
)
.
def
(
"SetReversed"
,
&
GraphInterface
::
SetReversed
)
.
def
(
"GetReversed"
,
&
GraphInterface
::
GetReversed
)
.
def
(
"SetKeepEpos"
,
&
GraphInterface
::
SetKeepEpos
)
.
def
(
"GetKeepEpos"
,
&
GraphInterface
::
GetKeepEpos
)
.
def
(
"SetVertexFilterProperty"
,
&
GraphInterface
::
SetVertexFilterProperty
)
.
def
(
"IsVertexFilterActive"
,
&
GraphInterface
::
IsVertexFilterActive
)
...
...
src/graph_tool/__init__.py
View file @
4296b96e
...
...
@@ -1246,7 +1246,9 @@ class Graph(object):
def
add_vertex
(
self
,
n
=
1
):
"""Add a vertex to the graph, and return it. If ``n > 1``, ``n``
vertices are inserted and an iterator over the new vertices is returned."""
vertices are inserted and an iterator over the new vertices is returned.
This operation is :math:`O(n)`.
"""
self
.
__check_perms
(
"add_vertex"
)
v
=
libcore
.
add_vertex
(
weakref
.
ref
(
self
),
n
)
...
...
@@ -1304,7 +1306,7 @@ class Graph(object):
def
add_edge
(
self
,
source
,
target
):
"""Add a new edge from ``source`` to ``target`` to the graph, and return
it."""
it.
This operation is :math:`O(1)`.
"""
self
.
__check_perms
(
"add_edge"
)
e
=
libcore
.
add_edge
(
weakref
.
ref
(
self
),
self
.
vertex
(
int
(
source
)),
self
.
vertex
(
int
(
target
)))
...
...
@@ -1314,10 +1316,36 @@ class Graph(object):
return
e
def
remove_edge
(
self
,
edge
):
"""Remove an edge from the graph."""
r
"""Remove an edge from the graph.
.. note::
This operation is normally :math:`O(k_s + k_t)`, where :math:`k_s`
and :math:`k_s` are the total degrees of the source and target
vertices, respectively. However, if :method:`~Graph.set_fast_edge_removal`
is set to `True`, this operation becomes :math:`O(1)`.
.. warning::
The relative ordering of the remaining edges in the graph is kept
unchanged, unless :method:`~Graph.set_fast_edge_removal` is set to
`True`, in which case it can change.
"""
self
.
__check_perms
(
"del_edge"
)
return
libcore
.
remove_edge
(
self
.
__graph
,
edge
)
def
set_fast_edge_removal
(
self
,
fast
=
True
):
r
"""If ``fast == True`` the fast :math:`O(1)` removal of edges will be
enabled. This requires an additional data structure of size :math:`O(E)`
to be kept at all times. If ``fast == False``, this data structure is
destroyed."""
self
.
__graph
.
SetKeepEpos
(
fast
)
def
get_fast_edge_removal
(
self
):
r
"""Return whether the fast :math:`O(1)` removal of edges is currently
enabled."""
return
self
.
__graph
.
GetKeepEpos
()
def
clear
(
self
):
"""Remove all vertices and edges from the graph."""
self
.
__check_perms
(
"del_vertex"
)
...
...
@@ -2111,7 +2139,7 @@ Vector_string.get_array = lambda self: None
Vector_string
.
__repr__
=
lambda
self
:
repr
(
list
(
self
))
# Global RNG
_rng
=
libcore
.
get_rng
(
numpy
.
random
.
randint
(
0
,
sys
.
maxsize
))
...
...
Write
Preview
Markdown
is supported
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