@@ -11,16 +11,25 @@ def _get_cutoff(n, cutoff):
11
11
return cutoff + 1 # Inclusive
12
12
13
13
14
- def _bfs_plain (G , source = None , target = None , * , index = None , cutoff = None ):
14
+ # Push-pull optimization is possible, but annoying to implement
15
+ def _bfs_plain (
16
+ G , source = None , target = None , * , index = None , cutoff = None , transpose = False , name = "bfs_plain"
17
+ ):
15
18
if source is not None :
19
+ if source not in G ._key_to_id :
20
+ raise KeyError (f"The node { source } is not in the graph" )
16
21
index = G ._key_to_id [source ]
17
22
if target is not None :
23
+ if target not in G ._key_to_id :
24
+ raise KeyError (f"The node { target } is not in the graph" )
18
25
dst_id = G ._key_to_id [target ]
19
26
else :
20
27
dst_id = None
21
28
A = G .get_property ("offdiag" )
29
+ if transpose and G .is_directed ():
30
+ A = A .T # TODO: should we use "AT" instead?
22
31
n = A .nrows
23
- v = Vector (bool , n , name = "bfs_plain" )
32
+ v = Vector (bool , n , name = name )
24
33
q = Vector (bool , n , name = "q" )
25
34
v [index ] = True
26
35
q [index ] = True
@@ -30,16 +39,22 @@ def _bfs_plain(G, source=None, target=None, *, index=None, cutoff=None):
30
39
q (~ v .S , replace ) << any_pair_bool (q @ A )
31
40
if q .nvals == 0 :
32
41
break
42
+ v (q .S ) << True
33
43
if dst_id is not None and dst_id in q :
34
44
break
35
- v (q .S ) << True
36
45
return v
37
46
38
47
39
- def _bfs_level (G , source , cutoff = None , * , transpose = False , dtype = int ):
48
+ def _bfs_level (G , source , target = None , * , cutoff = None , transpose = False , dtype = int ):
40
49
if dtype == bool :
41
50
dtype = int
42
51
index = G ._key_to_id [source ]
52
+ if target is not None :
53
+ if target not in G ._key_to_id :
54
+ raise KeyError (f"The node { target } is not in the graph" )
55
+ dst_id = G ._key_to_id [target ]
56
+ else :
57
+ dst_id = None
43
58
A = G .get_property ("offdiag" )
44
59
if transpose and G .is_directed ():
45
60
A = A .T # TODO: should we use "AT" instead?
@@ -55,10 +70,12 @@ def _bfs_level(G, source, cutoff=None, *, transpose=False, dtype=int):
55
70
if q .nvals == 0 :
56
71
break
57
72
v (q .S ) << i
73
+ if dst_id is not None and dst_id in q :
74
+ break
58
75
return v
59
76
60
77
61
- def _bfs_levels (G , nodes , cutoff = None , * , dtype = int ):
78
+ def _bfs_levels (G , nodes , * , cutoff = None , dtype = int ):
62
79
if dtype == bool :
63
80
dtype = int
64
81
A = G .get_property ("offdiag" )
@@ -90,7 +107,7 @@ def _bfs_levels(G, nodes, cutoff=None, *, dtype=int):
90
107
return D
91
108
92
109
93
- def _bfs_parent (G , source , cutoff = None , * , target = None , transpose = False , dtype = int ):
110
+ def _bfs_parent (G , source , target = None , * , cutoff = None , transpose = False , dtype = int ):
94
111
if dtype == bool :
95
112
dtype = int
96
113
index = G ._key_to_id [source ]
0 commit comments