@graphty/algorithms 1.2.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 +490 -336
- 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 +40 -21
- 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 +1 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +4 -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.map +1 -1
- package/dist/src/research/grsbm.js +6 -14
- package/dist/src/research/grsbm.js.map +1 -1
- package/dist/src/research/sync.d.ts.map +1 -1
- package/dist/src/research/sync.js +3 -29
- package/dist/src/research/sync.js.map +1 -1
- package/dist/src/research/terahac.d.ts +2 -0
- package/dist/src/research/terahac.d.ts.map +1 -1
- package/dist/src/research/terahac.js +7 -3
- package/dist/src/research/terahac.js.map +1 -1
- 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 +18 -3
- 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 +44 -20
- 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 +6 -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 +7 -16
- package/src/research/sync.ts +3 -32
- package/src/research/terahac.ts +10 -2
- 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
|
@@ -1,236 +1,18 @@
|
|
|
1
|
-
import type {Graph} from "../../core/graph.js";
|
|
2
|
-
import type {NodeId, ShortestPathResult, TraversalOptions, TraversalResult} from "../../types/index.js";
|
|
3
|
-
|
|
4
1
|
/**
|
|
5
2
|
* Breadth-First Search (BFS) implementation
|
|
6
3
|
*
|
|
7
4
|
* Explores graph level by level from a starting node. Guarantees shortest path
|
|
8
5
|
* in unweighted graphs and can be used for various graph analysis tasks.
|
|
6
|
+
*
|
|
7
|
+
* Automatically uses optimized implementations for large graphs (>10k nodes)
|
|
8
|
+
* to provide the best performance without requiring manual configuration.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
): TraversalResult {
|
|
19
|
-
if (!graph.hasNode(startNode)) {
|
|
20
|
-
throw new Error(`Start node ${String(startNode)} not found in graph`);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const visited = new Set<NodeId>();
|
|
24
|
-
const queue: {node: NodeId, level: number}[] = [];
|
|
25
|
-
const order: NodeId[] = [];
|
|
26
|
-
const tree = new Map<NodeId, NodeId | null>();
|
|
27
|
-
|
|
28
|
-
// Initialize with start node
|
|
29
|
-
queue.push({node: startNode, level: 0});
|
|
30
|
-
visited.add(startNode);
|
|
31
|
-
tree.set(startNode, null);
|
|
32
|
-
|
|
33
|
-
while (queue.length > 0) {
|
|
34
|
-
const current = queue.shift();
|
|
35
|
-
if (!current) {
|
|
36
|
-
break;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
order.push(current.node);
|
|
40
|
-
|
|
41
|
-
// Call visitor callback if provided
|
|
42
|
-
if (options.visitCallback) {
|
|
43
|
-
options.visitCallback(current.node, current.level);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// Early termination if target found
|
|
47
|
-
if (options.targetNode && current.node === options.targetNode) {
|
|
48
|
-
break;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// Explore neighbors
|
|
52
|
-
for (const neighbor of graph.neighbors(current.node)) {
|
|
53
|
-
if (!visited.has(neighbor)) {
|
|
54
|
-
visited.add(neighbor);
|
|
55
|
-
tree.set(neighbor, current.node);
|
|
56
|
-
queue.push({node: neighbor, level: current.level + 1});
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
return {visited, order, tree};
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Find shortest path between two nodes in an unweighted graph using BFS
|
|
66
|
-
*/
|
|
67
|
-
export function shortestPathBFS(
|
|
68
|
-
graph: Graph,
|
|
69
|
-
source: NodeId,
|
|
70
|
-
target: NodeId,
|
|
71
|
-
): ShortestPathResult | null {
|
|
72
|
-
if (!graph.hasNode(source)) {
|
|
73
|
-
throw new Error(`Source node ${String(source)} not found in graph`);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
if (!graph.hasNode(target)) {
|
|
77
|
-
throw new Error(`Target node ${String(target)} not found in graph`);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
// Special case: source equals target
|
|
81
|
-
if (source === target) {
|
|
82
|
-
return {
|
|
83
|
-
distance: 0,
|
|
84
|
-
path: [source],
|
|
85
|
-
predecessor: new Map([[source, null]]),
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
const visited = new Set<NodeId>();
|
|
90
|
-
const queue: {node: NodeId, distance: number}[] = [];
|
|
91
|
-
const predecessor = new Map<NodeId, NodeId | null>();
|
|
92
|
-
|
|
93
|
-
// Initialize BFS
|
|
94
|
-
queue.push({node: source, distance: 0});
|
|
95
|
-
visited.add(source);
|
|
96
|
-
predecessor.set(source, null);
|
|
97
|
-
|
|
98
|
-
while (queue.length > 0) {
|
|
99
|
-
const current = queue.shift();
|
|
100
|
-
if (!current) {
|
|
101
|
-
break;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// Target found
|
|
105
|
-
if (current.node === target) {
|
|
106
|
-
const path = reconstructPath(target, predecessor);
|
|
107
|
-
return {
|
|
108
|
-
distance: current.distance,
|
|
109
|
-
path,
|
|
110
|
-
predecessor,
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// Explore neighbors
|
|
115
|
-
for (const neighbor of graph.neighbors(current.node)) {
|
|
116
|
-
if (!visited.has(neighbor)) {
|
|
117
|
-
visited.add(neighbor);
|
|
118
|
-
predecessor.set(neighbor, current.node);
|
|
119
|
-
queue.push({node: neighbor, distance: current.distance + 1});
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
// No path found
|
|
125
|
-
return null;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* Find shortest paths from source to all reachable nodes using BFS
|
|
130
|
-
*/
|
|
131
|
-
export function singleSourceShortestPathBFS(
|
|
132
|
-
graph: Graph,
|
|
133
|
-
source: NodeId,
|
|
134
|
-
): Map<NodeId, ShortestPathResult> {
|
|
135
|
-
if (!graph.hasNode(source)) {
|
|
136
|
-
throw new Error(`Source node ${String(source)} not found in graph`);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
const results = new Map<NodeId, ShortestPathResult>();
|
|
140
|
-
const visited = new Set<NodeId>();
|
|
141
|
-
const queue: {node: NodeId, distance: number}[] = [];
|
|
142
|
-
const predecessor = new Map<NodeId, NodeId | null>();
|
|
143
|
-
|
|
144
|
-
// Initialize BFS
|
|
145
|
-
queue.push({node: source, distance: 0});
|
|
146
|
-
visited.add(source);
|
|
147
|
-
predecessor.set(source, null);
|
|
148
|
-
|
|
149
|
-
while (queue.length > 0) {
|
|
150
|
-
const current = queue.shift();
|
|
151
|
-
if (!current) {
|
|
152
|
-
break;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
// Store result for current node
|
|
156
|
-
const path = reconstructPath(current.node, predecessor);
|
|
157
|
-
results.set(current.node, {
|
|
158
|
-
distance: current.distance,
|
|
159
|
-
path,
|
|
160
|
-
predecessor: new Map(predecessor),
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
// Explore neighbors
|
|
164
|
-
for (const neighbor of graph.neighbors(current.node)) {
|
|
165
|
-
if (!visited.has(neighbor)) {
|
|
166
|
-
visited.add(neighbor);
|
|
167
|
-
predecessor.set(neighbor, current.node);
|
|
168
|
-
queue.push({node: neighbor, distance: current.distance + 1});
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
return results;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
/**
|
|
177
|
-
* Check if the graph is bipartite using BFS coloring
|
|
178
|
-
*/
|
|
179
|
-
export function isBipartite(graph: Graph): boolean {
|
|
180
|
-
if (graph.isDirected) {
|
|
181
|
-
throw new Error("Bipartite test requires an undirected graph");
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
const color = new Map<NodeId, 0 | 1>();
|
|
185
|
-
const visited = new Set<NodeId>();
|
|
186
|
-
|
|
187
|
-
// Check each connected component
|
|
188
|
-
for (const node of Array.from(graph.nodes())) {
|
|
189
|
-
if (!visited.has(node.id)) {
|
|
190
|
-
const queue: NodeId[] = [node.id];
|
|
191
|
-
color.set(node.id, 0);
|
|
192
|
-
visited.add(node.id);
|
|
193
|
-
|
|
194
|
-
while (queue.length > 0) {
|
|
195
|
-
const current = queue.shift();
|
|
196
|
-
if (!current) {
|
|
197
|
-
break;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
const currentColor = color.get(current);
|
|
201
|
-
if (currentColor === undefined) {
|
|
202
|
-
continue;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
for (const neighbor of Array.from(graph.neighbors(current))) {
|
|
206
|
-
if (!visited.has(neighbor)) {
|
|
207
|
-
// Color with opposite color
|
|
208
|
-
color.set(neighbor, currentColor === 0 ? 1 : 0);
|
|
209
|
-
visited.add(neighbor);
|
|
210
|
-
queue.push(neighbor);
|
|
211
|
-
} else if (color.get(neighbor) === currentColor) {
|
|
212
|
-
// Same color as current node - not bipartite
|
|
213
|
-
return false;
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
return true;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
/**
|
|
224
|
-
* Reconstruct path from predecessor map
|
|
225
|
-
*/
|
|
226
|
-
function reconstructPath(target: NodeId, predecessor: Map<NodeId, NodeId | null>): NodeId[] {
|
|
227
|
-
const path: NodeId[] = [];
|
|
228
|
-
let current: NodeId | null = target;
|
|
229
|
-
|
|
230
|
-
while (current !== null) {
|
|
231
|
-
path.unshift(current);
|
|
232
|
-
current = predecessor.get(current) ?? null;
|
|
233
|
-
}
|
|
11
|
+
// Re-export unified implementations that automatically optimize for large graphs
|
|
12
|
+
export {
|
|
13
|
+
breadthFirstSearch,
|
|
14
|
+
isBipartite,
|
|
15
|
+
shortestPathBFS,
|
|
16
|
+
singleSourceShortestPathBFS,
|
|
17
|
+
} from "./bfs-unified.js";
|
|
234
18
|
|
|
235
|
-
return path;
|
|
236
|
-
}
|