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
a4abd055
Commit
a4abd055
authored
Mar 10, 2016
by
Tiago Peixoto
Browse files
Implement all_paths()
This fixes issue
#278
.
parent
1989b4b5
Pipeline
#119
failed with stage
Changes
2
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
src/graph/topology/graph_distance.cc
View file @
a4abd055
...
...
@@ -455,7 +455,7 @@ void do_get_all_preds(GraphInterface& gi, boost::any adist,
template
<
class
Pred
,
class
Yield
>
void
get_all_paths
(
size_t
s
,
size_t
t
,
Pred
pred
,
Yield
&
yield
)
void
get_all_
shortest_
paths
(
size_t
s
,
size_t
t
,
Pred
pred
,
Yield
&
yield
)
{
vector
<
size_t
>
path
;
vector
<
pair
<
size_t
,
size_t
>>
stack
=
{{
t
,
0
}};
...
...
@@ -483,14 +483,15 @@ void get_all_paths(size_t s, size_t t, Pred pred, Yield& yield)
}
};
python
::
object
do_get_all_paths
(
GraphInterface
&
gi
,
size_t
s
,
size_t
t
,
boost
::
any
apred
)
python
::
object
do_get_all_
shortest_
paths
(
GraphInterface
&
gi
,
size_t
s
,
size_t
t
,
boost
::
any
apred
)
{
#ifdef HAVE_BOOST_COROUTINE
auto
dispatch
=
[
&
](
auto
&
yield
)
{
run_action
<>
()
(
gi
,
[
&
](
auto
&
,
auto
pred
)
{
get_all_paths
(
s
,
t
,
pred
,
yield
);},
(
gi
,
[
&
](
auto
&
,
auto
pred
)
{
get_all_shortest_paths
(
s
,
t
,
pred
,
yield
);},
vertex_scalar_vector_properties
())(
apred
);
};
return
python
::
object
(
CoroGenerator
(
dispatch
));
...
...
@@ -499,9 +500,65 @@ python::object do_get_all_paths(GraphInterface& gi, size_t s, size_t t,
#endif // HAVE_BOOST_COROUTINE
}
template
<
class
Graph
,
class
Yield
>
void
get_all_paths
(
size_t
s
,
size_t
t
,
size_t
cutoff
,
Yield
&
yield
,
Graph
&
g
)
{
typedef
typename
graph_traits
<
Graph
>::
out_edge_iterator
eiter_t
;
typedef
std
::
pair
<
eiter_t
,
eiter_t
>
item_t
;
vector
<
item_t
>
stack
=
{
out_edges
(
s
,
g
)};
while
(
!
stack
.
empty
())
{
auto
&
pos
=
stack
.
back
();
if
(
pos
.
first
==
pos
.
second
||
stack
.
size
()
>
cutoff
)
{
stack
.
pop_back
();
if
(
!
stack
.
empty
())
++
stack
.
back
().
first
;
continue
;
}
auto
v
=
target
(
*
pos
.
first
,
g
);
if
(
v
==
t
)
{
vector
<
size_t
>
path
=
{
s
};
for
(
auto
&
ei
:
stack
)
path
.
push_back
(
target
(
*
ei
.
first
,
g
));
yield
(
wrap_vector_owned
<
size_t
>
(
path
));
stack
.
pop_back
();
if
(
!
stack
.
empty
())
++
stack
.
back
().
first
;
}
else
{
stack
.
push_back
(
out_edges
(
v
,
g
));
}
}
};
python
::
object
do_get_all_paths
(
GraphInterface
&
gi
,
size_t
s
,
size_t
t
,
size_t
cutoff
)
{
#ifdef HAVE_BOOST_COROUTINE
auto
dispatch
=
[
&
](
auto
&
yield
)
{
run_action
<>
()
(
gi
,
[
&
](
auto
&
g
)
{
get_all_paths
(
s
,
t
,
cutoff
,
yield
,
g
);})();
};
return
python
::
object
(
CoroGenerator
(
dispatch
));
#else
throw
GraphException
(
"This functionality is not available because boost::coroutine was not found at compile-time"
);
#endif // HAVE_BOOST_COROUTINE
}
void
export_dists
()
{
python
::
def
(
"get_dists"
,
&
get_dists
);
python
::
def
(
"get_all_preds"
,
&
do_get_all_preds
);
python
::
def
(
"get_all_shortest_paths"
,
&
do_get_all_shortest_paths
);
python
::
def
(
"get_all_paths"
,
&
do_get_all_paths
);
};
src/graph_tool/topology/__init__.py
View file @
a4abd055
...
...
@@ -32,6 +32,7 @@ Summary
shortest_path
all_shortest_paths
all_predecessors
all_paths
pseudo_diameter
similarity
isomorphism
...
...
@@ -81,8 +82,8 @@ __all__ = ["isomorphism", "subgraph_isomorphism", "mark_subgraph",
"label_largest_component"
,
"label_biconnected_components"
,
"label_out_component"
,
"kcore_decomposition"
,
"shortest_distance"
,
"shortest_path"
,
"all_shortest_paths"
,
"all_predecessors"
,
"pseudo_diameter"
,
"is_bipartite"
,
"is_DAG"
,
"is_planar"
,
"make_maximal_planar"
,
"similarity"
,
"edge_reciprocity"
]
"all_paths"
,
"pseudo_diameter"
,
"is_bipartite"
,
"is_DAG"
,
"is_planar"
,
"make_maximal_planar"
,
"similarity"
,
"edge_reciprocity"
]
def
similarity
(
g1
,
g2
,
label1
=
None
,
label2
=
None
,
norm
=
True
):
r
"""Return the adjacency similarity between the two graphs.
...
...
@@ -1526,10 +1527,61 @@ def all_shortest_paths(g, source, target, weights=None, negative_weights=False,
if
all_preds_map
is
None
:
all_preds_map
=
all_predecessors
(
g
,
dist_map
,
pred_map
)
path_iterator
=
\
libgraph_tool_topology
.
get_all_shortest_paths
(
g
.
_Graph__graph
,
int
(
source
),
int
(
target
),
_prop
(
"v"
,
g
,
all_preds_map
))
return
path_iterator
def
all_paths
(
g
,
source
,
target
,
cutoff
=
None
):
"""Return an iterator over all paths from `source` to `target`.
Parameters
----------
g : :class:`~graph_tool.Graph`
Graph to be used.
source : :class:`~graph_tool.Vertex`
Source vertex of the search.
target : :class:`~graph_tool.Vertex`
Target vertex of the search.
cutoff : `int` (optional, default: None)
Maximum path length.
Returns
-------
path_iterator : iterator over a sequence of integers
Iterator over sequences of vertices from `source` to `target` in the
path.
Notes
-----
The algorithm uses a depth-first search to find all the paths.
The total number of paths between any two vertices can be quite large,
possibly scaling as :math:`O(V!)`.
Examples
--------
>>> g = gt.collection.data[""]
>>> for path in gt.all_paths(g, 13, 2, cutoff=2):
... print(path)
[13 15 2]
[13 60 2]
[13 64 2]
[ 13 100 2]
[ 13 106 2]
[13 2]
"""
if
cutoff
is
None
:
cutoff
=
g
.
num_edges
()
+
1
path_iterator
=
libgraph_tool_topology
.
get_all_paths
(
g
.
_Graph__graph
,
int
(
source
),
int
(
target
),
_prop
(
"v"
,
g
,
all_preds_map
)
)
cutoff
)
return
path_iterator
...
...
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