@graphty/algorithms 2.1.2 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +139 -50
- package/dist/algorithms.js +15260 -10390
- package/dist/algorithms.js.map +1 -1
- package/dist/algorithms.standalone.js +26675 -21542
- package/dist/algorithms.standalone.js.map +1 -1
- package/dist/src/algorithms/centrality/betweenness.d.ts +18 -0
- package/dist/src/algorithms/centrality/betweenness.d.ts.map +1 -1
- package/dist/src/algorithms/centrality/betweenness.js +40 -1
- package/dist/src/algorithms/centrality/betweenness.js.map +1 -1
- package/dist/src/algorithms/centrality/closeness.d.ts +20 -0
- package/dist/src/algorithms/centrality/closeness.d.ts.map +1 -1
- package/dist/src/algorithms/centrality/closeness.js +93 -8
- package/dist/src/algorithms/centrality/closeness.js.map +1 -1
- package/dist/src/algorithms/centrality/degree.d.ts +9 -0
- package/dist/src/algorithms/centrality/degree.d.ts.map +1 -1
- package/dist/src/algorithms/centrality/degree.js +18 -0
- package/dist/src/algorithms/centrality/degree.js.map +1 -1
- package/dist/src/algorithms/centrality/eigenvector.d.ts +10 -0
- package/dist/src/algorithms/centrality/eigenvector.d.ts.map +1 -1
- package/dist/src/algorithms/centrality/eigenvector.js +29 -0
- package/dist/src/algorithms/centrality/eigenvector.js.map +1 -1
- package/dist/src/algorithms/centrality/hits.d.ts +9 -0
- package/dist/src/algorithms/centrality/hits.d.ts.map +1 -1
- package/dist/src/algorithms/centrality/hits.js +23 -0
- package/dist/src/algorithms/centrality/hits.js.map +1 -1
- package/dist/src/algorithms/centrality/katz.d.ts +9 -0
- package/dist/src/algorithms/centrality/katz.d.ts.map +1 -1
- package/dist/src/algorithms/centrality/katz.js +31 -0
- package/dist/src/algorithms/centrality/katz.js.map +1 -1
- package/dist/src/algorithms/centrality/pagerank.d.ts +13 -13
- package/dist/src/algorithms/centrality/pagerank.d.ts.map +1 -1
- package/dist/src/algorithms/centrality/pagerank.js +47 -10
- package/dist/src/algorithms/centrality/pagerank.js.map +1 -1
- package/dist/src/algorithms/community/girvan-newman-legacy.d.ts +27 -0
- package/dist/src/algorithms/community/girvan-newman-legacy.d.ts.map +1 -0
- package/dist/src/algorithms/community/girvan-newman-legacy.js +335 -0
- package/dist/src/algorithms/community/girvan-newman-legacy.js.map +1 -0
- package/dist/src/algorithms/community/girvan-newman.d.ts +5 -3
- package/dist/src/algorithms/community/girvan-newman.d.ts.map +1 -1
- package/dist/src/algorithms/community/girvan-newman.js +34 -308
- package/dist/src/algorithms/community/girvan-newman.js.map +1 -1
- package/dist/src/algorithms/community/label-propagation.d.ts +9 -6
- package/dist/src/algorithms/community/label-propagation.d.ts.map +1 -1
- package/dist/src/algorithms/community/label-propagation.js +24 -110
- package/dist/src/algorithms/community/label-propagation.js.map +1 -1
- package/dist/src/algorithms/components/connected.d.ts.map +1 -1
- package/dist/src/algorithms/components/connected.js +28 -77
- package/dist/src/algorithms/components/connected.js.map +1 -1
- package/dist/src/algorithms/mst/kruskal.d.ts.map +1 -1
- package/dist/src/algorithms/mst/kruskal.js +59 -3
- package/dist/src/algorithms/mst/kruskal.js.map +1 -1
- package/dist/src/algorithms/shortest-path/bellman-ford.d.ts.map +1 -1
- package/dist/src/algorithms/shortest-path/bellman-ford.js +46 -0
- package/dist/src/algorithms/shortest-path/bellman-ford.js.map +1 -1
- package/dist/src/algorithms/shortest-path/dijkstra.d.ts.map +1 -1
- package/dist/src/algorithms/shortest-path/dijkstra.js +27 -0
- package/dist/src/algorithms/shortest-path/dijkstra.js.map +1 -1
- package/dist/src/algorithms/shortest-path/floyd-warshall.d.ts +15 -5
- package/dist/src/algorithms/shortest-path/floyd-warshall.d.ts.map +1 -1
- package/dist/src/algorithms/shortest-path/floyd-warshall.js +97 -107
- package/dist/src/algorithms/shortest-path/floyd-warshall.js.map +1 -1
- package/dist/src/algorithms/traversal/bfs-unified.d.ts +2 -12
- package/dist/src/algorithms/traversal/bfs-unified.d.ts.map +1 -1
- package/dist/src/algorithms/traversal/bfs-unified.js +47 -308
- package/dist/src/algorithms/traversal/bfs-unified.js.map +1 -1
- package/dist/src/algorithms/traversal/bfs-variants.d.ts.map +1 -1
- package/dist/src/algorithms/traversal/bfs-variants.js +5 -25
- package/dist/src/algorithms/traversal/bfs-variants.js.map +1 -1
- package/dist/src/algorithms/traversal/bfs.d.ts +0 -3
- package/dist/src/algorithms/traversal/bfs.d.ts.map +1 -1
- package/dist/src/algorithms/traversal/bfs.js +0 -4
- package/dist/src/algorithms/traversal/bfs.js.map +1 -1
- package/dist/src/algorithms/traversal/dfs.d.ts.map +1 -1
- package/dist/src/algorithms/traversal/dfs.js +33 -154
- package/dist/src/algorithms/traversal/dfs.js.map +1 -1
- package/dist/src/clustering/hierarchical-legacy.d.ts +56 -0
- package/dist/src/clustering/hierarchical-legacy.d.ts.map +1 -0
- package/dist/src/clustering/hierarchical-legacy.js +441 -0
- package/dist/src/clustering/hierarchical-legacy.js.map +1 -0
- package/dist/src/clustering/hierarchical.d.ts +7 -39
- package/dist/src/clustering/hierarchical.d.ts.map +1 -1
- package/dist/src/clustering/hierarchical.js +56 -417
- package/dist/src/clustering/hierarchical.js.map +1 -1
- package/dist/src/clustering/k-core-legacy.d.ts +30 -0
- package/dist/src/clustering/k-core-legacy.d.ts.map +1 -0
- package/dist/src/clustering/k-core-legacy.js +191 -0
- package/dist/src/clustering/k-core-legacy.js.map +1 -0
- package/dist/src/clustering/k-core.d.ts +8 -7
- package/dist/src/clustering/k-core.d.ts.map +1 -1
- package/dist/src/clustering/k-core.js +33 -174
- package/dist/src/clustering/k-core.js.map +1 -1
- package/dist/src/clustering/mcl-legacy.d.ts +42 -0
- package/dist/src/clustering/mcl-legacy.d.ts.map +1 -0
- package/dist/src/clustering/mcl-legacy.js +386 -0
- package/dist/src/clustering/mcl-legacy.js.map +1 -0
- package/dist/src/clustering/mcl.d.ts +9 -32
- package/dist/src/clustering/mcl.d.ts.map +1 -1
- package/dist/src/clustering/mcl.js +48 -374
- package/dist/src/clustering/mcl.js.map +1 -1
- package/dist/src/index.d.ts +29 -3
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +2 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/indexed/accelerator.d.ts +141 -11
- package/dist/src/indexed/accelerator.d.ts.map +1 -1
- package/dist/src/indexed/accelerator.js +319 -5
- package/dist/src/indexed/accelerator.js.map +1 -1
- package/dist/src/indexed/all-pairs.d.ts +59 -0
- package/dist/src/indexed/all-pairs.d.ts.map +1 -0
- package/dist/src/indexed/all-pairs.js +274 -0
- package/dist/src/indexed/all-pairs.js.map +1 -0
- package/dist/src/indexed/bellman-ford.d.ts +25 -0
- package/dist/src/indexed/bellman-ford.d.ts.map +1 -0
- package/dist/src/indexed/bellman-ford.js +59 -0
- package/dist/src/indexed/bellman-ford.js.map +1 -0
- package/dist/src/indexed/betweenness.d.ts +85 -0
- package/dist/src/indexed/betweenness.d.ts.map +1 -0
- package/dist/src/indexed/betweenness.js +188 -0
- package/dist/src/indexed/betweenness.js.map +1 -0
- package/dist/src/indexed/bfs.d.ts +69 -2
- package/dist/src/indexed/bfs.d.ts.map +1 -1
- package/dist/src/indexed/bfs.js +148 -1
- package/dist/src/indexed/bfs.js.map +1 -1
- package/dist/src/indexed/bipartite.d.ts +37 -0
- package/dist/src/indexed/bipartite.d.ts.map +1 -0
- package/dist/src/indexed/bipartite.js +54 -0
- package/dist/src/indexed/bipartite.js.map +1 -0
- package/dist/src/indexed/closeness.d.ts +49 -0
- package/dist/src/indexed/closeness.d.ts.map +1 -0
- package/dist/src/indexed/closeness.js +127 -0
- package/dist/src/indexed/closeness.js.map +1 -0
- package/dist/src/indexed/common-neighbors.d.ts +14 -1
- package/dist/src/indexed/common-neighbors.d.ts.map +1 -1
- package/dist/src/indexed/common-neighbors.js +24 -14
- package/dist/src/indexed/common-neighbors.js.map +1 -1
- package/dist/src/indexed/degree.d.ts +19 -0
- package/dist/src/indexed/degree.d.ts.map +1 -0
- package/dist/src/indexed/degree.js +45 -0
- package/dist/src/indexed/degree.js.map +1 -0
- package/dist/src/indexed/delta-pagerank.d.ts +145 -0
- package/dist/src/indexed/delta-pagerank.d.ts.map +1 -0
- package/dist/src/indexed/delta-pagerank.js +428 -0
- package/dist/src/indexed/delta-pagerank.js.map +1 -0
- package/dist/src/indexed/dfs.d.ts +55 -0
- package/dist/src/indexed/dfs.d.ts.map +1 -0
- package/dist/src/indexed/dfs.js +146 -0
- package/dist/src/indexed/dfs.js.map +1 -0
- package/dist/src/indexed/eigenvector.d.ts +48 -0
- package/dist/src/indexed/eigenvector.d.ts.map +1 -0
- package/dist/src/indexed/eigenvector.js +162 -0
- package/dist/src/indexed/eigenvector.js.map +1 -0
- package/dist/src/indexed/facade.d.ts +109 -0
- package/dist/src/indexed/facade.d.ts.map +1 -0
- package/dist/src/indexed/facade.js +204 -0
- package/dist/src/indexed/facade.js.map +1 -0
- package/dist/src/indexed/flow.d.ts +120 -0
- package/dist/src/indexed/flow.d.ts.map +1 -0
- package/dist/src/indexed/flow.js +377 -0
- package/dist/src/indexed/flow.js.map +1 -0
- package/dist/src/indexed/girvan-newman.d.ts +42 -0
- package/dist/src/indexed/girvan-newman.d.ts.map +1 -0
- package/dist/src/indexed/girvan-newman.js +90 -0
- package/dist/src/indexed/girvan-newman.js.map +1 -0
- package/dist/src/indexed/grsbm.d.ts +85 -0
- package/dist/src/indexed/grsbm.d.ts.map +1 -0
- package/dist/src/indexed/grsbm.js +287 -0
- package/dist/src/indexed/grsbm.js.map +1 -0
- package/dist/src/indexed/hierarchical.d.ts +69 -0
- package/dist/src/indexed/hierarchical.d.ts.map +1 -0
- package/dist/src/indexed/hierarchical.js +245 -0
- package/dist/src/indexed/hierarchical.js.map +1 -0
- package/dist/src/indexed/index.d.ts +29 -3
- package/dist/src/indexed/index.d.ts.map +1 -1
- package/dist/src/indexed/index.js +29 -3
- package/dist/src/indexed/index.js.map +1 -1
- package/dist/src/indexed/isomorphism.d.ts +42 -0
- package/dist/src/indexed/isomorphism.d.ts.map +1 -0
- package/dist/src/indexed/isomorphism.js +269 -0
- package/dist/src/indexed/isomorphism.js.map +1 -0
- package/dist/src/indexed/label-propagation.d.ts +134 -0
- package/dist/src/indexed/label-propagation.d.ts.map +1 -0
- package/dist/src/indexed/label-propagation.js +486 -0
- package/dist/src/indexed/label-propagation.js.map +1 -0
- package/dist/src/indexed/leiden.d.ts +52 -0
- package/dist/src/indexed/leiden.d.ts.map +1 -0
- package/dist/src/indexed/leiden.js +384 -0
- package/dist/src/indexed/leiden.js.map +1 -0
- package/dist/src/indexed/link-prediction.d.ts +147 -0
- package/dist/src/indexed/link-prediction.d.ts.map +1 -0
- package/dist/src/indexed/link-prediction.js +317 -0
- package/dist/src/indexed/link-prediction.js.map +1 -0
- package/dist/src/indexed/markov.d.ts +54 -0
- package/dist/src/indexed/markov.d.ts.map +1 -0
- package/dist/src/indexed/markov.js +284 -0
- package/dist/src/indexed/markov.js.map +1 -0
- package/dist/src/indexed/matching.d.ts +53 -0
- package/dist/src/indexed/matching.d.ts.map +1 -0
- package/dist/src/indexed/matching.js +139 -0
- package/dist/src/indexed/matching.js.map +1 -0
- package/dist/src/indexed/min-cut.d.ts +48 -0
- package/dist/src/indexed/min-cut.d.ts.map +1 -0
- package/dist/src/indexed/min-cut.js +175 -0
- package/dist/src/indexed/min-cut.js.map +1 -0
- package/dist/src/indexed/modularity.d.ts +34 -0
- package/dist/src/indexed/modularity.d.ts.map +1 -0
- package/dist/src/indexed/modularity.js +74 -0
- package/dist/src/indexed/modularity.js.map +1 -0
- package/dist/src/indexed/mst.d.ts +29 -1
- package/dist/src/indexed/mst.d.ts.map +1 -1
- package/dist/src/indexed/mst.js +62 -0
- package/dist/src/indexed/mst.js.map +1 -1
- package/dist/src/indexed/pagerank.d.ts +29 -6
- package/dist/src/indexed/pagerank.d.ts.map +1 -1
- package/dist/src/indexed/pagerank.js +107 -11
- package/dist/src/indexed/pagerank.js.map +1 -1
- package/dist/src/indexed/point-to-point.d.ts +53 -0
- package/dist/src/indexed/point-to-point.d.ts.map +1 -0
- package/dist/src/indexed/point-to-point.js +173 -0
- package/dist/src/indexed/point-to-point.js.map +1 -0
- package/dist/src/indexed/scc.d.ts +53 -0
- package/dist/src/indexed/scc.d.ts.map +1 -0
- package/dist/src/indexed/scc.js +110 -0
- package/dist/src/indexed/scc.js.map +1 -0
- package/dist/src/indexed/spectral.d.ts +61 -0
- package/dist/src/indexed/spectral.d.ts.map +1 -0
- package/dist/src/indexed/spectral.js +476 -0
- package/dist/src/indexed/spectral.js.map +1 -0
- package/dist/src/indexed/structures/bit-set.d.ts +45 -0
- package/dist/src/indexed/structures/bit-set.d.ts.map +1 -0
- package/dist/src/indexed/structures/bit-set.js +57 -0
- package/dist/src/indexed/structures/bit-set.js.map +1 -0
- package/dist/src/indexed/structures/max-heap.d.ts +52 -0
- package/dist/src/indexed/structures/max-heap.d.ts.map +1 -0
- package/dist/src/indexed/structures/max-heap.js +66 -0
- package/dist/src/indexed/structures/max-heap.js.map +1 -0
- package/dist/src/indexed/structures/min-heap.d.ts +30 -1
- package/dist/src/indexed/structures/min-heap.d.ts.map +1 -1
- package/dist/src/indexed/structures/min-heap.js +46 -6
- package/dist/src/indexed/structures/min-heap.js.map +1 -1
- package/dist/src/indexed/structures/ring-queue.d.ts +41 -0
- package/dist/src/indexed/structures/ring-queue.d.ts.map +1 -0
- package/dist/src/indexed/structures/ring-queue.js +64 -0
- package/dist/src/indexed/structures/ring-queue.js.map +1 -0
- package/dist/src/indexed/sync.d.ts +50 -0
- package/dist/src/indexed/sync.d.ts.map +1 -0
- package/dist/src/indexed/sync.js +175 -0
- package/dist/src/indexed/sync.js.map +1 -0
- package/dist/src/indexed/terahac.d.ts +58 -0
- package/dist/src/indexed/terahac.d.ts.map +1 -0
- package/dist/src/indexed/terahac.js +244 -0
- package/dist/src/indexed/terahac.js.map +1 -0
- package/dist/src/indexed/to-snapshot.d.ts +45 -2
- package/dist/src/indexed/to-snapshot.d.ts.map +1 -1
- package/dist/src/indexed/to-snapshot.js +140 -6
- package/dist/src/indexed/to-snapshot.js.map +1 -1
- package/dist/src/link-prediction/common-neighbors-legacy.d.ts +71 -0
- package/dist/src/link-prediction/common-neighbors-legacy.d.ts.map +1 -0
- package/dist/src/link-prediction/common-neighbors-legacy.js +172 -0
- package/dist/src/link-prediction/common-neighbors-legacy.js.map +1 -0
- package/dist/src/link-prediction/common-neighbors.d.ts +11 -19
- package/dist/src/link-prediction/common-neighbors.d.ts.map +1 -1
- package/dist/src/link-prediction/common-neighbors.js +56 -123
- package/dist/src/link-prediction/common-neighbors.js.map +1 -1
- package/dist/src/optimized/direction-optimized-bfs.d.ts +6 -0
- package/dist/src/optimized/direction-optimized-bfs.d.ts.map +1 -1
- package/dist/src/optimized/direction-optimized-bfs.js +6 -0
- package/dist/src/optimized/direction-optimized-bfs.js.map +1 -1
- package/dist/src/research/grsbm-legacy.d.ts +82 -0
- package/dist/src/research/grsbm-legacy.d.ts.map +1 -0
- package/dist/src/research/grsbm-legacy.js +416 -0
- package/dist/src/research/grsbm-legacy.js.map +1 -0
- package/dist/src/research/grsbm.d.ts +9 -66
- package/dist/src/research/grsbm.d.ts.map +1 -1
- package/dist/src/research/grsbm.js +67 -391
- package/dist/src/research/grsbm.js.map +1 -1
- package/dist/src/research/sync-legacy.d.ts +48 -0
- package/dist/src/research/sync-legacy.d.ts.map +1 -0
- package/dist/src/research/sync-legacy.js +337 -0
- package/dist/src/research/sync-legacy.js.map +1 -0
- package/dist/src/research/sync.d.ts +10 -32
- package/dist/src/research/sync.d.ts.map +1 -1
- package/dist/src/research/sync.js +28 -316
- package/dist/src/research/sync.js.map +1 -1
- package/package.json +4 -3
- package/src/algorithms/centrality/betweenness.ts +51 -1
- package/src/algorithms/centrality/closeness.ts +112 -12
- package/src/algorithms/centrality/degree.ts +19 -0
- package/src/algorithms/centrality/eigenvector.ts +34 -0
- package/src/algorithms/centrality/hits.ts +24 -0
- package/src/algorithms/centrality/katz.ts +32 -0
- package/src/algorithms/centrality/pagerank.ts +53 -13
- package/src/algorithms/community/girvan-newman-legacy.ts +414 -0
- package/src/algorithms/community/girvan-newman.ts +36 -386
- package/src/algorithms/community/label-propagation.ts +24 -133
- package/src/algorithms/components/connected.ts +28 -95
- package/src/algorithms/mst/kruskal.ts +65 -4
- package/src/algorithms/shortest-path/bellman-ford.ts +49 -0
- package/src/algorithms/shortest-path/dijkstra.ts +29 -0
- package/src/algorithms/shortest-path/floyd-warshall.ts +106 -136
- package/src/algorithms/traversal/bfs-unified.ts +52 -366
- package/src/algorithms/traversal/bfs-variants.ts +5 -28
- package/src/algorithms/traversal/bfs.ts +0 -4
- package/src/algorithms/traversal/dfs.ts +39 -182
- package/src/clustering/hierarchical-legacy.ts +551 -0
- package/src/clustering/hierarchical.ts +64 -520
- package/src/clustering/k-core-legacy.ts +229 -0
- package/src/clustering/k-core.ts +38 -209
- package/src/clustering/mcl-legacy.ts +498 -0
- package/src/clustering/mcl.ts +46 -479
- package/src/index.ts +90 -3
- package/src/indexed/accelerator.ts +502 -16
- package/src/indexed/all-pairs.ts +342 -0
- package/src/indexed/bellman-ford.ts +72 -0
- package/src/indexed/betweenness.ts +258 -0
- package/src/indexed/bfs.ts +189 -3
- package/src/indexed/bipartite.ts +77 -0
- package/src/indexed/closeness.ts +160 -0
- package/src/indexed/common-neighbors.ts +31 -14
- package/src/indexed/degree.ts +55 -0
- package/src/indexed/delta-pagerank.ts +513 -0
- package/src/indexed/dfs.ts +189 -0
- package/src/indexed/eigenvector.ts +202 -0
- package/src/indexed/facade.ts +229 -0
- package/src/indexed/flow.ts +500 -0
- package/src/indexed/girvan-newman.ts +120 -0
- package/src/indexed/grsbm.ts +390 -0
- package/src/indexed/hierarchical.ts +295 -0
- package/src/indexed/index.ts +94 -3
- package/src/indexed/isomorphism.ts +305 -0
- package/src/indexed/label-propagation.ts +582 -0
- package/src/indexed/leiden.ts +436 -0
- package/src/indexed/link-prediction.ts +399 -0
- package/src/indexed/markov.ts +324 -0
- package/src/indexed/matching.ts +192 -0
- package/src/indexed/min-cut.ts +201 -0
- package/src/indexed/modularity.ts +81 -0
- package/src/indexed/mst.ts +79 -1
- package/src/indexed/pagerank.ts +128 -15
- package/src/indexed/point-to-point.ts +220 -0
- package/src/indexed/scc.ts +132 -0
- package/src/indexed/spectral.ts +550 -0
- package/src/indexed/structures/bit-set.ts +65 -0
- package/src/indexed/structures/max-heap.ts +74 -0
- package/src/indexed/structures/min-heap.ts +51 -6
- package/src/indexed/structures/ring-queue.ts +70 -0
- package/src/indexed/sync.ts +229 -0
- package/src/indexed/terahac.ts +290 -0
- package/src/indexed/to-snapshot.ts +156 -6
- package/src/link-prediction/common-neighbors-legacy.ts +252 -0
- package/src/link-prediction/common-neighbors.ts +65 -168
- package/src/optimized/direction-optimized-bfs.ts +6 -1
- package/src/research/grsbm-legacy.ts +586 -0
- package/src/research/grsbm.ts +76 -555
- package/src/research/sync-legacy.ts +456 -0
- package/src/research/sync.ts +30 -431
|
@@ -1,28 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Common-neighbour link prediction over a legacy `Graph`. Every function here delegates to its
|
|
3
|
+
* `indexed.*` port over an unweighted snapshot of the graph (the scores never read a weight) and
|
|
4
|
+
* keeps its signature and result shape; the results equal the pre-migration implementation in
|
|
5
|
+
* `common-neighbors-legacy.ts` exactly.
|
|
6
|
+
*
|
|
7
|
+
* A node argument is looked up by the id itself, never by its spelling, as `graph.hasNode` does: a
|
|
8
|
+
* node that is not in the graph scores 0 and has no candidates.
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import type { GraphSnapshot } from "@graphty/graph-format";
|
|
13
|
+
|
|
1
14
|
import type { Graph } from "../core/graph.js";
|
|
15
|
+
import { commonNeighborsScore as indexedCommonNeighborsScore } from "../indexed/common-neighbors.js";
|
|
16
|
+
import {
|
|
17
|
+
commonNeighborsForPairs as indexedCommonNeighborsForPairs,
|
|
18
|
+
commonNeighborsPrediction as indexedCommonNeighborsPrediction,
|
|
19
|
+
evaluateCommonNeighbors as indexedEvaluateCommonNeighbors,
|
|
20
|
+
getTopCandidatesForNode as indexedGetTopCandidatesForNode,
|
|
21
|
+
type LinkPredictionResult,
|
|
22
|
+
type NodePairs,
|
|
23
|
+
} from "../indexed/link-prediction.js";
|
|
24
|
+
import { toTopologySnapshot } from "../indexed/to-snapshot.js";
|
|
2
25
|
import type { NodeId } from "../types/index.js";
|
|
3
|
-
import {
|
|
26
|
+
import type { LinkPredictionOptions, LinkPredictionScore } from "./common-neighbors-legacy.js";
|
|
27
|
+
|
|
28
|
+
export type { LinkPredictionOptions, LinkPredictionScore } from "./common-neighbors-legacy.js";
|
|
4
29
|
|
|
5
30
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* common neighbors are more likely to be connected.
|
|
11
|
-
*
|
|
12
|
-
* Time complexity: O(k²) where k is the average degree
|
|
13
|
-
* Space complexity: O(k)
|
|
31
|
+
* Id pairs to index pairs; an id not in the graph becomes `INVALID_INDEX`, which scores 0.
|
|
32
|
+
* @param s - The snapshot
|
|
33
|
+
* @param pairs - The caller's id pairs
|
|
34
|
+
* @returns The index pairs
|
|
14
35
|
*/
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
36
|
+
function toNodePairs(s: GraphSnapshot, pairs: [NodeId, NodeId][]): NodePairs {
|
|
37
|
+
return {
|
|
38
|
+
sources: Uint32Array.from(pairs, ([u]) => s.ids.indexOf(u)),
|
|
39
|
+
targets: Uint32Array.from(pairs, ([, v]) => s.ids.indexOf(v)),
|
|
40
|
+
};
|
|
20
41
|
}
|
|
21
42
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
43
|
+
/**
|
|
44
|
+
* Ranked index pairs to the legacy score objects.
|
|
45
|
+
* @param s - The snapshot
|
|
46
|
+
* @param r - The port's ranked pairs
|
|
47
|
+
* @returns One score object per pair, in rank order
|
|
48
|
+
*/
|
|
49
|
+
function toScores(s: GraphSnapshot, r: LinkPredictionResult): LinkPredictionScore[] {
|
|
50
|
+
return Array.from(r.scores, (score, k) => ({
|
|
51
|
+
source: s.ids.idOf(r.sources[k]),
|
|
52
|
+
target: s.ids.idOf(r.targets[k]),
|
|
53
|
+
score,
|
|
54
|
+
}));
|
|
26
55
|
}
|
|
27
56
|
|
|
28
57
|
/**
|
|
@@ -39,19 +68,13 @@ export function commonNeighborsScore(
|
|
|
39
68
|
target: NodeId,
|
|
40
69
|
options: LinkPredictionOptions = {},
|
|
41
70
|
): number {
|
|
42
|
-
|
|
71
|
+
const s = toTopologySnapshot(graph);
|
|
72
|
+
const u = s.ids.indexOf(source);
|
|
73
|
+
const v = s.ids.indexOf(target);
|
|
74
|
+
if (u >= s.nodeCount || v >= s.nodeCount) {
|
|
43
75
|
return 0;
|
|
44
76
|
}
|
|
45
|
-
|
|
46
|
-
const { directed = false } = options;
|
|
47
|
-
|
|
48
|
-
// Use utility function to get common neighbors
|
|
49
|
-
// For directed graphs, we want intermediate nodes that form paths source->X->target
|
|
50
|
-
const commonNeighborsSet = directed
|
|
51
|
-
? getIntermediateNodes(graph, source, target)
|
|
52
|
-
: getCommonNeighbors(graph, source, target, false);
|
|
53
|
-
|
|
54
|
-
return commonNeighborsSet.size;
|
|
77
|
+
return indexedCommonNeighborsScore(s, u, v, { directed: options.directed });
|
|
55
78
|
}
|
|
56
79
|
|
|
57
80
|
/**
|
|
@@ -61,47 +84,8 @@ export function commonNeighborsScore(
|
|
|
61
84
|
* @returns Array of link prediction scores sorted by score descending
|
|
62
85
|
*/
|
|
63
86
|
export function commonNeighborsPrediction(graph: Graph, options: LinkPredictionOptions = {}): LinkPredictionScore[] {
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
const scores: LinkPredictionScore[] = [];
|
|
67
|
-
const nodes = Array.from(graph.nodes()).map((n) => n.id);
|
|
68
|
-
|
|
69
|
-
for (let i = 0; i < nodes.length; i++) {
|
|
70
|
-
for (let j = i + 1; j < nodes.length; j++) {
|
|
71
|
-
const source = nodes[i];
|
|
72
|
-
const target = nodes[j];
|
|
73
|
-
|
|
74
|
-
if (source === undefined || target === undefined) {
|
|
75
|
-
continue;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// Skip existing edges unless requested
|
|
79
|
-
if (!includeExisting && graph.hasEdge(source, target)) {
|
|
80
|
-
continue;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
const score = commonNeighborsScore(graph, source, target, { directed });
|
|
84
|
-
|
|
85
|
-
if (score > 0) {
|
|
86
|
-
scores.push({ source, target, score });
|
|
87
|
-
|
|
88
|
-
// For undirected graphs, also add the reverse pair
|
|
89
|
-
if (!directed && source !== target) {
|
|
90
|
-
scores.push({ source: target, target: source, score });
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// Sort by score in descending order
|
|
97
|
-
scores.sort((a, b) => b.score - a.score);
|
|
98
|
-
|
|
99
|
-
// Return top K if specified
|
|
100
|
-
if (topK && topK > 0) {
|
|
101
|
-
return scores.slice(0, topK);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
return scores;
|
|
87
|
+
const s = toTopologySnapshot(graph);
|
|
88
|
+
return toScores(s, indexedCommonNeighborsPrediction(s, options));
|
|
105
89
|
}
|
|
106
90
|
|
|
107
91
|
/**
|
|
@@ -116,11 +100,9 @@ export function commonNeighborsForPairs(
|
|
|
116
100
|
pairs: [NodeId, NodeId][],
|
|
117
101
|
options: LinkPredictionOptions = {},
|
|
118
102
|
): LinkPredictionScore[] {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
score: commonNeighborsScore(graph, source, target, options),
|
|
123
|
-
}));
|
|
103
|
+
const s = toTopologySnapshot(graph);
|
|
104
|
+
const scores = indexedCommonNeighborsForPairs(s, toNodePairs(s, pairs), { directed: options.directed });
|
|
105
|
+
return pairs.map(([source, target], k) => ({ source, target, score: scores[k] }));
|
|
124
106
|
}
|
|
125
107
|
|
|
126
108
|
/**
|
|
@@ -135,36 +117,9 @@ export function getTopCandidatesForNode(
|
|
|
135
117
|
node: NodeId,
|
|
136
118
|
options: LinkPredictionOptions & { candidates?: NodeId[] } = {},
|
|
137
119
|
): LinkPredictionScore[] {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
const { directed = false, includeExisting = false, topK = 10, candidates } = options;
|
|
143
|
-
|
|
144
|
-
const scores: LinkPredictionScore[] = [];
|
|
145
|
-
const targetNodes = candidates ?? Array.from(graph.nodes()).map((n) => n.id);
|
|
146
|
-
|
|
147
|
-
for (const target of targetNodes) {
|
|
148
|
-
if (target === node) {
|
|
149
|
-
continue;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
// Skip existing edges unless requested
|
|
153
|
-
if (!includeExisting && graph.hasEdge(node, target)) {
|
|
154
|
-
continue;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
const score = commonNeighborsScore(graph, node, target, { directed });
|
|
158
|
-
|
|
159
|
-
if (score > 0) {
|
|
160
|
-
scores.push({ source: node, target, score });
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
// Sort by score in descending order
|
|
165
|
-
scores.sort((a, b) => b.score - a.score);
|
|
166
|
-
|
|
167
|
-
return scores.slice(0, topK);
|
|
120
|
+
const s = toTopologySnapshot(graph);
|
|
121
|
+
const candidates = options.candidates?.map((id) => s.ids.indexOf(id));
|
|
122
|
+
return toScores(s, indexedGetTopCandidatesForNode(s, s.ids.indexOf(node), { ...options, candidates }));
|
|
168
123
|
}
|
|
169
124
|
|
|
170
125
|
/**
|
|
@@ -186,67 +141,9 @@ export function evaluateCommonNeighbors(
|
|
|
186
141
|
f1Score: number;
|
|
187
142
|
auc: number;
|
|
188
143
|
} {
|
|
189
|
-
|
|
190
|
-
const
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
const allScores = [
|
|
195
|
-
...testScores.map((s) => ({ ...s, isActualEdge: true })),
|
|
196
|
-
...nonEdgeScores.map((s) => ({ ...s, isActualEdge: false })),
|
|
197
|
-
].sort((a, b) => b.score - a.score);
|
|
198
|
-
|
|
199
|
-
// Calculate precision and recall at different thresholds
|
|
200
|
-
let truePositives = 0;
|
|
201
|
-
let falsePositives = 0;
|
|
202
|
-
let bestF1 = 0;
|
|
203
|
-
let bestPrecision = 0;
|
|
204
|
-
let bestRecall = 0;
|
|
205
|
-
|
|
206
|
-
const totalPositives = testEdges.length;
|
|
207
|
-
|
|
208
|
-
for (const scoreItem of allScores) {
|
|
209
|
-
if (scoreItem.isActualEdge) {
|
|
210
|
-
truePositives++;
|
|
211
|
-
} else {
|
|
212
|
-
falsePositives++;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
const precision = truePositives / (truePositives + falsePositives);
|
|
216
|
-
const recall = truePositives / totalPositives;
|
|
217
|
-
const f1 = precision + recall > 0 ? (2 * (precision * recall)) / (precision + recall) : 0;
|
|
218
|
-
|
|
219
|
-
if (f1 > bestF1) {
|
|
220
|
-
bestF1 = f1;
|
|
221
|
-
bestPrecision = precision;
|
|
222
|
-
bestRecall = recall;
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
// Calculate AUC (Area Under Curve)
|
|
227
|
-
let auc = 0;
|
|
228
|
-
let tpCount = 0;
|
|
229
|
-
let fpCount = 0;
|
|
230
|
-
|
|
231
|
-
for (const item of allScores) {
|
|
232
|
-
if (item.isActualEdge) {
|
|
233
|
-
tpCount++;
|
|
234
|
-
} else {
|
|
235
|
-
auc += tpCount;
|
|
236
|
-
fpCount++;
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
if (tpCount > 0 && fpCount > 0) {
|
|
241
|
-
auc = auc / (tpCount * fpCount);
|
|
242
|
-
} else {
|
|
243
|
-
auc = 0.5; // Random performance
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
return {
|
|
247
|
-
precision: bestPrecision,
|
|
248
|
-
recall: bestRecall,
|
|
249
|
-
f1Score: bestF1,
|
|
250
|
-
auc,
|
|
251
|
-
};
|
|
144
|
+
const s = toTopologySnapshot(trainingGraph);
|
|
145
|
+
const metrics = indexedEvaluateCommonNeighbors(s, toNodePairs(s, testEdges), toNodePairs(s, nonEdges), {
|
|
146
|
+
directed: options.directed,
|
|
147
|
+
});
|
|
148
|
+
return { ...metrics };
|
|
252
149
|
}
|
|
@@ -28,6 +28,12 @@ interface BFSResult<TNodeId> {
|
|
|
28
28
|
*
|
|
29
29
|
* Based on: Beamer, S., Asanović, K., & Patterson, D. (2012).
|
|
30
30
|
* "Direction-optimizing breadth-first search." SC'12.
|
|
31
|
+
*
|
|
32
|
+
* The snapshot replacement is `indexed.directionOptimizedBfs`, which gives the same distances,
|
|
33
|
+
* and the same parents when the snapshot numbers nodes in this class's CSR order. This class
|
|
34
|
+
* keeps its own code rather than delegating: it runs on a `CSRGraph`, not a `Graph`;
|
|
35
|
+
* `searchMultiple` has no single-call equivalent; and a second `search` without `reset` keeps
|
|
36
|
+
* the previous search's nodes, where the replacement starts every call afresh.
|
|
31
37
|
*/
|
|
32
38
|
export class DirectionOptimizedBFS<TNodeId = NodeId> {
|
|
33
39
|
private graph: CSRGraph<TNodeId>;
|
|
@@ -292,4 +298,3 @@ export function directionOptimizedBFS<TNodeId = NodeId>(
|
|
|
292
298
|
const bfs = new DirectionOptimizedBFS(graph, options);
|
|
293
299
|
return bfs.search(source);
|
|
294
300
|
}
|
|
295
|
-
|