@graphty/algorithms 1.0.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.
Files changed (155) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +193 -0
  3. package/dist/src/algorithms/centrality/betweenness.d.ts +34 -0
  4. package/dist/src/algorithms/centrality/betweenness.d.ts.map +1 -0
  5. package/dist/src/algorithms/centrality/betweenness.js +223 -0
  6. package/dist/src/algorithms/centrality/betweenness.js.map +1 -0
  7. package/dist/src/algorithms/centrality/closeness.d.ts +43 -0
  8. package/dist/src/algorithms/centrality/closeness.d.ts.map +1 -0
  9. package/dist/src/algorithms/centrality/closeness.js +202 -0
  10. package/dist/src/algorithms/centrality/closeness.js.map +1 -0
  11. package/dist/src/algorithms/centrality/degree.d.ts +17 -0
  12. package/dist/src/algorithms/centrality/degree.d.ts.map +1 -0
  13. package/dist/src/algorithms/centrality/degree.js +86 -0
  14. package/dist/src/algorithms/centrality/degree.js.map +1 -0
  15. package/dist/src/algorithms/centrality/index.d.ts +11 -0
  16. package/dist/src/algorithms/centrality/index.d.ts.map +1 -0
  17. package/dist/src/algorithms/centrality/index.js +8 -0
  18. package/dist/src/algorithms/centrality/index.js.map +1 -0
  19. package/dist/src/algorithms/centrality/pagerank.d.ts +74 -0
  20. package/dist/src/algorithms/centrality/pagerank.d.ts.map +1 -0
  21. package/dist/src/algorithms/centrality/pagerank.js +191 -0
  22. package/dist/src/algorithms/centrality/pagerank.js.map +1 -0
  23. package/dist/src/algorithms/components/connected.d.ts +58 -0
  24. package/dist/src/algorithms/components/connected.d.ts.map +1 -0
  25. package/dist/src/algorithms/components/connected.js +234 -0
  26. package/dist/src/algorithms/components/connected.js.map +1 -0
  27. package/dist/src/algorithms/components/index.d.ts +5 -0
  28. package/dist/src/algorithms/components/index.d.ts.map +1 -0
  29. package/dist/src/algorithms/components/index.js +5 -0
  30. package/dist/src/algorithms/components/index.js.map +1 -0
  31. package/dist/src/algorithms/index.d.ts +8 -0
  32. package/dist/src/algorithms/index.d.ts.map +1 -0
  33. package/dist/src/algorithms/index.js +12 -0
  34. package/dist/src/algorithms/index.js.map +1 -0
  35. package/dist/src/algorithms/shortest-path/bellman-ford.d.ts +52 -0
  36. package/dist/src/algorithms/shortest-path/bellman-ford.d.ts.map +1 -0
  37. package/dist/src/algorithms/shortest-path/bellman-ford.js +131 -0
  38. package/dist/src/algorithms/shortest-path/bellman-ford.js.map +1 -0
  39. package/dist/src/algorithms/shortest-path/dijkstra.d.ts +26 -0
  40. package/dist/src/algorithms/shortest-path/dijkstra.d.ts.map +1 -0
  41. package/dist/src/algorithms/shortest-path/dijkstra.js +199 -0
  42. package/dist/src/algorithms/shortest-path/dijkstra.js.map +1 -0
  43. package/dist/src/algorithms/shortest-path/index.d.ts +7 -0
  44. package/dist/src/algorithms/shortest-path/index.d.ts.map +1 -0
  45. package/dist/src/algorithms/shortest-path/index.js +6 -0
  46. package/dist/src/algorithms/shortest-path/index.js.map +1 -0
  47. package/dist/src/algorithms/traversal/bfs.d.ts +25 -0
  48. package/dist/src/algorithms/traversal/bfs.d.ts.map +1 -0
  49. package/dist/src/algorithms/traversal/bfs.js +189 -0
  50. package/dist/src/algorithms/traversal/bfs.js.map +1 -0
  51. package/dist/src/algorithms/traversal/dfs.d.ts +32 -0
  52. package/dist/src/algorithms/traversal/dfs.d.ts.map +1 -0
  53. package/dist/src/algorithms/traversal/dfs.js +259 -0
  54. package/dist/src/algorithms/traversal/dfs.js.map +1 -0
  55. package/dist/src/algorithms/traversal/index.d.ts +7 -0
  56. package/dist/src/algorithms/traversal/index.d.ts.map +1 -0
  57. package/dist/src/algorithms/traversal/index.js +6 -0
  58. package/dist/src/algorithms/traversal/index.js.map +1 -0
  59. package/dist/src/core/graph.d.ts +100 -0
  60. package/dist/src/core/graph.d.ts.map +1 -0
  61. package/dist/src/core/graph.js +276 -0
  62. package/dist/src/core/graph.js.map +1 -0
  63. package/dist/src/data-structures/index.d.ts +6 -0
  64. package/dist/src/data-structures/index.d.ts.map +1 -0
  65. package/dist/src/data-structures/index.js +6 -0
  66. package/dist/src/data-structures/index.js.map +1 -0
  67. package/dist/src/data-structures/priority-queue.d.ts +60 -0
  68. package/dist/src/data-structures/priority-queue.d.ts.map +1 -0
  69. package/dist/src/data-structures/priority-queue.js +152 -0
  70. package/dist/src/data-structures/priority-queue.js.map +1 -0
  71. package/dist/src/data-structures/union-find.d.ts +54 -0
  72. package/dist/src/data-structures/union-find.d.ts.map +1 -0
  73. package/dist/src/data-structures/union-find.js +145 -0
  74. package/dist/src/data-structures/union-find.js.map +1 -0
  75. package/dist/src/index.d.ts +11 -0
  76. package/dist/src/index.d.ts.map +1 -0
  77. package/dist/src/index.js +13 -0
  78. package/dist/src/index.js.map +1 -0
  79. package/dist/src/types/index.d.ts +74 -0
  80. package/dist/src/types/index.d.ts.map +1 -0
  81. package/dist/src/types/index.js +5 -0
  82. package/dist/src/types/index.js.map +1 -0
  83. package/dist/test/browser/basic.test.d.ts +2 -0
  84. package/dist/test/browser/basic.test.d.ts.map +1 -0
  85. package/dist/test/browser/basic.test.js +70 -0
  86. package/dist/test/browser/basic.test.js.map +1 -0
  87. package/dist/test/unit/bellman-ford.test.d.ts +2 -0
  88. package/dist/test/unit/bellman-ford.test.d.ts.map +1 -0
  89. package/dist/test/unit/bellman-ford.test.js +231 -0
  90. package/dist/test/unit/bellman-ford.test.js.map +1 -0
  91. package/dist/test/unit/betweenness-centrality.test.d.ts +2 -0
  92. package/dist/test/unit/betweenness-centrality.test.d.ts.map +1 -0
  93. package/dist/test/unit/betweenness-centrality.test.js +311 -0
  94. package/dist/test/unit/betweenness-centrality.test.js.map +1 -0
  95. package/dist/test/unit/bfs.test.d.ts +2 -0
  96. package/dist/test/unit/bfs.test.d.ts.map +1 -0
  97. package/dist/test/unit/bfs.test.js +277 -0
  98. package/dist/test/unit/bfs.test.js.map +1 -0
  99. package/dist/test/unit/closeness.test.d.ts +2 -0
  100. package/dist/test/unit/closeness.test.d.ts.map +1 -0
  101. package/dist/test/unit/closeness.test.js +266 -0
  102. package/dist/test/unit/closeness.test.js.map +1 -0
  103. package/dist/test/unit/connected-components.test.d.ts +2 -0
  104. package/dist/test/unit/connected-components.test.d.ts.map +1 -0
  105. package/dist/test/unit/connected-components.test.js +355 -0
  106. package/dist/test/unit/connected-components.test.js.map +1 -0
  107. package/dist/test/unit/degree-centrality.test.d.ts +2 -0
  108. package/dist/test/unit/degree-centrality.test.d.ts.map +1 -0
  109. package/dist/test/unit/degree-centrality.test.js +260 -0
  110. package/dist/test/unit/degree-centrality.test.js.map +1 -0
  111. package/dist/test/unit/dfs.test.d.ts +2 -0
  112. package/dist/test/unit/dfs.test.d.ts.map +1 -0
  113. package/dist/test/unit/dfs.test.js +350 -0
  114. package/dist/test/unit/dfs.test.js.map +1 -0
  115. package/dist/test/unit/dijkstra.test.d.ts +2 -0
  116. package/dist/test/unit/dijkstra.test.d.ts.map +1 -0
  117. package/dist/test/unit/dijkstra.test.js +311 -0
  118. package/dist/test/unit/dijkstra.test.js.map +1 -0
  119. package/dist/test/unit/graph.test.d.ts +2 -0
  120. package/dist/test/unit/graph.test.d.ts.map +1 -0
  121. package/dist/test/unit/graph.test.js +175 -0
  122. package/dist/test/unit/graph.test.js.map +1 -0
  123. package/dist/test/unit/pagerank.test.d.ts +2 -0
  124. package/dist/test/unit/pagerank.test.d.ts.map +1 -0
  125. package/dist/test/unit/pagerank.test.js +281 -0
  126. package/dist/test/unit/pagerank.test.js.map +1 -0
  127. package/dist/test/unit/priority-queue.test.d.ts +2 -0
  128. package/dist/test/unit/priority-queue.test.d.ts.map +1 -0
  129. package/dist/test/unit/priority-queue.test.js +189 -0
  130. package/dist/test/unit/priority-queue.test.js.map +1 -0
  131. package/dist/test/unit/union-find.test.d.ts +2 -0
  132. package/dist/test/unit/union-find.test.d.ts.map +1 -0
  133. package/dist/test/unit/union-find.test.js +245 -0
  134. package/dist/test/unit/union-find.test.js.map +1 -0
  135. package/package.json +100 -0
  136. package/src/algorithms/centrality/betweenness.ts +303 -0
  137. package/src/algorithms/centrality/closeness.ts +296 -0
  138. package/src/algorithms/centrality/degree.ts +105 -0
  139. package/src/algorithms/centrality/index.ts +11 -0
  140. package/src/algorithms/centrality/pagerank.ts +302 -0
  141. package/src/algorithms/components/connected.ts +298 -0
  142. package/src/algorithms/components/index.ts +17 -0
  143. package/src/algorithms/index.ts +15 -0
  144. package/src/algorithms/shortest-path/bellman-ford.ts +214 -0
  145. package/src/algorithms/shortest-path/dijkstra.ts +256 -0
  146. package/src/algorithms/shortest-path/index.ts +7 -0
  147. package/src/algorithms/traversal/bfs.ts +236 -0
  148. package/src/algorithms/traversal/dfs.ts +367 -0
  149. package/src/algorithms/traversal/index.ts +7 -0
  150. package/src/core/graph.ts +326 -0
  151. package/src/data-structures/index.ts +6 -0
  152. package/src/data-structures/priority-queue.ts +180 -0
  153. package/src/data-structures/union-find.ts +170 -0
  154. package/src/index.ts +35 -0
  155. package/src/types/index.ts +95 -0
@@ -0,0 +1,259 @@
1
+ import { Graph } from "../../core/graph.js";
2
+ /**
3
+ * Perform depth-first search starting from a given node
4
+ */
5
+ export function depthFirstSearch(graph, startNode, options = {}) {
6
+ if (!graph.hasNode(startNode)) {
7
+ throw new Error(`Start node ${String(startNode)} not found in graph`);
8
+ }
9
+ const visited = new Set();
10
+ const order = [];
11
+ const tree = new Map();
12
+ if (options.recursive) {
13
+ dfsRecursive(graph, startNode, visited, order, tree, options, 0);
14
+ }
15
+ else {
16
+ dfsIterative(graph, startNode, visited, order, tree, options);
17
+ }
18
+ return { visited, order, tree };
19
+ }
20
+ /**
21
+ * Iterative DFS implementation (safer for browsers)
22
+ */
23
+ function dfsIterative(graph, startNode, visited, order, tree, options) {
24
+ if (options.preOrder === false) {
25
+ // For post-order, use a simpler recursive approach to ensure correctness
26
+ dfsRecursive(graph, startNode, visited, order, tree, options, 0, null);
27
+ return;
28
+ }
29
+ const stack = [];
30
+ stack.push({ node: startNode, parent: null, depth: 0 });
31
+ while (stack.length > 0) {
32
+ const current = stack.pop();
33
+ if (!current) {
34
+ break;
35
+ }
36
+ if (!visited.has(current.node)) {
37
+ visited.add(current.node);
38
+ tree.set(current.node, current.parent);
39
+ // Pre-order processing
40
+ order.push(current.node);
41
+ // Call visitor callback if provided
42
+ if (options.visitCallback) {
43
+ options.visitCallback(current.node, current.depth);
44
+ }
45
+ // Early termination if target found
46
+ if (options.targetNode && current.node === options.targetNode) {
47
+ break;
48
+ }
49
+ // Add neighbors to stack in reverse order to maintain left-to-right traversal
50
+ const neighbors = Array.from(graph.neighbors(current.node));
51
+ for (let i = neighbors.length - 1; i >= 0; i--) {
52
+ const neighbor = neighbors[i];
53
+ if (neighbor !== undefined && !visited.has(neighbor)) {
54
+ stack.push({ node: neighbor, parent: current.node, depth: current.depth + 1 });
55
+ }
56
+ }
57
+ }
58
+ }
59
+ }
60
+ /**
61
+ * Recursive DFS implementation
62
+ */
63
+ function dfsRecursive(graph, node, visited, order, tree, options, depth, parent = null) {
64
+ visited.add(node);
65
+ tree.set(node, parent);
66
+ // Pre-order processing
67
+ if (options.preOrder !== false) {
68
+ order.push(node);
69
+ if (options.visitCallback) {
70
+ options.visitCallback(node, depth);
71
+ }
72
+ // Early termination if target found
73
+ if (options.targetNode && node === options.targetNode) {
74
+ return;
75
+ }
76
+ }
77
+ // Recursively visit neighbors
78
+ for (const neighbor of graph.neighbors(node)) {
79
+ if (!visited.has(neighbor)) {
80
+ dfsRecursive(graph, neighbor, visited, order, tree, options, depth + 1, node);
81
+ }
82
+ }
83
+ // Post-order processing
84
+ if (options.preOrder === false) {
85
+ order.push(node);
86
+ if (options.visitCallback) {
87
+ options.visitCallback(node, depth);
88
+ }
89
+ }
90
+ }
91
+ /**
92
+ * Detect cycles in a graph using DFS
93
+ */
94
+ export function hasCycleDFS(graph) {
95
+ const visited = new Set();
96
+ // Check each unvisited node for cycles
97
+ for (const node of graph.nodes()) {
98
+ if (!visited.has(node.id)) {
99
+ if (graph.isDirected) {
100
+ const recursionStack = new Set();
101
+ if (hasCycleUtilDirected(graph, node.id, visited, recursionStack)) {
102
+ return true;
103
+ }
104
+ }
105
+ else {
106
+ if (hasCycleUtilUndirected(graph, node.id, visited, null)) {
107
+ return true;
108
+ }
109
+ }
110
+ }
111
+ }
112
+ return false;
113
+ }
114
+ /**
115
+ * Utility function for cycle detection in directed graphs
116
+ */
117
+ function hasCycleUtilDirected(graph, node, visited, recursionStack) {
118
+ visited.add(node);
119
+ recursionStack.add(node);
120
+ // Check all neighbors
121
+ for (const neighbor of graph.neighbors(node)) {
122
+ if (!visited.has(neighbor)) {
123
+ if (hasCycleUtilDirected(graph, neighbor, visited, recursionStack)) {
124
+ return true;
125
+ }
126
+ }
127
+ else if (recursionStack.has(neighbor)) {
128
+ // Back edge found - cycle detected
129
+ return true;
130
+ }
131
+ }
132
+ recursionStack.delete(node);
133
+ return false;
134
+ }
135
+ /**
136
+ * Utility function for cycle detection in undirected graphs
137
+ */
138
+ function hasCycleUtilUndirected(graph, node, visited, parent) {
139
+ visited.add(node);
140
+ // Check all neighbors
141
+ for (const neighbor of graph.neighbors(node)) {
142
+ if (!visited.has(neighbor)) {
143
+ if (hasCycleUtilUndirected(graph, neighbor, visited, node)) {
144
+ return true;
145
+ }
146
+ }
147
+ else if (neighbor !== parent) {
148
+ // Found a visited node that's not the parent - cycle detected
149
+ return true;
150
+ }
151
+ }
152
+ return false;
153
+ }
154
+ /**
155
+ * Topological sorting using DFS (for directed acyclic graphs)
156
+ */
157
+ export function topologicalSort(graph) {
158
+ if (!graph.isDirected) {
159
+ throw new Error("Topological sort requires a directed graph");
160
+ }
161
+ // First check if graph has cycles
162
+ if (hasCycleDFS(graph)) {
163
+ return null; // Cannot topologically sort a graph with cycles
164
+ }
165
+ const visited = new Set();
166
+ const stack = [];
167
+ // Perform DFS from each unvisited node
168
+ for (const node of graph.nodes()) {
169
+ if (!visited.has(node.id)) {
170
+ topologicalSortUtil(graph, node.id, visited, stack);
171
+ }
172
+ }
173
+ // Return nodes in reverse order of finishing times
174
+ return stack.reverse();
175
+ }
176
+ /**
177
+ * Utility function for topological sorting
178
+ */
179
+ function topologicalSortUtil(graph, node, visited, stack) {
180
+ visited.add(node);
181
+ // Visit all neighbors first
182
+ for (const neighbor of graph.neighbors(node)) {
183
+ if (!visited.has(neighbor)) {
184
+ topologicalSortUtil(graph, neighbor, visited, stack);
185
+ }
186
+ }
187
+ // Add current node to stack after visiting all neighbors
188
+ stack.push(node);
189
+ }
190
+ /**
191
+ * Find strongly connected components using DFS (for directed graphs)
192
+ */
193
+ export function findStronglyConnectedComponents(graph) {
194
+ if (!graph.isDirected) {
195
+ throw new Error("Strongly connected components require a directed graph");
196
+ }
197
+ const visited = new Set();
198
+ const finishOrder = [];
199
+ // Step 1: Get nodes in order of finishing times
200
+ for (const node of graph.nodes()) {
201
+ if (!visited.has(node.id)) {
202
+ dfsFinishOrder(graph, node.id, visited, finishOrder);
203
+ }
204
+ }
205
+ // Step 2: Create transpose graph (reverse all edges)
206
+ const transposeGraph = createTransposeGraph(graph);
207
+ // Step 3: DFS on transpose graph in reverse finish order
208
+ const visited2 = new Set();
209
+ const components = [];
210
+ for (let i = finishOrder.length - 1; i >= 0; i--) {
211
+ const node = finishOrder[i];
212
+ if (node !== undefined && !visited2.has(node)) {
213
+ const component = [];
214
+ dfsCollectComponent(transposeGraph, node, visited2, component);
215
+ components.push(component);
216
+ }
217
+ }
218
+ return components;
219
+ }
220
+ /**
221
+ * DFS to record finish order
222
+ */
223
+ function dfsFinishOrder(graph, node, visited, finishOrder) {
224
+ visited.add(node);
225
+ for (const neighbor of graph.neighbors(node)) {
226
+ if (!visited.has(neighbor)) {
227
+ dfsFinishOrder(graph, neighbor, visited, finishOrder);
228
+ }
229
+ }
230
+ finishOrder.push(node);
231
+ }
232
+ /**
233
+ * DFS to collect nodes in a component
234
+ */
235
+ function dfsCollectComponent(graph, node, visited, component) {
236
+ visited.add(node);
237
+ component.push(node);
238
+ for (const neighbor of graph.neighbors(node)) {
239
+ if (!visited.has(neighbor)) {
240
+ dfsCollectComponent(graph, neighbor, visited, component);
241
+ }
242
+ }
243
+ }
244
+ /**
245
+ * Create transpose (reverse) of a directed graph
246
+ */
247
+ function createTransposeGraph(graph) {
248
+ const transpose = new Graph({ directed: true });
249
+ // Add all nodes
250
+ for (const node of graph.nodes()) {
251
+ transpose.addNode(node.id, node.data);
252
+ }
253
+ // Add reverse edges
254
+ for (const edge of graph.edges()) {
255
+ transpose.addEdge(edge.target, edge.source, edge.weight, edge.data);
256
+ }
257
+ return transpose;
258
+ }
259
+ //# sourceMappingURL=dfs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dfs.js","sourceRoot":"","sources":["../../../../src/algorithms/traversal/dfs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Graph traversal algorithms
3
+ */
4
+ export { breadthFirstSearch, isBipartite, shortestPathBFS, singleSourceShortestPathBFS } from "./bfs.js";
5
+ export type { DFSOptions } from "./dfs.js";
6
+ export { depthFirstSearch, findStronglyConnectedComponents, hasCycleDFS, topologicalSort } from "./dfs.js";
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/algorithms/traversal/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAC,kBAAkB,EAAE,WAAW,EAAE,eAAe,EAAE,2BAA2B,EAAC,MAAM,UAAU,CAAC;AACvG,YAAY,EAAC,UAAU,EAAC,MAAM,UAAU,CAAC;AACzC,OAAO,EAAC,gBAAgB,EAAE,+BAA+B,EAAE,WAAW,EAAE,eAAe,EAAC,MAAM,UAAU,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Graph traversal algorithms
3
+ */
4
+ export { breadthFirstSearch, isBipartite, shortestPathBFS, singleSourceShortestPathBFS } from "./bfs.js";
5
+ export { depthFirstSearch, findStronglyConnectedComponents, hasCycleDFS, topologicalSort } from "./dfs.js";
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/algorithms/traversal/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAC,kBAAkB,EAAE,WAAW,EAAE,eAAe,EAAE,2BAA2B,EAAC,MAAM,UAAU,CAAC;AAEvG,OAAO,EAAC,gBAAgB,EAAE,+BAA+B,EAAE,WAAW,EAAE,eAAe,EAAC,MAAM,UAAU,CAAC"}
@@ -0,0 +1,100 @@
1
+ import type { Edge, GraphConfig, Node, NodeId } from "../types/index.js";
2
+ /**
3
+ * Core Graph data structure for the Graphty Algorithms library
4
+ *
5
+ * Provides efficient graph representation with support for both directed and undirected graphs.
6
+ * Uses adjacency lists for optimal performance with sparse graphs.
7
+ */
8
+ export declare class Graph {
9
+ private nodeMap;
10
+ private adjacencyList;
11
+ private incomingEdges;
12
+ private config;
13
+ private edgeCount;
14
+ constructor(config?: Partial<GraphConfig>);
15
+ /**
16
+ * Add a node to the graph
17
+ */
18
+ addNode(id: NodeId, data?: Record<string, unknown>): void;
19
+ /**
20
+ * Remove a node from the graph
21
+ */
22
+ removeNode(id: NodeId): boolean;
23
+ /**
24
+ * Add an edge to the graph
25
+ */
26
+ addEdge(source: NodeId, target: NodeId, weight?: number, data?: Record<string, unknown>): void;
27
+ /**
28
+ * Remove an edge from the graph
29
+ */
30
+ removeEdge(source: NodeId, target: NodeId): boolean;
31
+ /**
32
+ * Check if a node exists in the graph
33
+ */
34
+ hasNode(id: NodeId): boolean;
35
+ /**
36
+ * Check if an edge exists in the graph
37
+ */
38
+ hasEdge(source: NodeId, target: NodeId): boolean;
39
+ /**
40
+ * Get a node by ID
41
+ */
42
+ getNode(id: NodeId): Node | undefined;
43
+ /**
44
+ * Get an edge by source and target
45
+ */
46
+ getEdge(source: NodeId, target: NodeId): Edge | undefined;
47
+ /**
48
+ * Get the number of nodes in the graph
49
+ */
50
+ get nodeCount(): number;
51
+ /**
52
+ * Get the number of edges in the graph
53
+ */
54
+ get totalEdgeCount(): number;
55
+ /**
56
+ * Check if the graph is directed
57
+ */
58
+ get isDirected(): boolean;
59
+ /**
60
+ * Get all nodes in the graph
61
+ */
62
+ nodes(): IterableIterator<Node>;
63
+ /**
64
+ * Get all edges in the graph
65
+ */
66
+ edges(): IterableIterator<Edge>;
67
+ /**
68
+ * Get neighbors of a node (outgoing edges)
69
+ */
70
+ neighbors(nodeId: NodeId): IterableIterator<NodeId>;
71
+ /**
72
+ * Get incoming neighbors of a node (directed graphs only)
73
+ */
74
+ inNeighbors(nodeId: NodeId): IterableIterator<NodeId>;
75
+ /**
76
+ * Get outgoing neighbors of a node
77
+ */
78
+ outNeighbors(nodeId: NodeId): IterableIterator<NodeId>;
79
+ /**
80
+ * Get the degree of a node
81
+ */
82
+ degree(nodeId: NodeId): number;
83
+ /**
84
+ * Get the in-degree of a node
85
+ */
86
+ inDegree(nodeId: NodeId): number;
87
+ /**
88
+ * Get the out-degree of a node
89
+ */
90
+ outDegree(nodeId: NodeId): number;
91
+ /**
92
+ * Create a copy of the graph
93
+ */
94
+ clone(): Graph;
95
+ /**
96
+ * Get graph configuration
97
+ */
98
+ getConfig(): GraphConfig;
99
+ }
100
+ //# sourceMappingURL=graph.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../../../src/core/graph.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAC,MAAM,mBAAmB,CAAC;AAEvE;;;;;GAKG;AACH,qBAAa,KAAK;IACd,OAAO,CAAC,OAAO,CAAoB;IACnC,OAAO,CAAC,aAAa,CAAiC;IACtD,OAAO,CAAC,aAAa,CAAiC;IACtD,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,SAAS,CAAS;gBAEd,MAAM,GAAE,OAAO,CAAC,WAAW,CAAM;IAa7C;;OAEG;IACH,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAWzD;;OAEG;IACH,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAwC/B;;OAEG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,SAAI,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IA8CzF;;OAEG;IACH,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO;IAyBnD;;OAEG;IACH,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAI5B;;OAEG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO;IAKhD;;OAEG;IACH,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS;IAIrC;;OAEG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS;IAKzD;;OAEG;IACH,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED;;OAEG;IACH,IAAI,cAAc,IAAI,MAAM,CAE3B;IAED;;OAEG;IACH,IAAI,UAAU,IAAI,OAAO,CAExB;IAED;;OAEG;IACH,KAAK,IAAI,gBAAgB,CAAC,IAAI,CAAC;IAI/B;;OAEG;IACF,KAAK,IAAI,gBAAgB,CAAC,IAAI,CAAC;IAahC;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,gBAAgB,CAAC,MAAM,CAAC;IAKnD;;OAEG;IACH,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,gBAAgB,CAAC,MAAM,CAAC;IASrD;;OAEG;IACH,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,gBAAgB,CAAC,MAAM,CAAC;IAItD;;OAEG;IACH,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAS9B;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAShC;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAKjC;;OAEG;IACH,KAAK,IAAI,KAAK;IAqBd;;OAEG;IACH,SAAS,IAAI,WAAW;CAG3B"}
@@ -0,0 +1,276 @@
1
+ /**
2
+ * Core Graph data structure for the Graphty Algorithms library
3
+ *
4
+ * Provides efficient graph representation with support for both directed and undirected graphs.
5
+ * Uses adjacency lists for optimal performance with sparse graphs.
6
+ */
7
+ export class Graph {
8
+ nodeMap;
9
+ adjacencyList;
10
+ incomingEdges; // For directed graphs
11
+ config;
12
+ edgeCount;
13
+ constructor(config = {}) {
14
+ this.config = {
15
+ directed: false,
16
+ allowSelfLoops: true,
17
+ allowParallelEdges: false,
18
+ ...config,
19
+ };
20
+ this.nodeMap = new Map();
21
+ this.adjacencyList = new Map();
22
+ this.incomingEdges = new Map();
23
+ this.edgeCount = 0;
24
+ }
25
+ /**
26
+ * Add a node to the graph
27
+ */
28
+ addNode(id, data) {
29
+ if (!this.nodeMap.has(id)) {
30
+ this.nodeMap.set(id, { id, data });
31
+ this.adjacencyList.set(id, new Map());
32
+ if (this.config.directed) {
33
+ this.incomingEdges.set(id, new Map());
34
+ }
35
+ }
36
+ }
37
+ /**
38
+ * Remove a node from the graph
39
+ */
40
+ removeNode(id) {
41
+ if (!this.nodeMap.has(id)) {
42
+ return false;
43
+ }
44
+ // Remove all edges connected to this node
45
+ const outgoingEdges = this.adjacencyList.get(id);
46
+ if (outgoingEdges) {
47
+ for (const targetId of outgoingEdges.keys()) {
48
+ this.removeEdge(id, targetId);
49
+ }
50
+ }
51
+ if (this.config.directed) {
52
+ const incomingEdges = this.incomingEdges.get(id);
53
+ if (incomingEdges) {
54
+ for (const sourceId of incomingEdges.keys()) {
55
+ this.removeEdge(sourceId, id);
56
+ }
57
+ }
58
+ }
59
+ else {
60
+ // For undirected graphs, also remove edges where this node is the target
61
+ for (const [nodeId, edges] of this.adjacencyList) {
62
+ if (edges.has(id)) {
63
+ this.removeEdge(nodeId, id);
64
+ }
65
+ }
66
+ }
67
+ // Remove the node itself
68
+ this.nodeMap.delete(id);
69
+ this.adjacencyList.delete(id);
70
+ if (this.config.directed) {
71
+ this.incomingEdges.delete(id);
72
+ }
73
+ return true;
74
+ }
75
+ /**
76
+ * Add an edge to the graph
77
+ */
78
+ addEdge(source, target, weight = 1, data) {
79
+ // Ensure both nodes exist
80
+ this.addNode(source);
81
+ this.addNode(target);
82
+ // Check self-loops
83
+ if (!this.config.allowSelfLoops && source === target) {
84
+ throw new Error("Self-loops are not allowed in this graph");
85
+ }
86
+ // Check parallel edges
87
+ if (!this.config.allowParallelEdges && this.hasEdge(source, target)) {
88
+ throw new Error("Parallel edges are not allowed in this graph");
89
+ }
90
+ const edge = { source, target, weight, data };
91
+ // Add to adjacency list
92
+ const sourceAdjacency = this.adjacencyList.get(source);
93
+ if (sourceAdjacency) {
94
+ sourceAdjacency.set(target, edge);
95
+ }
96
+ if (this.config.directed) {
97
+ // For directed graphs, add to incoming edges list
98
+ const targetIncoming = this.incomingEdges.get(target);
99
+ if (targetIncoming) {
100
+ targetIncoming.set(source, edge);
101
+ }
102
+ }
103
+ else {
104
+ // For undirected graphs, add the reverse edge
105
+ if (source !== target) {
106
+ const reverseEdge = { source: target, target: source, weight, data };
107
+ const targetAdjacency = this.adjacencyList.get(target);
108
+ if (targetAdjacency) {
109
+ targetAdjacency.set(source, reverseEdge);
110
+ }
111
+ }
112
+ }
113
+ this.edgeCount++;
114
+ }
115
+ /**
116
+ * Remove an edge from the graph
117
+ */
118
+ removeEdge(source, target) {
119
+ const sourceEdges = this.adjacencyList.get(source);
120
+ if (!sourceEdges?.has(target)) {
121
+ return false;
122
+ }
123
+ sourceEdges.delete(target);
124
+ if (this.config.directed) {
125
+ const targetIncoming = this.incomingEdges.get(target);
126
+ if (targetIncoming) {
127
+ targetIncoming.delete(source);
128
+ }
129
+ }
130
+ else {
131
+ // For undirected graphs, remove the reverse edge
132
+ const targetEdges = this.adjacencyList.get(target);
133
+ if (targetEdges) {
134
+ targetEdges.delete(source);
135
+ }
136
+ }
137
+ this.edgeCount--;
138
+ return true;
139
+ }
140
+ /**
141
+ * Check if a node exists in the graph
142
+ */
143
+ hasNode(id) {
144
+ return this.nodeMap.has(id);
145
+ }
146
+ /**
147
+ * Check if an edge exists in the graph
148
+ */
149
+ hasEdge(source, target) {
150
+ const sourceEdges = this.adjacencyList.get(source);
151
+ return sourceEdges ? sourceEdges.has(target) : false;
152
+ }
153
+ /**
154
+ * Get a node by ID
155
+ */
156
+ getNode(id) {
157
+ return this.nodeMap.get(id);
158
+ }
159
+ /**
160
+ * Get an edge by source and target
161
+ */
162
+ getEdge(source, target) {
163
+ const sourceEdges = this.adjacencyList.get(source);
164
+ return sourceEdges ? sourceEdges.get(target) : undefined;
165
+ }
166
+ /**
167
+ * Get the number of nodes in the graph
168
+ */
169
+ get nodeCount() {
170
+ return this.nodeMap.size;
171
+ }
172
+ /**
173
+ * Get the number of edges in the graph
174
+ */
175
+ get totalEdgeCount() {
176
+ return this.edgeCount;
177
+ }
178
+ /**
179
+ * Check if the graph is directed
180
+ */
181
+ get isDirected() {
182
+ return this.config.directed;
183
+ }
184
+ /**
185
+ * Get all nodes in the graph
186
+ */
187
+ nodes() {
188
+ return this.nodeMap.values();
189
+ }
190
+ /**
191
+ * Get all edges in the graph
192
+ */
193
+ *edges() {
194
+ for (const [source, edges] of this.adjacencyList) {
195
+ for (const edge of edges.values()) {
196
+ // For undirected graphs, only yield each edge once
197
+ if (!this.config.directed && source > edge.target) {
198
+ continue;
199
+ }
200
+ yield edge;
201
+ }
202
+ }
203
+ }
204
+ /**
205
+ * Get neighbors of a node (outgoing edges)
206
+ */
207
+ neighbors(nodeId) {
208
+ const edges = this.adjacencyList.get(nodeId);
209
+ return edges ? edges.keys() : new Map().keys();
210
+ }
211
+ /**
212
+ * Get incoming neighbors of a node (directed graphs only)
213
+ */
214
+ inNeighbors(nodeId) {
215
+ if (!this.config.directed) {
216
+ return this.neighbors(nodeId);
217
+ }
218
+ const edges = this.incomingEdges.get(nodeId);
219
+ return edges ? edges.keys() : new Map().keys();
220
+ }
221
+ /**
222
+ * Get outgoing neighbors of a node
223
+ */
224
+ outNeighbors(nodeId) {
225
+ return this.neighbors(nodeId);
226
+ }
227
+ /**
228
+ * Get the degree of a node
229
+ */
230
+ degree(nodeId) {
231
+ if (this.config.directed) {
232
+ return this.inDegree(nodeId) + this.outDegree(nodeId);
233
+ }
234
+ const edges = this.adjacencyList.get(nodeId);
235
+ return edges ? edges.size : 0;
236
+ }
237
+ /**
238
+ * Get the in-degree of a node
239
+ */
240
+ inDegree(nodeId) {
241
+ if (!this.config.directed) {
242
+ return this.degree(nodeId);
243
+ }
244
+ const edges = this.incomingEdges.get(nodeId);
245
+ return edges ? edges.size : 0;
246
+ }
247
+ /**
248
+ * Get the out-degree of a node
249
+ */
250
+ outDegree(nodeId) {
251
+ const edges = this.adjacencyList.get(nodeId);
252
+ return edges ? edges.size : 0;
253
+ }
254
+ /**
255
+ * Create a copy of the graph
256
+ */
257
+ clone() {
258
+ const cloned = new Graph(this.config);
259
+ // Copy nodes
260
+ for (const node of this.nodeMap.values()) {
261
+ cloned.addNode(node.id, node.data ? { ...node.data } : undefined);
262
+ }
263
+ // Copy edges
264
+ for (const edge of this.edges()) {
265
+ cloned.addEdge(edge.source, edge.target, edge.weight, edge.data ? { ...edge.data } : undefined);
266
+ }
267
+ return cloned;
268
+ }
269
+ /**
270
+ * Get graph configuration
271
+ */
272
+ getConfig() {
273
+ return { ...this.config };
274
+ }
275
+ }
276
+ //# sourceMappingURL=graph.js.map