Skip to content

Commit d63d49d

Browse files
authored
A few more algorithms and automatically add algorithms to README (#67)
* A few more algorithms and automatically add algorithms to README
1 parent 759b9cd commit d63d49d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+1000
-303
lines changed

Diff for: .github/workflows/lint.yml

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1+
# Rely on pre-commit.ci instead
12
name: Lint via pre-commit
23

34
on:
4-
pull_request:
5-
push:
6-
branches-ignore:
7-
- main
5+
workflow_dispatch:
6+
# pull_request:
7+
# push:
8+
# branches-ignore:
9+
# - main
810

911
permissions:
1012
contents: read

Diff for: .pre-commit-config.yaml

+5-5
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ repos:
2525
- id: mixed-line-ending
2626
- id: trailing-whitespace
2727
- repo: https://github.com/abravalheri/validate-pyproject
28-
rev: v0.12.2
28+
rev: v0.13
2929
hooks:
3030
- id: validate-pyproject
3131
name: Validate pyproject.toml
@@ -40,7 +40,7 @@ repos:
4040
hooks:
4141
- id: isort
4242
- repo: https://github.com/asottile/pyupgrade
43-
rev: v3.3.2
43+
rev: v3.4.0
4444
hooks:
4545
- id: pyupgrade
4646
args: [--py38-plus]
@@ -55,7 +55,7 @@ repos:
5555
- id: black
5656
# - id: black-jupyter
5757
- repo: https://github.com/charliermarsh/ruff-pre-commit
58-
rev: v0.0.264
58+
rev: v0.0.269
5959
hooks:
6060
- id: ruff
6161
args: [--fix-only, --show-fixes]
@@ -66,7 +66,7 @@ repos:
6666
additional_dependencies: &flake8_dependencies
6767
# These versions need updated manually
6868
- flake8==6.0.0
69-
- flake8-bugbear==23.3.23
69+
- flake8-bugbear==23.5.9
7070
- flake8-simplify==0.20.0
7171
- repo: https://github.com/asottile/yesqa
7272
rev: v1.4.0
@@ -81,7 +81,7 @@ repos:
8181
additional_dependencies: [tomli]
8282
files: ^(graphblas_algorithms|docs)/
8383
- repo: https://github.com/charliermarsh/ruff-pre-commit
84-
rev: v0.0.264
84+
rev: v0.0.269
8585
hooks:
8686
- id: ruff
8787
# `pyroma` may help keep our package standards up to date if best practices change.

Diff for: README.md

+135-90
Original file line numberDiff line numberDiff line change
@@ -112,93 +112,138 @@ The following NetworkX algorithms have been implemented
112112
by graphblas-algorithms and can be used following the
113113
dispatch pattern shown above.
114114

115-
- Boundary
116-
- edge_boundary
117-
- node_boundary
118-
- Centrality
119-
- degree_centrality
120-
- eigenvector_centrality
121-
- in_degree_centrality
122-
- katz_centrality
123-
- out_degree_centrality
124-
- Cluster
125-
- average_clustering
126-
- clustering
127-
- generalized_degree
128-
- square_clustering
129-
- transitivity
130-
- triangles
131-
- Community
132-
- inter_community_edges
133-
- intra_community_edges
134-
- Components
135-
- is_connected
136-
- is_weakly_connected
137-
- node_connected_component
138-
- Core
139-
- k_truss
140-
- Cuts
141-
- boundary_expansion
142-
- conductance
143-
- cut_size
144-
- edge_expansion
145-
- mixing_expansion
146-
- node_expansion
147-
- normalized_cut_size
148-
- volume
149-
- DAG
150-
- ancestors
151-
- descendants
152-
- Dominating
153-
- is_dominating_set
154-
- Generators
155-
- ego_graph
156-
- Isolate
157-
- is_isolate
158-
- isolates
159-
- number_of_isolates
160-
- Link Analysis
161-
- google_matrix
162-
- hits
163-
- pagerank
164-
- Operators
165-
- compose
166-
- difference
167-
- disjoint_union
168-
- full_join
169-
- intersection
170-
- symmetric_difference
171-
- union
172-
- Reciprocity
173-
- overall_reciprocity
174-
- reciprocity
175-
- Regular
176-
- is_k_regular
177-
- is_regular
178-
- Shortest Paths
179-
- all_pairs_bellman_ford_path_length
180-
- all_pairs_shortest_path_length
181-
- bellman_ford_path
182-
- floyd_warshall
183-
- floyd_warshall_numpy
184-
- floyd_warshall_predecessor_and_distance
185-
- has_path
186-
- negative_edge_cycle
187-
- single_source_bellman_ford_path_length
188-
- single_source_shortest_path_length
189-
- single_target_shortest_path_length
190-
- Simple Paths
191-
- is_simple_path
192-
- S Metric
193-
- s_metric
194-
- Structural Holes
195-
- mutual_weight
196-
- Tournament
197-
- is_tournament
198-
- score_sequence
199-
- tournament_matrix
200-
- Traversal
201-
- bfs_layers
202-
- descendants_at_distance
203-
- Triads
204-
- is_triad
115+
[//]: # (Begin auto-generated code)
116+
117+
```
118+
graphblas_algorithms.nxapi
119+
├── boundary
120+
│ ├── edge_boundary
121+
│ └── node_boundary
122+
├── centrality
123+
│ ├── degree_alg
124+
│ │ ├── degree_centrality
125+
│ │ ├── in_degree_centrality
126+
│ │ └── out_degree_centrality
127+
│ ├── eigenvector
128+
│ │ └── eigenvector_centrality
129+
│ └── katz
130+
│ └── katz_centrality
131+
├── cluster
132+
│ ├── average_clustering
133+
│ ├── clustering
134+
│ ├── generalized_degree
135+
│ ├── square_clustering
136+
│ ├── transitivity
137+
│ └── triangles
138+
├── community
139+
│ └── quality
140+
│ ├── inter_community_edges
141+
│ └── intra_community_edges
142+
├── components
143+
│ ├── connected
144+
│ │ ├── is_connected
145+
│ │ └── node_connected_component
146+
│ └── weakly_connected
147+
│ └── is_weakly_connected
148+
├── core
149+
│ └── k_truss
150+
├── cuts
151+
│ ├── boundary_expansion
152+
│ ├── conductance
153+
│ ├── cut_size
154+
│ ├── edge_expansion
155+
│ ├── mixing_expansion
156+
│ ├── node_expansion
157+
│ ├── normalized_cut_size
158+
│ └── volume
159+
├── dag
160+
│ ├── ancestors
161+
│ └── descendants
162+
├── dominating
163+
│ └── is_dominating_set
164+
├── efficiency_measures
165+
│ └── efficiency
166+
├── generators
167+
│ └── ego
168+
│ └── ego_graph
169+
├── isolate
170+
│ ├── is_isolate
171+
│ ├── isolates
172+
│ └── number_of_isolates
173+
├── isomorphism
174+
│ └── isomorph
175+
│ ├── fast_could_be_isomorphic
176+
│ └── faster_could_be_isomorphic
177+
├── linalg
178+
│ ├── bethehessianmatrix
179+
│ │ └── bethe_hessian_matrix
180+
│ ├── graphmatrix
181+
│ │ └── adjacency_matrix
182+
│ ├── laplacianmatrix
183+
│ │ ├── laplacian_matrix
184+
│ │ └── normalized_laplacian_matrix
185+
│ └── modularitymatrix
186+
│ ├── directed_modularity_matrix
187+
│ └── modularity_matrix
188+
├── link_analysis
189+
│ ├── hits_alg
190+
│ │ └── hits
191+
│ └── pagerank_alg
192+
│ ├── google_matrix
193+
│ └── pagerank
194+
├── lowest_common_ancestors
195+
│ └── lowest_common_ancestor
196+
├── operators
197+
│ ├── binary
198+
│ │ ├── compose
199+
│ │ ├── difference
200+
│ │ ├── disjoint_union
201+
│ │ ├── full_join
202+
│ │ ├── intersection
203+
│ │ ├── symmetric_difference
204+
│ │ └── union
205+
│ └── unary
206+
│ ├── complement
207+
│ └── reverse
208+
├── reciprocity
209+
│ ├── overall_reciprocity
210+
│ └── reciprocity
211+
├── regular
212+
│ ├── is_k_regular
213+
│ └── is_regular
214+
├── shortest_paths
215+
│ ├── dense
216+
│ │ ├── floyd_warshall
217+
│ │ ├── floyd_warshall_numpy
218+
│ │ └── floyd_warshall_predecessor_and_distance
219+
│ ├── generic
220+
│ │ └── has_path
221+
│ ├── unweighted
222+
│ │ ├── all_pairs_shortest_path_length
223+
│ │ ├── single_source_shortest_path_length
224+
│ │ └── single_target_shortest_path_length
225+
│ └── weighted
226+
│ ├── all_pairs_bellman_ford_path_length
227+
│ ├── bellman_ford_path
228+
│ ├── bellman_ford_path_length
229+
│ ├── negative_edge_cycle
230+
│ └── single_source_bellman_ford_path_length
231+
├── simple_paths
232+
│ └── is_simple_path
233+
├── smetric
234+
│ └── s_metric
235+
├── structuralholes
236+
│ └── mutual_weight
237+
├── tournament
238+
│ ├── is_tournament
239+
│ ├── score_sequence
240+
│ └── tournament_matrix
241+
├── traversal
242+
│ └── breadth_first_search
243+
│ ├── bfs_layers
244+
│ └── descendants_at_distance
245+
└── triads
246+
└── is_triad
247+
```
248+
249+
[//]: # (End auto-generated code)

Diff for: environment.yml

+2
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ dependencies:
4242
- pydot
4343
- pygraphviz
4444
- sympy
45+
# For updating algorithm list in README
46+
- rich
4547
# For linting
4648
- pre-commit
4749
# For testing

Diff for: graphblas_algorithms/__init__.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import importlib.metadata
22

33
from .classes import *
4+
from .generators import *
5+
from .linalg import *
46

57
from .algorithms import * # isort:skip
6-
from .generators import * # isort:skip
78

89
try:
910
__version__ = importlib.metadata.version("graphblas-algorithms")

Diff for: graphblas_algorithms/algorithms/__init__.py

+3
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,11 @@
88
from .cuts import *
99
from .dag import *
1010
from .dominating import *
11+
from .efficiency_measures import *
1112
from .isolate import *
13+
from .isomorphism import *
1214
from .link_analysis import *
15+
from .lowest_common_ancestors import *
1316
from .operators import *
1417
from .reciprocity import *
1518
from .regular import *

Diff for: graphblas_algorithms/algorithms/_bfs.py

+23-6
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,25 @@ def _get_cutoff(n, cutoff):
1111
return cutoff + 1 # Inclusive
1212

1313

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+
):
1518
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")
1621
index = G._key_to_id[source]
1722
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")
1825
dst_id = G._key_to_id[target]
1926
else:
2027
dst_id = None
2128
A = G.get_property("offdiag")
29+
if transpose and G.is_directed():
30+
A = A.T # TODO: should we use "AT" instead?
2231
n = A.nrows
23-
v = Vector(bool, n, name="bfs_plain")
32+
v = Vector(bool, n, name=name)
2433
q = Vector(bool, n, name="q")
2534
v[index] = True
2635
q[index] = True
@@ -30,16 +39,22 @@ def _bfs_plain(G, source=None, target=None, *, index=None, cutoff=None):
3039
q(~v.S, replace) << any_pair_bool(q @ A)
3140
if q.nvals == 0:
3241
break
42+
v(q.S) << True
3343
if dst_id is not None and dst_id in q:
3444
break
35-
v(q.S) << True
3645
return v
3746

3847

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):
4049
if dtype == bool:
4150
dtype = int
4251
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
4358
A = G.get_property("offdiag")
4459
if transpose and G.is_directed():
4560
A = A.T # TODO: should we use "AT" instead?
@@ -55,10 +70,12 @@ def _bfs_level(G, source, cutoff=None, *, transpose=False, dtype=int):
5570
if q.nvals == 0:
5671
break
5772
v(q.S) << i
73+
if dst_id is not None and dst_id in q:
74+
break
5875
return v
5976

6077

61-
def _bfs_levels(G, nodes, cutoff=None, *, dtype=int):
78+
def _bfs_levels(G, nodes, *, cutoff=None, dtype=int):
6279
if dtype == bool:
6380
dtype = int
6481
A = G.get_property("offdiag")
@@ -90,7 +107,7 @@ def _bfs_levels(G, nodes, cutoff=None, *, dtype=int):
90107
return D
91108

92109

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):
94111
if dtype == bool:
95112
dtype = int
96113
index = G._key_to_id[source]

0 commit comments

Comments
 (0)