@graphty/algorithms 1.1.0 → 1.3.1
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 +820 -235
- package/dist/algorithms.d.ts +42 -2
- package/dist/algorithms.js +11099 -2
- package/dist/algorithms.js.map +1 -1
- package/dist/src/algorithms/centrality/betweenness.d.ts +4 -0
- package/dist/src/algorithms/centrality/betweenness.d.ts.map +1 -1
- package/dist/src/algorithms/centrality/betweenness.js +124 -170
- package/dist/src/algorithms/centrality/betweenness.js.map +1 -1
- package/dist/src/algorithms/centrality/closeness.d.ts +26 -1
- package/dist/src/algorithms/centrality/closeness.d.ts.map +1 -1
- package/dist/src/algorithms/centrality/closeness.js +56 -149
- package/dist/src/algorithms/centrality/closeness.js.map +1 -1
- package/dist/src/algorithms/centrality/degree.js +3 -3
- package/dist/src/algorithms/centrality/degree.js.map +1 -1
- package/dist/src/algorithms/centrality/delta-pagerank-simple.d.ts +39 -0
- package/dist/src/algorithms/centrality/delta-pagerank-simple.d.ts.map +1 -0
- package/dist/src/algorithms/centrality/delta-pagerank-simple.js +286 -0
- package/dist/src/algorithms/centrality/delta-pagerank-simple.js.map +1 -0
- package/dist/src/algorithms/centrality/delta-pagerank.d.ts +80 -0
- package/dist/src/algorithms/centrality/delta-pagerank.d.ts.map +1 -0
- package/dist/src/algorithms/centrality/delta-pagerank.js +294 -0
- package/dist/src/algorithms/centrality/delta-pagerank.js.map +1 -0
- package/dist/src/algorithms/centrality/index.d.ts +2 -0
- package/dist/src/algorithms/centrality/index.d.ts.map +1 -1
- package/dist/src/algorithms/centrality/index.js +1 -0
- package/dist/src/algorithms/centrality/index.js.map +1 -1
- package/dist/src/algorithms/centrality/pagerank.d.ts +17 -0
- package/dist/src/algorithms/centrality/pagerank.d.ts.map +1 -1
- package/dist/src/algorithms/centrality/pagerank.js +45 -0
- package/dist/src/algorithms/centrality/pagerank.js.map +1 -1
- package/dist/src/algorithms/community/girvan-newman.d.ts.map +1 -1
- package/dist/src/algorithms/community/girvan-newman.js +47 -54
- package/dist/src/algorithms/community/girvan-newman.js.map +1 -1
- package/dist/src/algorithms/community/index.d.ts +2 -0
- package/dist/src/algorithms/community/index.d.ts.map +1 -1
- package/dist/src/algorithms/community/index.js.map +1 -1
- package/dist/src/algorithms/community/label-propagation.d.ts +13 -3
- package/dist/src/algorithms/community/label-propagation.d.ts.map +1 -1
- package/dist/src/algorithms/community/label-propagation.js +50 -35
- package/dist/src/algorithms/community/label-propagation.js.map +1 -1
- package/dist/src/algorithms/community/leiden.d.ts +3 -2
- package/dist/src/algorithms/community/leiden.d.ts.map +1 -1
- package/dist/src/algorithms/community/leiden.js +34 -39
- package/dist/src/algorithms/community/leiden.js.map +1 -1
- package/dist/src/algorithms/community/louvain-optimized.d.ts +112 -0
- package/dist/src/algorithms/community/louvain-optimized.d.ts.map +1 -0
- package/dist/src/algorithms/community/louvain-optimized.js +303 -0
- package/dist/src/algorithms/community/louvain-optimized.js.map +1 -0
- package/dist/src/algorithms/community/louvain.d.ts.map +1 -1
- package/dist/src/algorithms/community/louvain.js +17 -76
- package/dist/src/algorithms/community/louvain.js.map +1 -1
- package/dist/src/algorithms/community/modularity-utils.d.ts +59 -0
- package/dist/src/algorithms/community/modularity-utils.d.ts.map +1 -0
- package/dist/src/algorithms/community/modularity-utils.js +112 -0
- package/dist/src/algorithms/community/modularity-utils.js.map +1 -0
- package/dist/src/algorithms/matching/bipartite.d.ts.map +1 -1
- package/dist/src/algorithms/matching/bipartite.js +8 -40
- package/dist/src/algorithms/matching/bipartite.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 +1 -12
- package/dist/src/algorithms/shortest-path/bellman-ford.js.map +1 -1
- package/dist/src/algorithms/shortest-path/bidirectional-dijkstra.d.ts +37 -0
- package/dist/src/algorithms/shortest-path/bidirectional-dijkstra.d.ts.map +1 -0
- package/dist/src/algorithms/shortest-path/bidirectional-dijkstra.js +193 -0
- package/dist/src/algorithms/shortest-path/bidirectional-dijkstra.js.map +1 -0
- package/dist/src/algorithms/shortest-path/dijkstra.d.ts +5 -2
- package/dist/src/algorithms/shortest-path/dijkstra.d.ts.map +1 -1
- package/dist/src/algorithms/shortest-path/dijkstra.js +15 -14
- package/dist/src/algorithms/shortest-path/dijkstra.js.map +1 -1
- package/dist/src/algorithms/traversal/bfs-unified.d.ts +29 -0
- package/dist/src/algorithms/traversal/bfs-unified.d.ts.map +1 -0
- package/dist/src/algorithms/traversal/bfs-unified.js +333 -0
- package/dist/src/algorithms/traversal/bfs-unified.js.map +1 -0
- package/dist/src/algorithms/traversal/bfs-variants.d.ts +54 -0
- package/dist/src/algorithms/traversal/bfs-variants.d.ts.map +1 -0
- package/dist/src/algorithms/traversal/bfs-variants.js +368 -0
- package/dist/src/algorithms/traversal/bfs-variants.js.map +1 -0
- package/dist/src/algorithms/traversal/bfs.d.ts +4 -18
- package/dist/src/algorithms/traversal/bfs.d.ts.map +1 -1
- package/dist/src/algorithms/traversal/bfs.js +5 -182
- package/dist/src/algorithms/traversal/bfs.js.map +1 -1
- package/dist/src/benchmark-all-algorithms.d.ts +23 -0
- package/dist/src/benchmark-all-algorithms.d.ts.map +1 -0
- package/dist/src/benchmark-all-algorithms.js +462 -0
- package/dist/src/benchmark-all-algorithms.js.map +1 -0
- package/dist/src/clustering/hierarchical.d.ts +16 -15
- package/dist/src/clustering/hierarchical.d.ts.map +1 -1
- package/dist/src/clustering/hierarchical.js +209 -223
- package/dist/src/clustering/hierarchical.js.map +1 -1
- package/dist/src/clustering/index.d.ts +4 -2
- package/dist/src/clustering/index.d.ts.map +1 -1
- package/dist/src/clustering/index.js +2 -2
- package/dist/src/clustering/index.js.map +1 -1
- package/dist/src/clustering/k-core.d.ts +16 -15
- package/dist/src/clustering/k-core.d.ts.map +1 -1
- package/dist/src/clustering/k-core.js +57 -21
- package/dist/src/clustering/k-core.js.map +1 -1
- package/dist/src/clustering/spectral.d.ts +8 -0
- package/dist/src/clustering/spectral.d.ts.map +1 -1
- package/dist/src/clustering/spectral.js +158 -35
- package/dist/src/clustering/spectral.js.map +1 -1
- package/dist/src/core/graph.js +4 -4
- package/dist/src/core/graph.js.map +1 -1
- package/dist/src/flow/ford-fulkerson.d.ts +17 -11
- package/dist/src/flow/ford-fulkerson.d.ts.map +1 -1
- package/dist/src/flow/ford-fulkerson.js +141 -217
- package/dist/src/flow/ford-fulkerson.js.map +1 -1
- package/dist/src/flow/min-cut.d.ts +6 -5
- package/dist/src/flow/min-cut.d.ts.map +1 -1
- package/dist/src/flow/min-cut.js +17 -8
- package/dist/src/flow/min-cut.js.map +1 -1
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +6 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/link-prediction/adamic-adar.d.ts.map +1 -1
- package/dist/src/link-prediction/adamic-adar.js +17 -26
- package/dist/src/link-prediction/adamic-adar.js.map +1 -1
- package/dist/src/link-prediction/common-neighbors.d.ts.map +1 -1
- package/dist/src/link-prediction/common-neighbors.js +7 -11
- package/dist/src/link-prediction/common-neighbors.js.map +1 -1
- package/dist/src/optimized/bit-packed.d.ts +143 -0
- package/dist/src/optimized/bit-packed.d.ts.map +1 -0
- package/dist/src/optimized/bit-packed.js +292 -0
- package/dist/src/optimized/bit-packed.js.map +1 -0
- package/dist/src/optimized/csr-graph.d.ts +86 -0
- package/dist/src/optimized/csr-graph.d.ts.map +1 -0
- package/dist/src/optimized/csr-graph.js +341 -0
- package/dist/src/optimized/csr-graph.js.map +1 -0
- package/dist/src/optimized/direction-optimized-bfs.d.ts +74 -0
- package/dist/src/optimized/direction-optimized-bfs.d.ts.map +1 -0
- package/dist/src/optimized/direction-optimized-bfs.js +223 -0
- package/dist/src/optimized/direction-optimized-bfs.js.map +1 -0
- package/dist/src/optimized/graph-adapter.d.ts +62 -0
- package/dist/src/optimized/graph-adapter.d.ts.map +1 -0
- package/dist/src/optimized/graph-adapter.js +146 -0
- package/dist/src/optimized/graph-adapter.js.map +1 -0
- package/dist/src/optimized/index.d.ts +14 -0
- package/dist/src/optimized/index.d.ts.map +1 -0
- package/dist/src/optimized/index.js +28 -0
- package/dist/src/optimized/index.js.map +1 -0
- package/dist/src/research/grsbm.d.ts +83 -0
- package/dist/src/research/grsbm.d.ts.map +1 -0
- package/dist/src/research/grsbm.js +403 -0
- package/dist/src/research/grsbm.js.map +1 -0
- package/dist/src/research/index.d.ts +12 -0
- package/dist/src/research/index.d.ts.map +1 -0
- package/dist/src/research/index.js +14 -0
- package/dist/src/research/index.js.map +1 -0
- package/dist/src/research/sync.d.ts +49 -0
- package/dist/src/research/sync.d.ts.map +1 -0
- package/dist/src/research/sync.js +316 -0
- package/dist/src/research/sync.js.map +1 -0
- package/dist/src/research/terahac.d.ts +65 -0
- package/dist/src/research/terahac.d.ts.map +1 -0
- package/dist/src/research/terahac.js +379 -0
- package/dist/src/research/terahac.js.map +1 -0
- package/dist/src/types/index.d.ts +8 -0
- package/dist/src/types/index.d.ts.map +1 -1
- package/dist/src/utils/algorithm-utilities.d.ts +2 -0
- package/dist/src/utils/algorithm-utilities.d.ts.map +1 -0
- package/dist/src/utils/algorithm-utilities.js +2 -0
- package/dist/src/utils/algorithm-utilities.js.map +1 -0
- package/dist/src/utils/graph-converters.d.ts +79 -0
- package/dist/src/utils/graph-converters.d.ts.map +1 -0
- package/dist/src/utils/graph-converters.js +196 -0
- package/dist/src/utils/graph-converters.js.map +1 -0
- package/dist/src/utils/graph-utilities.d.ts +62 -0
- package/dist/src/utils/graph-utilities.d.ts.map +1 -0
- package/dist/src/utils/graph-utilities.js +148 -0
- package/dist/src/utils/graph-utilities.js.map +1 -0
- package/dist/src/utils/index.d.ts +5 -0
- package/dist/src/utils/index.d.ts.map +1 -0
- package/dist/src/utils/index.js +5 -0
- package/dist/src/utils/index.js.map +1 -0
- package/dist/src/utils/math-utilities.d.ts +52 -0
- package/dist/src/utils/math-utilities.d.ts.map +1 -0
- package/dist/src/utils/math-utilities.js +123 -0
- package/dist/src/utils/math-utilities.js.map +1 -0
- package/dist/src/utils/matrix-utilities.d.ts +2 -0
- package/dist/src/utils/matrix-utilities.d.ts.map +1 -0
- package/dist/src/utils/matrix-utilities.js +2 -0
- package/dist/src/utils/matrix-utilities.js.map +1 -0
- package/dist/src/utils/optimization-helpers.d.ts +33 -0
- package/dist/src/utils/optimization-helpers.d.ts.map +1 -0
- package/dist/src/utils/optimization-helpers.js +47 -0
- package/dist/src/utils/optimization-helpers.js.map +1 -0
- package/package.json +28 -4
- package/src/algorithms/centrality/betweenness.ts +167 -199
- package/src/algorithms/centrality/closeness.ts +73 -191
- package/src/algorithms/centrality/degree.ts +3 -3
- package/src/algorithms/centrality/delta-pagerank-simple.ts +366 -0
- package/src/algorithms/centrality/delta-pagerank.ts +435 -0
- package/src/algorithms/centrality/index.ts +2 -0
- package/src/algorithms/centrality/pagerank.ts +66 -0
- package/src/algorithms/community/girvan-newman.ts +52 -59
- package/src/algorithms/community/index.ts +2 -0
- package/src/algorithms/community/label-propagation.ts +64 -35
- package/src/algorithms/community/leiden.ts +40 -41
- package/src/algorithms/community/louvain-optimized.ts +445 -0
- package/src/algorithms/community/louvain.ts +24 -104
- package/src/algorithms/community/modularity-utils.ts +146 -0
- package/src/algorithms/matching/bipartite.ts +8 -44
- package/src/algorithms/shortest-path/bellman-ford.ts +1 -14
- package/src/algorithms/shortest-path/bidirectional-dijkstra.ts +248 -0
- package/src/algorithms/shortest-path/dijkstra.ts +17 -15
- package/src/algorithms/traversal/bfs-unified.ts +433 -0
- package/src/algorithms/traversal/bfs-variants.ts +496 -0
- package/src/algorithms/traversal/bfs.ts +10 -228
- package/src/benchmark-all-algorithms.ts +548 -0
- package/src/clustering/hierarchical.ts +241 -251
- package/src/clustering/index.ts +4 -2
- package/src/clustering/k-core.ts +87 -39
- package/src/clustering/spectral.ts +185 -34
- package/src/core/graph.ts +4 -4
- package/src/flow/ford-fulkerson.ts +186 -254
- package/src/flow/min-cut.ts +21 -11
- package/src/index.ts +9 -0
- package/src/link-prediction/adamic-adar.ts +17 -30
- package/src/link-prediction/common-neighbors.ts +7 -16
- package/src/optimized/bit-packed.ts +340 -0
- package/src/optimized/csr-graph.ts +455 -0
- package/src/optimized/direction-optimized-bfs.ts +291 -0
- package/src/optimized/graph-adapter.ts +200 -0
- package/src/optimized/index.ts +36 -0
- package/src/research/grsbm.ts +580 -0
- package/src/research/index.ts +17 -0
- package/src/research/sync.ts +440 -0
- package/src/research/terahac.ts +514 -0
- package/src/types/index.ts +8 -0
- package/src/utils/algorithm-utilities.ts +2 -0
- package/src/utils/graph-converters.ts +241 -0
- package/src/utils/graph-utilities.ts +199 -0
- package/src/utils/index.ts +4 -0
- package/src/utils/math-utilities.ts +140 -0
- package/src/utils/matrix-utilities.ts +2 -0
- package/src/utils/optimization-helpers.ts +81 -0
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compressed Sparse Row (CSR) graph representation
|
|
3
|
+
*
|
|
4
|
+
* Provides cache-efficient graph storage with sequential memory access patterns.
|
|
5
|
+
* Optimized for traversal operations and sparse graphs.
|
|
6
|
+
*/
|
|
7
|
+
export class CSRGraph {
|
|
8
|
+
constructor(adjacencyList, weights, buildReverse = true) {
|
|
9
|
+
this.data = this.buildCSR(adjacencyList, weights, buildReverse);
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Build CSR structure from adjacency list
|
|
13
|
+
*/
|
|
14
|
+
buildCSR(adjacencyList, weights, buildReverse = true) {
|
|
15
|
+
// Collect all unique nodes (both sources and targets)
|
|
16
|
+
const allNodes = new Set();
|
|
17
|
+
for (const [source, neighbors] of adjacencyList) {
|
|
18
|
+
allNodes.add(source);
|
|
19
|
+
for (const neighbor of neighbors) {
|
|
20
|
+
allNodes.add(neighbor);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
// Sort nodes for consistent ordering. Numeric IDs sort numerically,
|
|
24
|
+
// string IDs sort lexicographically for predictable iteration order.
|
|
25
|
+
const nodes = Array.from(allNodes).sort((a, b) => {
|
|
26
|
+
if (typeof a === "number" && typeof b === "number") {
|
|
27
|
+
return a - b;
|
|
28
|
+
}
|
|
29
|
+
return String(a).localeCompare(String(b));
|
|
30
|
+
});
|
|
31
|
+
const nodeCount = nodes.length;
|
|
32
|
+
// Build node mappings
|
|
33
|
+
const nodeIdToIndex = new Map();
|
|
34
|
+
const indexToNodeId = [];
|
|
35
|
+
nodes.forEach((nodeId, index) => {
|
|
36
|
+
nodeIdToIndex.set(nodeId, index);
|
|
37
|
+
indexToNodeId[index] = nodeId;
|
|
38
|
+
});
|
|
39
|
+
// Count total edges
|
|
40
|
+
let edgeCount = 0;
|
|
41
|
+
for (const neighbors of adjacencyList.values()) {
|
|
42
|
+
edgeCount += neighbors.length;
|
|
43
|
+
}
|
|
44
|
+
// Allocate arrays
|
|
45
|
+
const rowPointers = new Uint32Array(nodeCount + 1);
|
|
46
|
+
const columnIndices = new Uint32Array(edgeCount);
|
|
47
|
+
const edgeWeights = weights ? new Float32Array(edgeCount) : undefined;
|
|
48
|
+
// Build CSR structure
|
|
49
|
+
let currentEdge = 0;
|
|
50
|
+
for (let i = 0; i < nodeCount; i++) {
|
|
51
|
+
rowPointers[i] = currentEdge;
|
|
52
|
+
const nodeId = indexToNodeId[i];
|
|
53
|
+
if (nodeId === undefined) {
|
|
54
|
+
throw new Error(`Invalid node index ${String(i)}`);
|
|
55
|
+
}
|
|
56
|
+
const neighbors = adjacencyList.get(nodeId) ?? [];
|
|
57
|
+
// Sort neighbors for better cache locality and binary search
|
|
58
|
+
const sortedNeighbors = neighbors
|
|
59
|
+
.map((n) => {
|
|
60
|
+
const index = nodeIdToIndex.get(n);
|
|
61
|
+
if (index === undefined) {
|
|
62
|
+
throw new Error(`Node ${String(n)} not found in nodeIdToIndex map`);
|
|
63
|
+
}
|
|
64
|
+
return { id: n, index };
|
|
65
|
+
})
|
|
66
|
+
.sort((a, b) => a.index - b.index);
|
|
67
|
+
for (const neighbor of sortedNeighbors) {
|
|
68
|
+
columnIndices[currentEdge] = neighbor.index;
|
|
69
|
+
if (edgeWeights && weights) {
|
|
70
|
+
const edgeKey = `${String(nodeId)}-${String(neighbor.id)}`;
|
|
71
|
+
const weight = weights.get(edgeKey);
|
|
72
|
+
if (weight !== undefined) {
|
|
73
|
+
edgeWeights[currentEdge] = weight;
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
edgeWeights[currentEdge] = 1;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
currentEdge++;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
rowPointers[nodeCount] = currentEdge;
|
|
83
|
+
const result = {
|
|
84
|
+
rowPointers,
|
|
85
|
+
columnIndices,
|
|
86
|
+
nodeIdToIndex,
|
|
87
|
+
indexToNodeId,
|
|
88
|
+
};
|
|
89
|
+
if (edgeWeights) {
|
|
90
|
+
result.edgeWeights = edgeWeights;
|
|
91
|
+
}
|
|
92
|
+
// Build reverse edges for bottom-up BFS
|
|
93
|
+
if (buildReverse) {
|
|
94
|
+
const reverseAdjacency = new Map();
|
|
95
|
+
for (let i = 0; i < nodeCount; i++) {
|
|
96
|
+
reverseAdjacency.set(i, []);
|
|
97
|
+
}
|
|
98
|
+
// Build reverse adjacency from forward edges
|
|
99
|
+
for (let i = 0; i < nodeCount; i++) {
|
|
100
|
+
const start = rowPointers[i];
|
|
101
|
+
const end = rowPointers[i + 1];
|
|
102
|
+
if (start !== undefined && end !== undefined) {
|
|
103
|
+
for (let j = start; j < end; j++) {
|
|
104
|
+
const target = columnIndices[j];
|
|
105
|
+
if (target !== undefined) {
|
|
106
|
+
reverseAdjacency.get(target)?.push(i);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
// Build reverse CSR
|
|
112
|
+
const reverseRowPointers = new Uint32Array(nodeCount + 1);
|
|
113
|
+
const reverseColumnIndices = new Uint32Array(edgeCount);
|
|
114
|
+
let reverseEdge = 0;
|
|
115
|
+
for (let i = 0; i < nodeCount; i++) {
|
|
116
|
+
reverseRowPointers[i] = reverseEdge;
|
|
117
|
+
const incoming = reverseAdjacency.get(i) ?? [];
|
|
118
|
+
incoming.sort((a, b) => a - b);
|
|
119
|
+
for (const source of incoming) {
|
|
120
|
+
reverseColumnIndices[reverseEdge++] = source;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
reverseRowPointers[nodeCount] = reverseEdge;
|
|
124
|
+
result.reverseRowPointers = reverseRowPointers;
|
|
125
|
+
result.reverseColumnIndices = reverseColumnIndices;
|
|
126
|
+
}
|
|
127
|
+
return result;
|
|
128
|
+
}
|
|
129
|
+
// Core API methods
|
|
130
|
+
nodeCount() {
|
|
131
|
+
return this.data.indexToNodeId.length;
|
|
132
|
+
}
|
|
133
|
+
edgeCount() {
|
|
134
|
+
return this.data.columnIndices.length;
|
|
135
|
+
}
|
|
136
|
+
hasNode(nodeId) {
|
|
137
|
+
return this.data.nodeIdToIndex.has(nodeId);
|
|
138
|
+
}
|
|
139
|
+
hasEdge(source, target) {
|
|
140
|
+
const sourceIndex = this.data.nodeIdToIndex.get(source);
|
|
141
|
+
const targetIndex = this.data.nodeIdToIndex.get(target);
|
|
142
|
+
if (sourceIndex === undefined || targetIndex === undefined) {
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
const start = this.data.rowPointers[sourceIndex];
|
|
146
|
+
const end = this.data.rowPointers[sourceIndex + 1];
|
|
147
|
+
// Binary search for target in sorted neighbors
|
|
148
|
+
if (start === undefined || end === undefined) {
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
151
|
+
return this.binarySearch(this.data.columnIndices, targetIndex, start, end) !== -1;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Get neighbors as node IDs
|
|
155
|
+
*/
|
|
156
|
+
neighbors(nodeId) {
|
|
157
|
+
const nodeIndex = this.data.nodeIdToIndex.get(nodeId);
|
|
158
|
+
if (nodeIndex === undefined) {
|
|
159
|
+
return new Set().values();
|
|
160
|
+
}
|
|
161
|
+
const start = this.data.rowPointers[nodeIndex];
|
|
162
|
+
const end = this.data.rowPointers[nodeIndex + 1];
|
|
163
|
+
const { columnIndices, indexToNodeId } = this.data;
|
|
164
|
+
function* generateNeighbors() {
|
|
165
|
+
if (start !== undefined && end !== undefined) {
|
|
166
|
+
for (let i = start; i < end; i++) {
|
|
167
|
+
const idx = columnIndices[i];
|
|
168
|
+
if (idx !== undefined) {
|
|
169
|
+
const nodeId = indexToNodeId[idx];
|
|
170
|
+
if (nodeId !== undefined) {
|
|
171
|
+
yield nodeId;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return generateNeighbors();
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Get all nodes
|
|
181
|
+
*/
|
|
182
|
+
nodes() {
|
|
183
|
+
return this.data.indexToNodeId.values();
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Get neighbors as indices (internal use)
|
|
187
|
+
*/
|
|
188
|
+
getNeighborIndices(nodeIndex) {
|
|
189
|
+
if (nodeIndex < 0 || nodeIndex >= this.data.indexToNodeId.length) {
|
|
190
|
+
return [];
|
|
191
|
+
}
|
|
192
|
+
const start = this.data.rowPointers[nodeIndex];
|
|
193
|
+
const end = this.data.rowPointers[nodeIndex + 1];
|
|
194
|
+
if (start === undefined || end === undefined) {
|
|
195
|
+
return [];
|
|
196
|
+
}
|
|
197
|
+
return Array.from(this.data.columnIndices.subarray(start, end));
|
|
198
|
+
}
|
|
199
|
+
outDegree(nodeId) {
|
|
200
|
+
const nodeIndex = this.data.nodeIdToIndex.get(nodeId);
|
|
201
|
+
if (nodeIndex === undefined) {
|
|
202
|
+
return 0;
|
|
203
|
+
}
|
|
204
|
+
return this.outDegreeByIndex(nodeIndex);
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Get out-degree by index (internal use)
|
|
208
|
+
*/
|
|
209
|
+
outDegreeByIndex(nodeIndex) {
|
|
210
|
+
const start = this.data.rowPointers[nodeIndex];
|
|
211
|
+
const end = this.data.rowPointers[nodeIndex + 1];
|
|
212
|
+
if (start !== undefined && end !== undefined) {
|
|
213
|
+
return end - start;
|
|
214
|
+
}
|
|
215
|
+
return 0;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Iterator support for neighbor indices
|
|
219
|
+
*/
|
|
220
|
+
*iterateNeighborIndices(nodeIndex) {
|
|
221
|
+
const start = this.data.rowPointers[nodeIndex];
|
|
222
|
+
const end = this.data.rowPointers[nodeIndex + 1];
|
|
223
|
+
if (start !== undefined && end !== undefined) {
|
|
224
|
+
for (let i = start; i < end; i++) {
|
|
225
|
+
const value = this.data.columnIndices[i];
|
|
226
|
+
if (value !== undefined) {
|
|
227
|
+
yield value;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Iterator support for incoming neighbor indices (for bottom-up BFS)
|
|
234
|
+
*/
|
|
235
|
+
*iterateIncomingNeighborIndices(nodeIndex) {
|
|
236
|
+
if (!this.data.reverseRowPointers || !this.data.reverseColumnIndices) {
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
const start = this.data.reverseRowPointers[nodeIndex];
|
|
240
|
+
const end = this.data.reverseRowPointers[nodeIndex + 1];
|
|
241
|
+
if (start !== undefined && end !== undefined) {
|
|
242
|
+
for (let i = start; i < end; i++) {
|
|
243
|
+
const value = this.data.reverseColumnIndices[i];
|
|
244
|
+
if (value !== undefined) {
|
|
245
|
+
yield value;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Convert node ID to index
|
|
252
|
+
*/
|
|
253
|
+
nodeToIndex(nodeId) {
|
|
254
|
+
const index = this.data.nodeIdToIndex.get(nodeId);
|
|
255
|
+
if (index === undefined) {
|
|
256
|
+
throw new Error(`Node ${String(nodeId)} not found in graph`);
|
|
257
|
+
}
|
|
258
|
+
return index;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Convert index to node ID
|
|
262
|
+
*/
|
|
263
|
+
indexToNodeId(index) {
|
|
264
|
+
const nodeId = this.data.indexToNodeId[index];
|
|
265
|
+
if (nodeId === undefined) {
|
|
266
|
+
throw new Error(`Index ${String(index)} out of bounds`);
|
|
267
|
+
}
|
|
268
|
+
return nodeId;
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Get edge weight
|
|
272
|
+
*/
|
|
273
|
+
getEdgeWeight(source, target) {
|
|
274
|
+
if (!this.data.edgeWeights) {
|
|
275
|
+
return undefined;
|
|
276
|
+
}
|
|
277
|
+
const sourceIndex = this.data.nodeIdToIndex.get(source);
|
|
278
|
+
const targetIndex = this.data.nodeIdToIndex.get(target);
|
|
279
|
+
if (sourceIndex === undefined || targetIndex === undefined) {
|
|
280
|
+
return undefined;
|
|
281
|
+
}
|
|
282
|
+
const start = this.data.rowPointers[sourceIndex];
|
|
283
|
+
const end = this.data.rowPointers[sourceIndex + 1];
|
|
284
|
+
if (start === undefined || end === undefined) {
|
|
285
|
+
return undefined;
|
|
286
|
+
}
|
|
287
|
+
const edgeIndex = this.binarySearch(this.data.columnIndices, targetIndex, start, end);
|
|
288
|
+
if (edgeIndex === -1) {
|
|
289
|
+
return undefined;
|
|
290
|
+
}
|
|
291
|
+
return this.data.edgeWeights[edgeIndex];
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Binary search for target in sorted array
|
|
295
|
+
*/
|
|
296
|
+
binarySearch(arr, target, start, end) {
|
|
297
|
+
let left = start;
|
|
298
|
+
let right = end - 1;
|
|
299
|
+
while (left <= right) {
|
|
300
|
+
const mid = (left + right) >>> 1;
|
|
301
|
+
const value = arr[mid];
|
|
302
|
+
if (value === undefined) {
|
|
303
|
+
return -1;
|
|
304
|
+
}
|
|
305
|
+
if (value === target) {
|
|
306
|
+
return mid;
|
|
307
|
+
}
|
|
308
|
+
if (value < target) {
|
|
309
|
+
left = mid + 1;
|
|
310
|
+
}
|
|
311
|
+
else {
|
|
312
|
+
right = mid - 1;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
return -1;
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Create CSR graph from standard Graph
|
|
319
|
+
*/
|
|
320
|
+
static fromGraph(graph) {
|
|
321
|
+
const adjacencyList = new Map();
|
|
322
|
+
const weights = new Map();
|
|
323
|
+
// Build adjacency list
|
|
324
|
+
for (const node of graph.nodes()) {
|
|
325
|
+
const neighbors = [];
|
|
326
|
+
for (const neighbor of graph.neighbors(node.id)) {
|
|
327
|
+
neighbors.push(neighbor);
|
|
328
|
+
// Get edge weight if available
|
|
329
|
+
if (graph.getEdge) {
|
|
330
|
+
const edge = graph.getEdge(node.id, neighbor);
|
|
331
|
+
if (edge?.weight !== undefined) {
|
|
332
|
+
weights.set(`${String(node.id)}-${String(neighbor)}`, edge.weight);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
adjacencyList.set(node.id, neighbors);
|
|
337
|
+
}
|
|
338
|
+
return new CSRGraph(adjacencyList, weights.size > 0 ? weights : undefined);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
//# sourceMappingURL=csr-graph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"csr-graph.js","sourceRoot":"","sources":["../../../src/optimized/csr-graph.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { NodeId } from "../types/index.js";
|
|
2
|
+
import { CSRGraph } from "./csr-graph.js";
|
|
3
|
+
/**
|
|
4
|
+
* Options for Direction-Optimized BFS
|
|
5
|
+
*/
|
|
6
|
+
export interface DirectionOptimizedBFSOptions {
|
|
7
|
+
alpha?: number;
|
|
8
|
+
beta?: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Result of BFS traversal
|
|
12
|
+
*/
|
|
13
|
+
export interface BFSResult<TNodeId> {
|
|
14
|
+
distances: Map<TNodeId, number>;
|
|
15
|
+
parents: Map<TNodeId, TNodeId | null>;
|
|
16
|
+
visitedCount: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Direction-Optimized Breadth-First Search
|
|
20
|
+
*
|
|
21
|
+
* Dynamically switches between top-down and bottom-up search strategies
|
|
22
|
+
* based on the size of the frontier. Particularly effective for low-diameter
|
|
23
|
+
* graphs like social networks.
|
|
24
|
+
*
|
|
25
|
+
* Based on: Beamer, S., Asanović, K., & Patterson, D. (2012).
|
|
26
|
+
* "Direction-optimizing breadth-first search." SC'12.
|
|
27
|
+
*/
|
|
28
|
+
export declare class DirectionOptimizedBFS<TNodeId = NodeId> {
|
|
29
|
+
private graph;
|
|
30
|
+
private alpha;
|
|
31
|
+
private beta;
|
|
32
|
+
private parent;
|
|
33
|
+
private frontier;
|
|
34
|
+
private nextFrontier;
|
|
35
|
+
private distances;
|
|
36
|
+
constructor(graph: CSRGraph<TNodeId>, options?: DirectionOptimizedBFSOptions);
|
|
37
|
+
/**
|
|
38
|
+
* Perform BFS from a single source
|
|
39
|
+
*/
|
|
40
|
+
search(source: TNodeId): BFSResult<TNodeId>;
|
|
41
|
+
/**
|
|
42
|
+
* Top-down BFS step - explore from frontier
|
|
43
|
+
*/
|
|
44
|
+
private topDownStep;
|
|
45
|
+
/**
|
|
46
|
+
* Bottom-up BFS step - check unvisited nodes
|
|
47
|
+
*/
|
|
48
|
+
private bottomUpStep;
|
|
49
|
+
/**
|
|
50
|
+
* Calculate edges to check for switching heuristic
|
|
51
|
+
*/
|
|
52
|
+
private calculateEdgesToCheck;
|
|
53
|
+
/**
|
|
54
|
+
* Build result map from internal data structures
|
|
55
|
+
*/
|
|
56
|
+
private buildResult;
|
|
57
|
+
/**
|
|
58
|
+
* Perform multi-source BFS
|
|
59
|
+
*/
|
|
60
|
+
searchMultiple(sources: TNodeId[]): BFSResult<TNodeId>;
|
|
61
|
+
/**
|
|
62
|
+
* Reset internal state for reuse
|
|
63
|
+
*/
|
|
64
|
+
reset(): void;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Convenience function for single-source BFS
|
|
68
|
+
*/
|
|
69
|
+
export declare function directionOptimizedBFS<TNodeId = NodeId>(graph: CSRGraph<TNodeId>, source: TNodeId, options?: DirectionOptimizedBFSOptions): BFSResult<TNodeId>;
|
|
70
|
+
/**
|
|
71
|
+
* Convenience function for multi-source BFS
|
|
72
|
+
*/
|
|
73
|
+
export declare function directionOptimizedBFSMultiple<TNodeId = NodeId>(graph: CSRGraph<TNodeId>, sources: TNodeId[], options?: DirectionOptimizedBFSOptions): BFSResult<TNodeId>;
|
|
74
|
+
//# sourceMappingURL=direction-optimized-bfs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"direction-optimized-bfs.d.ts","sourceRoot":"","sources":["../../../src/optimized/direction-optimized-bfs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,mBAAmB,CAAC;AAE9C,OAAO,EAAC,QAAQ,EAAC,MAAM,gBAAgB,CAAC;AAExC;;GAEG;AACH,MAAM,WAAW,4BAA4B;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,SAAS,CAAC,OAAO;IAC9B,SAAS,EAAE,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAChC,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC,CAAC;IACtC,YAAY,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;;GASG;AACH,qBAAa,qBAAqB,CAAC,OAAO,GAAG,MAAM;IAC/C,OAAO,CAAC,KAAK,CAAoB;IACjC,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,IAAI,CAAS;IAGrB,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,QAAQ,CAAc;IAC9B,OAAO,CAAC,YAAY,CAAc;IAClC,OAAO,CAAC,SAAS,CAAuB;gBAE5B,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,EAAE,4BAA4B;IAY5E;;KAEC;IACD,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC;IAkD3C;;KAEC;IACD,OAAO,CAAC,WAAW;IAoBnB;;KAEC;IACD,OAAO,CAAC,YAAY;IAwBpB;;KAEC;IACD,OAAO,CAAC,qBAAqB;IAQ7B;;KAEC;IACD,OAAO,CAAC,WAAW;IA4BnB;;KAEC;IACD,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,SAAS,CAAC,OAAO,CAAC;IAuDtD;;KAEC;IACD,KAAK,IAAI,IAAI;CAMhB;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,GAAG,MAAM,EAClD,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,EACxB,MAAM,EAAE,OAAO,EACf,OAAO,CAAC,EAAE,4BAA4B,GACvC,SAAS,CAAC,OAAO,CAAC,CAGpB;AAED;;GAEG;AACH,wBAAgB,6BAA6B,CAAC,OAAO,GAAG,MAAM,EAC1D,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,EACxB,OAAO,EAAE,OAAO,EAAE,EAClB,OAAO,CAAC,EAAE,4BAA4B,GACvC,SAAS,CAAC,OAAO,CAAC,CAGpB"}
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import { CompactDistanceArray, GraphBitSet } from "./bit-packed.js";
|
|
2
|
+
/**
|
|
3
|
+
* Direction-Optimized Breadth-First Search
|
|
4
|
+
*
|
|
5
|
+
* Dynamically switches between top-down and bottom-up search strategies
|
|
6
|
+
* based on the size of the frontier. Particularly effective for low-diameter
|
|
7
|
+
* graphs like social networks.
|
|
8
|
+
*
|
|
9
|
+
* Based on: Beamer, S., Asanović, K., & Patterson, D. (2012).
|
|
10
|
+
* "Direction-optimizing breadth-first search." SC'12.
|
|
11
|
+
*/
|
|
12
|
+
export class DirectionOptimizedBFS {
|
|
13
|
+
constructor(graph, options) {
|
|
14
|
+
this.graph = graph;
|
|
15
|
+
this.alpha = options?.alpha ?? 15;
|
|
16
|
+
this.beta = options?.beta ?? 18;
|
|
17
|
+
const nodeCount = graph.nodeCount();
|
|
18
|
+
this.parent = new Int32Array(nodeCount).fill(-1);
|
|
19
|
+
this.frontier = new GraphBitSet(nodeCount);
|
|
20
|
+
this.nextFrontier = new GraphBitSet(nodeCount);
|
|
21
|
+
this.distances = new CompactDistanceArray(nodeCount);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Perform BFS from a single source
|
|
25
|
+
*/
|
|
26
|
+
search(source) {
|
|
27
|
+
const sourceIndex = this.graph.nodeToIndex(source);
|
|
28
|
+
this.parent[sourceIndex] = -2; // Mark as source
|
|
29
|
+
this.frontier.add(sourceIndex);
|
|
30
|
+
this.distances.set(sourceIndex, 0);
|
|
31
|
+
// let currentDistance = 0; // Variable not used
|
|
32
|
+
// Initialize edgesToCheck to total edges to prevent immediate switch to bottom-up
|
|
33
|
+
let edgesToCheck = this.graph.edgeCount();
|
|
34
|
+
let scoutCount = 0; // Will be set after first top-down step
|
|
35
|
+
let awakeCount = 1; // Number of nodes in current frontier
|
|
36
|
+
let oldAwakeCount = 0;
|
|
37
|
+
// Direction tracking
|
|
38
|
+
let useBottomUp = false;
|
|
39
|
+
while (!this.frontier.isEmpty()) {
|
|
40
|
+
oldAwakeCount = awakeCount;
|
|
41
|
+
if (useBottomUp) {
|
|
42
|
+
// Check if we should switch back to top-down
|
|
43
|
+
if (awakeCount >= oldAwakeCount ||
|
|
44
|
+
awakeCount > this.graph.nodeCount() / this.beta) {
|
|
45
|
+
useBottomUp = false;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
// Check if we should switch to bottom-up
|
|
50
|
+
if (scoutCount > edgesToCheck / this.alpha) {
|
|
51
|
+
useBottomUp = true;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
if (useBottomUp) {
|
|
55
|
+
awakeCount = this.bottomUpStep();
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
scoutCount = this.topDownStep();
|
|
59
|
+
awakeCount = this.nextFrontier.size();
|
|
60
|
+
}
|
|
61
|
+
// Swap frontiers
|
|
62
|
+
this.frontier.swap(this.nextFrontier);
|
|
63
|
+
this.nextFrontier.clear();
|
|
64
|
+
// currentDistance++; // Variable not used
|
|
65
|
+
edgesToCheck = this.calculateEdgesToCheck();
|
|
66
|
+
}
|
|
67
|
+
return this.buildResult();
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Top-down BFS step - explore from frontier
|
|
71
|
+
*/
|
|
72
|
+
topDownStep() {
|
|
73
|
+
let scoutCount = 0;
|
|
74
|
+
// Iterate through frontier nodes
|
|
75
|
+
for (const node of this.frontier) {
|
|
76
|
+
const currentDistance = this.distances.get(node);
|
|
77
|
+
for (const neighbor of this.graph.iterateNeighborIndices(node)) {
|
|
78
|
+
if (this.parent[neighbor] === -1) {
|
|
79
|
+
this.parent[neighbor] = node;
|
|
80
|
+
this.distances.set(neighbor, currentDistance + 1);
|
|
81
|
+
this.nextFrontier.add(neighbor);
|
|
82
|
+
scoutCount += this.graph.outDegreeByIndex(neighbor);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return scoutCount;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Bottom-up BFS step - check unvisited nodes
|
|
90
|
+
*/
|
|
91
|
+
bottomUpStep() {
|
|
92
|
+
const nodeCount = this.graph.nodeCount();
|
|
93
|
+
let awakeCount = 0;
|
|
94
|
+
// Check all unvisited nodes
|
|
95
|
+
for (let node = 0; node < nodeCount; node++) {
|
|
96
|
+
if (this.parent[node] === -1) {
|
|
97
|
+
// Use incoming edges for bottom-up traversal
|
|
98
|
+
for (const neighbor of this.graph.iterateIncomingNeighborIndices(node)) {
|
|
99
|
+
if (this.frontier.has(neighbor)) {
|
|
100
|
+
this.parent[node] = neighbor;
|
|
101
|
+
const neighborDist = this.distances.get(neighbor);
|
|
102
|
+
this.distances.set(node, neighborDist + 1);
|
|
103
|
+
this.nextFrontier.add(node);
|
|
104
|
+
awakeCount++;
|
|
105
|
+
break; // Found a parent, no need to check more
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return awakeCount;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Calculate edges to check for switching heuristic
|
|
114
|
+
*/
|
|
115
|
+
calculateEdgesToCheck() {
|
|
116
|
+
let count = 0;
|
|
117
|
+
for (const node of this.frontier) {
|
|
118
|
+
count += this.graph.outDegreeByIndex(node);
|
|
119
|
+
}
|
|
120
|
+
return count;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Build result map from internal data structures
|
|
124
|
+
*/
|
|
125
|
+
buildResult() {
|
|
126
|
+
const distances = new Map();
|
|
127
|
+
const parents = new Map();
|
|
128
|
+
let visitedCount = 0;
|
|
129
|
+
for (let i = 0; i < this.graph.nodeCount(); i++) {
|
|
130
|
+
if (this.parent[i] !== -1) {
|
|
131
|
+
const nodeId = this.graph.indexToNodeId(i);
|
|
132
|
+
distances.set(nodeId, this.distances.get(i));
|
|
133
|
+
if (this.parent[i] === -2) {
|
|
134
|
+
// Source node
|
|
135
|
+
parents.set(nodeId, null);
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
// Regular node with parent
|
|
139
|
+
const parentIndex = this.parent[i];
|
|
140
|
+
if (parentIndex !== undefined && parentIndex >= 0) {
|
|
141
|
+
parents.set(nodeId, this.graph.indexToNodeId(parentIndex));
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
visitedCount++;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return { distances, parents, visitedCount };
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Perform multi-source BFS
|
|
151
|
+
*/
|
|
152
|
+
searchMultiple(sources) {
|
|
153
|
+
// Initialize multiple sources
|
|
154
|
+
for (const source of sources) {
|
|
155
|
+
const sourceIndex = this.graph.nodeToIndex(source);
|
|
156
|
+
this.parent[sourceIndex] = -2; // Mark as source
|
|
157
|
+
this.frontier.add(sourceIndex);
|
|
158
|
+
this.distances.set(sourceIndex, 0);
|
|
159
|
+
}
|
|
160
|
+
// let currentDistance = 0; // Variable not used
|
|
161
|
+
let edgesToCheck = 0;
|
|
162
|
+
let scoutCount = 0;
|
|
163
|
+
// Calculate initial edges to check
|
|
164
|
+
for (const node of this.frontier) {
|
|
165
|
+
const degree = this.graph.outDegreeByIndex(node);
|
|
166
|
+
edgesToCheck += degree;
|
|
167
|
+
scoutCount += degree;
|
|
168
|
+
}
|
|
169
|
+
let awakeCount = sources.length;
|
|
170
|
+
let oldAwakeCount = 0;
|
|
171
|
+
let useBottomUp = false;
|
|
172
|
+
while (!this.frontier.isEmpty()) {
|
|
173
|
+
oldAwakeCount = awakeCount;
|
|
174
|
+
if (useBottomUp) {
|
|
175
|
+
if (awakeCount >= oldAwakeCount ||
|
|
176
|
+
awakeCount > this.graph.nodeCount() / this.beta) {
|
|
177
|
+
useBottomUp = false;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
if (scoutCount > edgesToCheck / this.alpha) {
|
|
182
|
+
useBottomUp = true;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
if (useBottomUp) {
|
|
186
|
+
awakeCount = this.bottomUpStep();
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
scoutCount = this.topDownStep();
|
|
190
|
+
awakeCount = this.nextFrontier.size();
|
|
191
|
+
}
|
|
192
|
+
this.frontier.swap(this.nextFrontier);
|
|
193
|
+
this.nextFrontier.clear();
|
|
194
|
+
// currentDistance++; // Variable not used
|
|
195
|
+
edgesToCheck = this.calculateEdgesToCheck();
|
|
196
|
+
}
|
|
197
|
+
return this.buildResult();
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Reset internal state for reuse
|
|
201
|
+
*/
|
|
202
|
+
reset() {
|
|
203
|
+
this.parent.fill(-1);
|
|
204
|
+
this.frontier.clear();
|
|
205
|
+
this.nextFrontier.clear();
|
|
206
|
+
this.distances.clear();
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Convenience function for single-source BFS
|
|
211
|
+
*/
|
|
212
|
+
export function directionOptimizedBFS(graph, source, options) {
|
|
213
|
+
const bfs = new DirectionOptimizedBFS(graph, options);
|
|
214
|
+
return bfs.search(source);
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Convenience function for multi-source BFS
|
|
218
|
+
*/
|
|
219
|
+
export function directionOptimizedBFSMultiple(graph, sources, options) {
|
|
220
|
+
const bfs = new DirectionOptimizedBFS(graph, options);
|
|
221
|
+
return bfs.searchMultiple(sources);
|
|
222
|
+
}
|
|
223
|
+
//# sourceMappingURL=direction-optimized-bfs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"direction-optimized-bfs.js","sourceRoot":"","sources":["../../../src/optimized/direction-optimized-bfs.ts"],"names":[],"mappings":"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"}
|