@graphty/algorithms 1.8.1 → 2.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 (43) hide show
  1. package/README.md +5 -4
  2. package/dist/algorithms.js +518 -525
  3. package/dist/algorithms.js.map +1 -1
  4. package/dist/algorithms.standalone.js +519 -526
  5. package/dist/algorithms.standalone.js.map +1 -1
  6. package/dist/src/algorithms/centrality/eigenvector.d.ts +13 -2
  7. package/dist/src/algorithms/centrality/eigenvector.d.ts.map +1 -1
  8. package/dist/src/algorithms/centrality/eigenvector.js +96 -73
  9. package/dist/src/algorithms/centrality/eigenvector.js.map +1 -1
  10. package/dist/src/algorithms/community/girvan-newman.js +35 -15
  11. package/dist/src/algorithms/community/girvan-newman.js.map +1 -1
  12. package/dist/src/algorithms/community/leiden.d.ts.map +1 -1
  13. package/dist/src/algorithms/community/leiden.js +214 -222
  14. package/dist/src/algorithms/community/leiden.js.map +1 -1
  15. package/dist/src/algorithms/community/louvain-optimized.d.ts +28 -72
  16. package/dist/src/algorithms/community/louvain-optimized.d.ts.map +1 -1
  17. package/dist/src/algorithms/community/louvain-optimized.js +249 -262
  18. package/dist/src/algorithms/community/louvain-optimized.js.map +1 -1
  19. package/dist/src/algorithms/community/modularity-utils.d.ts +15 -7
  20. package/dist/src/algorithms/community/modularity-utils.d.ts.map +1 -1
  21. package/dist/src/algorithms/community/modularity-utils.js +38 -38
  22. package/dist/src/algorithms/community/modularity-utils.js.map +1 -1
  23. package/dist/src/algorithms/shortest-path/bellman-ford.d.ts.map +1 -1
  24. package/dist/src/algorithms/shortest-path/bellman-ford.js +35 -8
  25. package/dist/src/algorithms/shortest-path/bellman-ford.js.map +1 -1
  26. package/dist/src/errors.d.ts +21 -0
  27. package/dist/src/errors.d.ts.map +1 -0
  28. package/dist/src/errors.js +23 -0
  29. package/dist/src/errors.js.map +1 -0
  30. package/dist/src/index.d.ts +1 -0
  31. package/dist/src/index.d.ts.map +1 -1
  32. package/dist/src/index.js +2 -0
  33. package/dist/src/index.js.map +1 -1
  34. package/package.json +11 -8
  35. package/src/algorithms/centrality/eigenvector.ts +103 -84
  36. package/src/algorithms/community/girvan-newman.ts +38 -17
  37. package/src/algorithms/community/leiden.ts +270 -275
  38. package/src/algorithms/community/louvain-optimized.ts +303 -313
  39. package/src/algorithms/community/modularity-utils.ts +42 -45
  40. package/src/algorithms/shortest-path/bellman-ford.ts +46 -8
  41. package/src/errors.ts +26 -0
  42. package/src/index.ts +3 -0
  43. package/dist/tsconfig.tsbuildinfo +0 -1
@@ -3,13 +3,18 @@ import type { CommunityResult } from "../../types/index.js";
3
3
  /**
4
4
  * Optimized Louvain community detection algorithm with early pruning and threshold cycling
5
5
  *
6
+ * Runs the full multilevel method of Blondel et al. (local moving, then aggregating each community
7
+ * into one node, repeated until nothing moves) over typed arrays indexed 0..n-1.
8
+ *
6
9
  * Key optimizations:
7
- * - Leaf node pruning: Skip nodes with degree 1
10
+ * - Typed-array adjacency (CSR) instead of per-edge map lookups
11
+ * - Leaf node pruning: skip a degree-1 node already in its neighbour's community
8
12
  * - Importance ordering: Process high-impact nodes first
9
- * - Threshold cycling: Adaptive convergence thresholds
13
+ * - Threshold cycling: Adaptive move thresholds, relative to each node's largest possible gain
10
14
  * - Early termination: Stop when changes become insignificant
11
15
  *
12
- * Expected speedup: 2-5x on large graphs with many leaf nodes
16
+ * The graph is treated as undirected: a directed edge counts as an undirected edge of its weight.
17
+ * A self-loop of weight w adds 2w to its node's degree, the standard convention (NetworkX too).
13
18
  */
14
19
  interface OptimizedLouvainOptions {
15
20
  /**
@@ -17,11 +22,11 @@ interface OptimizedLouvainOptions {
17
22
  */
18
23
  resolution?: number;
19
24
  /**
20
- * Maximum iterations per level (default: 100)
25
+ * Maximum local-moving sweeps per level (default: 100)
21
26
  */
22
27
  maxIterations?: number;
23
28
  /**
24
- * Convergence tolerance (default: 1e-6)
29
+ * Convergence tolerance on a sweep's modularity gain (default: 1e-6)
25
30
  */
26
31
  tolerance?: number;
27
32
  /**
@@ -33,7 +38,7 @@ interface OptimizedLouvainOptions {
33
38
  */
34
39
  importanceOrdering?: boolean;
35
40
  /**
36
- * Base pruning threshold (default: 0.01)
41
+ * Base move threshold, as a fraction of a node's largest possible modularity gain (default: 0.01)
37
42
  */
38
43
  pruningThreshold?: number;
39
44
  /**
@@ -51,11 +56,6 @@ interface PruningStats {
51
56
  */
52
57
  export declare class OptimizedLouvain {
53
58
  private graph;
54
- private communities;
55
- private communityWeights;
56
- private nodeWeights;
57
- private nodeDegrees;
58
- private totalWeight;
59
59
  private pruningStats;
60
60
  /**
61
61
  * Create an optimized Louvain detector for the given graph
@@ -65,78 +65,34 @@ export declare class OptimizedLouvain {
65
65
  /**
66
66
  * Run optimized Louvain algorithm
67
67
  * @param options - Algorithm configuration options
68
- * @returns Community detection result with communities, modularity, and iterations
68
+ * @returns Community detection result with communities, modularity, and iterations (levels)
69
69
  */
70
70
  detectCommunities(options?: OptimizedLouvainOptions): CommunityResult;
71
71
  /**
72
- * Initialize data structures
72
+ * Get pruning statistics
73
+ * @returns Statistics about nodes pruned during optimization
73
74
  */
74
- private initialize;
75
+ getPruningStats(): PruningStats;
75
76
  /**
76
- * Get nodes ordered by importance (degree * log(weight))
77
- * @returns Array of node IDs sorted by descending importance
77
+ * Index the graph's nodes 0..n-1 and build the level-0 CSR adjacency
78
+ * @returns The level-0 graph and the node id at each index
78
79
  */
79
- private getNodesInImportanceOrder;
80
+ private buildLevel;
80
81
  /**
81
- * Perform local moving phase with optimizations
82
- * @param nodes - Array of node IDs to process
82
+ * Move each node to the neighbouring community with the best modularity gain, until no move
83
+ * improves modularity
84
+ * @param level - The graph at this level
83
85
  * @param options - Local moving options
84
- * @param options.pruneLeaves - Whether to skip leaf nodes
85
- * @param options.threshold - Minimum gain threshold for moves
86
- * @param options.resolution - Resolution parameter for modularity
87
- * @returns True if any improvement was made, false otherwise
88
- */
89
- private performLocalMoving;
90
- /**
91
- * Check if node is a leaf (degree 1)
92
- * @param nodeId - The node ID to check
93
- * @returns True if the node has degree 1, false otherwise
86
+ * @returns Each node's community (numbered 0..count-1), the count, and whether any node moved
94
87
  */
95
- private isLeafNode;
88
+ private localMoving;
96
89
  /**
97
- * Get adaptive threshold that decreases with iterations
98
- * @param iteration - Current iteration number
99
- * @param baseThreshold - Base threshold value to scale
100
- * @returns Adaptive threshold value that decays over iterations
90
+ * Order nodes for local moving, by importance (degree * log(1 + weighted degree)) if asked
91
+ * @param level - The graph at this level
92
+ * @param importanceOrdering - Whether to sort by importance
93
+ * @returns Node indices in processing order
101
94
  */
102
- private getAdaptiveThreshold;
103
- /**
104
- * Calculate modularity gain from moving a node to a community
105
- * @param nodeId - The node ID to move
106
- * @param targetCommunity - The target community ID
107
- * @param resolution - Resolution parameter for modularity calculation
108
- * @returns The modularity gain from moving the node
109
- */
110
- private calculateModularityGain;
111
- /**
112
- * Remove node from community (for gain calculation)
113
- * @param nodeId - The node ID to remove
114
- * @param community - The community ID to remove from
115
- */
116
- private removeNodeFromCommunity;
117
- /**
118
- * Add node to community
119
- * @param nodeId - The node ID to add
120
- * @param community - The community ID to add to
121
- */
122
- private addNodeToCommunity;
123
- /**
124
- * Get neighboring communities of a node
125
- * @param nodeId - The node ID to find neighbor communities for
126
- * @returns Set of community IDs that neighbors belong to
127
- */
128
- private getNeighborCommunities;
129
- /**
130
- * Calculate total modularity
131
- * @param resolution - Resolution parameter for modularity calculation
132
- * @returns The modularity score of the current partition
133
- */
134
- private calculateModularity;
135
- /**
136
- * Get pruning statistics
137
- * @returns Statistics about nodes pruned during optimization
138
- */
139
- getPruningStats(): PruningStats;
95
+ private nodeOrder;
140
96
  }
141
97
  /**
142
98
  * Optimized Louvain algorithm with automatic optimization selection
@@ -1 +1 @@
1
- {"version":3,"file":"louvain-optimized.d.ts","sourceRoot":"","sources":["../../../../src/algorithms/community/louvain-optimized.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,KAAK,EAAE,eAAe,EAAU,MAAM,sBAAsB,CAAC;AAEpE;;;;;;;;;;GAUG;AAEH,UAAU,uBAAuB;IAC7B;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;OAEG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;OAEG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,UAAU,YAAY;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,iBAAiB,EAAE,MAAM,CAAC;CAC7B;AAED;;GAEG;AACH,qBAAa,gBAAgB;IACzB,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,WAAW,CAAsB;IACzC,OAAO,CAAC,gBAAgB,CAAsB;IAC9C,OAAO,CAAC,WAAW,CAAsB;IACzC,OAAO,CAAC,WAAW,CAAsB;IACzC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,YAAY,CAAe;IAEnC;;;OAGG;gBACS,KAAK,EAAE,KAAK;IAcxB;;;;OAIG;IACI,iBAAiB,CAAC,OAAO,GAAE,uBAA4B,GAAG,eAAe;IAmEhF;;OAEG;IACH,OAAO,CAAC,UAAU;IA2ClB;;;OAGG;IACH,OAAO,CAAC,yBAAyB;IAiBjC;;;;;;;;OAQG;IACH,OAAO,CAAC,kBAAkB;IAoE1B;;;;OAIG;IACH,OAAO,CAAC,UAAU;IAKlB;;;;;OAKG;IACH,OAAO,CAAC,oBAAoB;IAM5B;;;;;;OAMG;IACH,OAAO,CAAC,uBAAuB;IAiC/B;;;;OAIG;IACH,OAAO,CAAC,uBAAuB;IAM/B;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;IAM1B;;;;OAIG;IACH,OAAO,CAAC,sBAAsB;IAuB9B;;;;OAIG;IACH,OAAO,CAAC,mBAAmB;IAwC3B;;;OAGG;IACI,eAAe,IAAI,YAAY;CAGzC;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,GAAE,uBAA4B,GAAG,eAAe,CAGrG"}
1
+ {"version":3,"file":"louvain-optimized.d.ts","sourceRoot":"","sources":["../../../../src/algorithms/community/louvain-optimized.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,KAAK,EAAE,eAAe,EAAU,MAAM,sBAAsB,CAAC;AAEpE;;;;;;;;;;;;;;;GAeG;AAEH,UAAU,uBAAuB;IAC7B;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;OAEG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;OAEG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,UAAU,YAAY;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,iBAAiB,EAAE,MAAM,CAAC;CAC7B;AAyBD;;GAEG;AACH,qBAAa,gBAAgB;IACzB,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,YAAY,CAAe;IAEnC;;;OAGG;gBACS,KAAK,EAAE,KAAK;IASxB;;;;OAIG;IACI,iBAAiB,CAAC,OAAO,GAAE,uBAA4B,GAAG,eAAe;IA8ChF;;;OAGG;IACI,eAAe,IAAI,YAAY;IAItC;;;OAGG;IACH,OAAO,CAAC,UAAU;IAqClB;;;;;;OAMG;IACH,OAAO,CAAC,WAAW;IAiHnB;;;;;OAKG;IACH,OAAO,CAAC,SAAS;CAiBpB;AA+GD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,GAAE,uBAA4B,GAAG,eAAe,CAGrG"}