@graphty/algorithms 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,17 +1,18 @@
1
1
  # @graphty/algorithms
2
2
 
3
- [![Build Status](https://github.com/graphty-org/algorithms/workflows/CI/badge.svg)](https://github.com/graphty-org/algorithms/actions)
4
- [![Coverage Status](https://codecov.io/gh/graphty-org/algorithms/branch/main/graph/badge.svg)](https://codecov.io/gh/graphty-org/algorithms)
3
+ [![Build Status](https://github.com/graphty-org/algorithms/actions/workflows/test.yml/badge.svg)](https://github.com/graphty-org/algorithms/actions/workflows/test.yml)
4
+ [![Coverage Status](https://coveralls.io/repos/github/graphty-org/algorithms/badge.svg)](https://coveralls.io/github/graphty-org/algorithms)
5
5
  [![npm version](https://img.shields.io/npm/v/@graphty/algorithms.svg)](https://www.npmjs.com/package/@graphty/algorithms)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
7
 
7
- A comprehensive TypeScript graph algorithms library with 65+ algorithms optimized for browser environments and visualization applications.
8
+ A comprehensive TypeScript graph algorithms library with 100+ algorithms optimized for browser environments and visualization applications.
8
9
 
9
10
  ## Features
10
11
 
11
12
  - **TypeScript-first**: Full type safety with comprehensive type definitions
12
13
  - **Browser-optimized**: Designed to run efficiently in web browsers
13
14
  - **Modular**: Import only the algorithms you need
14
- - **Comprehensive**: 65+ graph algorithms including traversal, shortest paths, centrality, clustering, flow, and more
15
+ - **Comprehensive**: 100+ graph algorithms including traversal, shortest paths, centrality, clustering, flow, matching, link prediction, and more
15
16
  - **Well-tested**: Extensive test suite with high coverage
16
17
  - **Standards-compliant**: Follows conventional commits and semantic versioning
17
18
 
@@ -46,7 +47,9 @@ const traversal = breadthFirstSearch(graph, 'A');
46
47
  console.log(traversal.order); // ['A', 'B', 'C']
47
48
 
48
49
  const shortestPaths = dijkstra(graph, 'A');
49
- console.log(shortestPaths.distances); // Map { 'A' => 0, 'B' => 1, 'C' => 3 }
50
+ // Get distance to C
51
+ const pathToC = shortestPaths.get('C');
52
+ console.log(pathToC?.distance); // 3
50
53
  ```
51
54
 
52
55
  ## API Reference
@@ -171,7 +174,7 @@ graph.clear(): void
171
174
  #### Breadth-First Search (BFS)
172
175
 
173
176
  ```typescript
174
- import { breadthFirstSearch, shortestPathBFS, singleSourceShortestPathBFS } from '@graphty/algorithms';
177
+ import { breadthFirstSearch, shortestPathBFS, singleSourceShortestPathBFS, isBipartite } from '@graphty/algorithms';
175
178
 
176
179
  // Basic BFS traversal
177
180
  const result = breadthFirstSearch(graph, startNode, {
@@ -196,7 +199,7 @@ const bipartite = isBipartite(graph);
196
199
  #### Depth-First Search (DFS)
197
200
 
198
201
  ```typescript
199
- import { depthFirstSearch, topologicalSort, hasCycleDFS } from '@graphty/algorithms';
202
+ import { depthFirstSearch, topologicalSort, hasCycleDFS, findStronglyConnectedComponents } from '@graphty/algorithms';
200
203
 
201
204
  // Basic DFS traversal
202
205
  const result = depthFirstSearch(graph, startNode, {
@@ -212,6 +215,10 @@ const sorted = topologicalSort(graph);
212
215
  // Cycle detection
213
216
  const hasCycle = hasCycleDFS(graph);
214
217
  // Returns: boolean
218
+
219
+ // Find strongly connected components using DFS
220
+ const sccs = findStronglyConnectedComponents(graph);
221
+ // Returns: NodeId[][]
215
222
  ```
216
223
 
217
224
  ### Shortest Path Algorithms
@@ -225,19 +232,20 @@ import { dijkstra, dijkstraPath, singleSourceShortestPath, allPairsShortestPath
225
232
  const result = dijkstra(graph, source, {
226
233
  target?: NodeId // Optional: stop when target is reached
227
234
  });
228
- // Returns: Map<NodeId, { path: NodeId[], distance: number, predecessor: NodeId | null }>
235
+ // Returns: Map<NodeId, ShortestPathResult>
236
+ // ShortestPathResult = { distance: number, path: NodeId[], predecessor: Map<NodeId, NodeId | null> }
229
237
 
230
238
  // Get specific path
231
239
  const path = dijkstraPath(graph, source, target);
232
- // Returns: { path: NodeId[], distance: number } | null
240
+ // Returns: ShortestPathResult | null
233
241
 
234
242
  // All shortest paths from source
235
243
  const paths = singleSourceShortestPath(graph, source);
236
- // Returns: Map<NodeId, { path: NodeId[], distance: number }>
244
+ // Returns: Map<NodeId, ShortestPathResult>
237
245
 
238
246
  // All pairs shortest paths
239
247
  const allPairs = allPairsShortestPath(graph);
240
- // Returns: Map<NodeId, Map<NodeId, { path: NodeId[], distance: number }>>
248
+ // Returns: Map<NodeId, Map<NodeId, ShortestPathResult>>
241
249
  ```
242
250
 
243
251
  #### Bellman-Ford Algorithm
@@ -256,7 +264,7 @@ const result = bellmanFord(graph, source);
256
264
 
257
265
  // Get specific path
258
266
  const path = bellmanFordPath(graph, source, target);
259
- // Returns: { path: NodeId[], distance: number } | null
267
+ // Returns: ShortestPathResult | null
260
268
 
261
269
  // Check for negative cycles
262
270
  const result = hasNegativeCycle(graph);
@@ -293,7 +301,7 @@ const centralities = degreeCentrality(graph, {
293
301
  normalized?: boolean, // Default: false
294
302
  weight?: string // Optional: edge property for weighted degree
295
303
  });
296
- // Returns: CentralityResult (Map<NodeId, number>)
304
+ // Returns: CentralityResult (Record<string, number>)
297
305
 
298
306
  // Calculate for single node
299
307
  const centrality = nodeDegreeCentrality(graph, nodeId, { normalized?: boolean });
@@ -311,7 +319,7 @@ const centralities = betweennessCentrality(graph, {
311
319
  weight?: string, // Optional: use weighted shortest paths
312
320
  endpoints?: boolean // Default: false, include endpoints in paths
313
321
  });
314
- // Returns: CentralityResult
322
+ // Returns: CentralityResult (Record<string, number>)
315
323
 
316
324
  // Single node betweenness
317
325
  const centrality = nodeBetweennessCentrality(graph, nodeId, options);
@@ -331,7 +339,7 @@ import { closenessCentrality, nodeClosenessCentrality, weightedClosenessCentrali
331
339
  const centralities = closenessCentrality(graph, {
332
340
  normalized?: boolean // Default: false
333
341
  });
334
- // Returns: CentralityResult
342
+ // Returns: CentralityResult (Record<string, number>)
335
343
 
336
344
  // Single node closeness
337
345
  const centrality = nodeClosenessCentrality(graph, nodeId, { normalized?: boolean });
@@ -342,7 +350,7 @@ const centralities = weightedClosenessCentrality(graph, {
342
350
  normalized?: boolean,
343
351
  weight?: string // Edge property for weights
344
352
  });
345
- // Returns: CentralityResult
353
+ // Returns: CentralityResult (Record<string, number>)
346
354
  ```
347
355
 
348
356
  #### PageRank
@@ -363,13 +371,67 @@ const result = pageRank(graph, {
363
371
  // Personalized PageRank (with bias)
364
372
  const ranks = personalizedPageRank(graph, personalization, options);
365
373
  // personalization: Map<NodeId, number> - restart probabilities
366
- // Returns: CentralityResult
374
+ // Returns: CentralityResult (Record<string, number>)
367
375
 
368
376
  // Get top N nodes by PageRank
369
377
  const topNodes = topPageRankNodes(graph, n, options);
370
378
  // Returns: Array<{ node: NodeId, rank: number }>
371
379
  ```
372
380
 
381
+ #### Eigenvector Centrality
382
+
383
+ ```typescript
384
+ import { eigenvectorCentrality, nodeEigenvectorCentrality } from '@graphty/algorithms';
385
+
386
+ // Calculate eigenvector centrality for all nodes
387
+ const centralities = eigenvectorCentrality(graph, {
388
+ maxIterations?: number, // Default: 100
389
+ tolerance?: number // Default: 1e-6
390
+ });
391
+ // Returns: CentralityResult (Record<string, number>)
392
+
393
+ // Single node eigenvector centrality
394
+ const centrality = nodeEigenvectorCentrality(graph, nodeId, options);
395
+ // Returns: number
396
+ ```
397
+
398
+ #### Katz Centrality
399
+
400
+ ```typescript
401
+ import { katzCentrality, nodeKatzCentrality } from '@graphty/algorithms';
402
+
403
+ // Calculate Katz centrality for all nodes
404
+ const centralities = katzCentrality(graph, {
405
+ alpha?: number, // Attenuation factor (default: 0.1)
406
+ beta?: number, // Weight for direct connections (default: 1.0)
407
+ maxIterations?: number, // Default: 100
408
+ tolerance?: number, // Default: 1e-6
409
+ normalized?: boolean // Default: true
410
+ });
411
+ // Returns: CentralityResult (Record<string, number>)
412
+
413
+ // Single node Katz centrality
414
+ const centrality = nodeKatzCentrality(graph, nodeId, options);
415
+ // Returns: number
416
+ ```
417
+
418
+ #### HITS Algorithm
419
+
420
+ ```typescript
421
+ import { hits, nodeHITS } from '@graphty/algorithms';
422
+
423
+ // Calculate hub and authority scores
424
+ const result = hits(graph, {
425
+ maxIterations?: number, // Default: 100
426
+ tolerance?: number // Default: 1e-6
427
+ });
428
+ // Returns: HITSResult { hubs: CentralityResult, authorities: CentralityResult }
429
+
430
+ // Single node HITS scores
431
+ const scores = nodeHITS(graph, nodeId, options);
432
+ // Returns: { hub: number, authority: number }
433
+ ```
434
+
373
435
  ### Connected Components
374
436
 
375
437
  #### Basic Component Operations
@@ -429,6 +491,10 @@ const stronglyConnected = isStronglyConnected(graph);
429
491
  // Create condensation graph (DAG of SCCs)
430
492
  const condensation = condensationGraph(graph);
431
493
  // Returns: { graph: Graph, componentMap: Map<NodeId, number> }
494
+
495
+ // Alternative DFS-based connected components
496
+ const components = connectedComponentsDFS(graph);
497
+ // Returns: ComponentResult
432
498
  ```
433
499
 
434
500
  #### Weakly Connected Components
@@ -599,6 +665,10 @@ const flow = fordFulkerson(graph, source, sink, {
599
665
 
600
666
  // Edmonds-Karp using BFS (better complexity)
601
667
  const flow = edmondsKarp(graph, source, sink, options);
668
+
669
+ // Create bipartite flow network
670
+ const flowNetwork = createBipartiteFlowNetwork(leftNodes, rightNodes, edges, capacities?);
671
+ // Returns: FlowNetwork
602
672
  ```
603
673
 
604
674
  #### Minimum Cut
@@ -627,29 +697,29 @@ const cut = kargerMinCut(graph, iterations?);
627
697
  import { hierarchicalClustering, cutDendrogram, cutDendrogramKClusters } from '@graphty/algorithms';
628
698
 
629
699
  // Agglomerative clustering
630
- const dendrogram = hierarchicalClustering(graph, {
631
- linkage: 'single' | 'complete' | 'average', // Default: 'average'
632
- distanceMetric?: (a: NodeId, b: NodeId) => number
633
- });
634
- // Returns: Dendrogram structure
700
+ const result = hierarchicalClustering(graph, linkage);
701
+ // graph: Map<NodeId, Set<NodeId>>
702
+ // linkage: 'single' | 'complete' | 'average' | 'ward' (default: 'single')
703
+ // Returns: HierarchicalClusteringResult { root: ClusterNode, dendrogram: ClusterNode[], clusters: Map<number, Set<NodeId>[]> }
635
704
 
636
705
  // Cut at specific height
637
- const clusters = cutDendrogram(dendrogram, height);
638
- // Returns: NodeId[][]
706
+ const clusters = cutDendrogram(result.root, height);
707
+ // Returns: Set<NodeId>[]
639
708
 
640
709
  // Get exactly k clusters
641
- const clusters = cutDendrogramKClusters(dendrogram, k);
642
- // Returns: NodeId[][]
710
+ const clusters = cutDendrogramKClusters(result.root, k);
711
+ // Returns: Set<NodeId>[]
643
712
  ```
644
713
 
645
714
  #### K-Core Decomposition
646
715
 
647
716
  ```typescript
648
- import { kCoreDecomposition, getKCore, kTruss } from '@graphty/algorithms';
717
+ import { kCoreDecomposition, getKCore, kTruss, degeneracyOrdering } from '@graphty/algorithms';
649
718
 
650
719
  // Find all k-cores
651
- const cores = kCoreDecomposition(graph);
652
- // Returns: Map<NodeId, number> (node to core number)
720
+ const result = kCoreDecomposition(graph);
721
+ // graph: Map<NodeId, Set<NodeId>>
722
+ // Returns: KCoreResult { cores: Map<number, Set<NodeId>>, coreness: Map<NodeId, number>, maxCore: number }
653
723
 
654
724
  // Extract specific k-core subgraph
655
725
  const kCore = getKCore(graph, k);
@@ -657,9 +727,231 @@ const kCore = getKCore(graph, k);
657
727
 
658
728
  // Find k-truss (triangular cores)
659
729
  const truss = kTruss(graph, k);
660
- // Returns: Graph
730
+ // Returns: Set<string> (edge strings)
731
+
732
+ // Degeneracy ordering
733
+ const ordering = degeneracyOrdering(graph);
734
+ // Returns: NodeId[]
735
+ ```
736
+
737
+ #### Spectral Clustering
738
+
739
+ ```typescript
740
+ import { spectralClustering } from '@graphty/algorithms';
741
+
742
+ // Spectral clustering using graph Laplacian
743
+ const result = spectralClustering(graph, {
744
+ k: number, // Number of clusters
745
+ laplacianType?: 'unnormalized' | 'normalized' | 'randomWalk', // Default: 'normalized'
746
+ maxIterations?: number, // Default: 100
747
+ tolerance?: number // Default: 1e-4
748
+ });
749
+ // Returns: SpectralClusteringResult { communities: NodeId[][], clusterAssignments: Map<NodeId, number> }
661
750
  ```
662
751
 
752
+ #### Markov Clustering (MCL)
753
+
754
+ ```typescript
755
+ import { markovClustering } from '@graphty/algorithms';
756
+
757
+ // MCL algorithm for network clustering
758
+ const result = markovClustering(graph, {
759
+ expansion?: number, // Expansion parameter (default: 2)
760
+ inflation?: number, // Inflation parameter (default: 2)
761
+ maxIterations?: number, // Default: 100
762
+ tolerance?: number // Default: 1e-6
763
+ });
764
+ // Returns: MCLResult { communities: NodeId[][], attractors: Set<NodeId>, iterations: number, converged: boolean }
765
+ ```
766
+
767
+ ### Matching Algorithms
768
+
769
+ #### Bipartite Matching
770
+
771
+ ```typescript
772
+ import { maximumBipartiteMatching, greedyBipartiteMatching, bipartitePartition } from '@graphty/algorithms';
773
+
774
+ // Maximum bipartite matching (Hungarian algorithm)
775
+ const matching = maximumBipartiteMatching(graph, {
776
+ leftNodes?: Set<NodeId>, // Optional: specify left partition
777
+ rightNodes?: Set<NodeId>, // Optional: specify right partition
778
+ });
779
+ // Returns: BipartiteMatchingResult { matching: Map<NodeId, NodeId>, size: number }
780
+
781
+ // Greedy bipartite matching (faster, approximate)
782
+ const matching = greedyBipartiteMatching(graph, options);
783
+
784
+ // Partition graph into bipartite sets
785
+ const partition = bipartitePartition(graph);
786
+ // Returns: { left: Set<NodeId>, right: Set<NodeId> } | null
787
+ ```
788
+
789
+ #### Graph Isomorphism
790
+
791
+ ```typescript
792
+ import { isGraphIsomorphic, findAllIsomorphisms } from '@graphty/algorithms';
793
+
794
+ // Check if two graphs are isomorphic
795
+ const result = isGraphIsomorphic(graph1, graph2, {
796
+ nodeMatch?: (node1: NodeId, node2: NodeId, g1: Graph, g2: Graph) => boolean,
797
+ edgeMatch?: (edge1: [NodeId, NodeId], edge2: [NodeId, NodeId], g1: Graph, g2: Graph) => boolean,
798
+ findAllMappings?: boolean // Find all possible isomorphisms
799
+ });
800
+ // Returns: IsomorphismResult { isIsomorphic: boolean, mapping?: Map<NodeId, NodeId> }
801
+
802
+ // Find all isomorphism mappings
803
+ const mappings = findAllIsomorphisms(graph1, graph2, options);
804
+ // Returns: Array<Map<NodeId, NodeId>>
805
+ ```
806
+
807
+ ### Link Prediction Algorithms
808
+
809
+ #### Common Neighbors
810
+
811
+ ```typescript
812
+ import { commonNeighborsScore, commonNeighborsPrediction, commonNeighborsForPairs } from '@graphty/algorithms';
813
+
814
+ // Score for a specific pair
815
+ const score = commonNeighborsScore(graph, node1, node2);
816
+ // Returns: number
817
+
818
+ // Predict links for all non-connected pairs
819
+ const predictions = commonNeighborsPrediction(graph, {
820
+ directed?: boolean, // Consider direction
821
+ includeExisting?: boolean, // Include existing edges
822
+ topK?: number // Return only top K predictions
823
+ });
824
+ // Returns: LinkPredictionScore[]
825
+
826
+ // Score multiple specific pairs
827
+ const scores = commonNeighborsForPairs(graph, pairs, options);
828
+ // Returns: LinkPredictionScore[]
829
+
830
+ // Evaluate prediction performance
831
+ const evaluation = evaluateCommonNeighbors(graph, testEdges);
832
+ // Returns: { precision, recall, f1Score }
833
+
834
+ // Get top candidates for a node
835
+ const candidates = getTopCandidatesForNode(graph, nodeId, { topK?: number });
836
+ // Returns: LinkPredictionScore[]
837
+ ```
838
+
839
+ #### Adamic-Adar Index
840
+
841
+ ```typescript
842
+ import { adamicAdarScore, adamicAdarPrediction, adamicAdarForPairs } from '@graphty/algorithms';
843
+
844
+ // Adamic-Adar score for a pair (weighted by neighbor degrees)
845
+ const score = adamicAdarScore(graph, node1, node2);
846
+ // Returns: number
847
+
848
+ // Predict links using Adamic-Adar
849
+ const predictions = adamicAdarPrediction(graph, {
850
+ directed?: boolean,
851
+ includeExisting?: boolean,
852
+ topK?: number
853
+ });
854
+ // Returns: LinkPredictionScore[]
855
+
856
+ // Score multiple pairs
857
+ const scores = adamicAdarForPairs(graph, pairs, options);
858
+ // Returns: LinkPredictionScore[]
859
+
860
+ // Compare Adamic-Adar with Common Neighbors
861
+ const comparison = compareAdamicAdarWithCommonNeighbors(graph, pairs);
862
+ // Returns: Array<{ source, target, adamicAdar, commonNeighbors }>
863
+
864
+ // Evaluate prediction performance
865
+ const evaluation = evaluateAdamicAdar(graph, testEdges);
866
+ // Returns: { precision, recall, f1Score }
867
+
868
+ // Get top candidates for a node
869
+ const candidates = getTopAdamicAdarCandidatesForNode(graph, nodeId, { topK?: number });
870
+ // Returns: LinkPredictionScore[]
871
+ ```
872
+
873
+ ### Research Algorithms (2023-2025)
874
+
875
+ Cutting-edge graph algorithms based on recent research.
876
+
877
+ #### SynC - Synergistic Deep Graph Clustering
878
+
879
+ ```typescript
880
+ import { syncClustering } from '@graphty/algorithms';
881
+
882
+ // Deep learning based clustering
883
+ const result = syncClustering(graph, {
884
+ k: number, // Number of clusters
885
+ maxIterations?: number, // Default: 100
886
+ learningRate?: number, // Default: 0.01
887
+ hiddenDim?: number, // Default: 64
888
+ randomSeed?: number
889
+ });
890
+ // Returns: SynCResult {
891
+ // communities: NodeId[][],
892
+ // clusterAssignments: Map<NodeId, number>,
893
+ // embeddings: Map<NodeId, number[]>,
894
+ // iterations: number,
895
+ // converged: boolean
896
+ // }
897
+ ```
898
+
899
+ #### TeraHAC - Scalable Hierarchical Agglomerative Clustering
900
+
901
+ ```typescript
902
+ import { teraHAC } from '@graphty/algorithms';
903
+
904
+ // Scalable hierarchical clustering
905
+ const result = teraHAC(graph, {
906
+ linkage?: 'single' | 'complete' | 'average', // Default: 'average'
907
+ k?: number, // Target number of clusters
908
+ threshold?: number, // Distance threshold for merging
909
+ sampleSize?: number, // Default: 1000
910
+ randomSeed?: number
911
+ });
912
+ // Returns: TeraHACResult {
913
+ // root: TeraHACClusterNode,
914
+ // dendrogram: TeraHACClusterNode[],
915
+ // clusters: NodeId[][],
916
+ // mergeDistances: number[]
917
+ // }
918
+ ```
919
+
920
+ #### GRSBM - Greedy Recursive Spectral Bisection with Modularity
921
+
922
+ ```typescript
923
+ import { grsbm } from '@graphty/algorithms';
924
+
925
+ // Explainable community detection
926
+ const result = grsbm(graph, {
927
+ minClusterSize?: number, // Default: 5
928
+ maxDepth?: number, // Default: 10
929
+ modularityThreshold?: number, // Default: 0.1
930
+ explainClusters?: boolean // Default: true
931
+ });
932
+ // Returns: GRSBMResult {
933
+ // clusters: GRSBMCluster[], // Each cluster has id, nodes, modularity, explanation
934
+ // hierarchy: Map<number, number[]>,
935
+ // totalModularity: number
936
+ // }
937
+ ```
938
+
939
+ ## Algorithm Categories Summary
940
+
941
+ ### Available Algorithms by Category:
942
+
943
+ - **Traversal**: BFS, DFS, Topological Sort, Cycle Detection, Bipartite Check
944
+ - **Shortest Path**: Dijkstra, Bellman-Ford, Floyd-Warshall, A*
945
+ - **Centrality**: Degree, Betweenness, Closeness, PageRank, Eigenvector, Katz, HITS
946
+ - **Components**: Connected, Strongly Connected, Weakly Connected, Condensation Graph
947
+ - **Community Detection**: Louvain, Leiden, Label Propagation, Girvan-Newman
948
+ - **Clustering**: Hierarchical, K-Core, Spectral, Markov (MCL)
949
+ - **Minimum Spanning Tree**: Kruskal, Prim
950
+ - **Network Flow**: Ford-Fulkerson, Edmonds-Karp, Min-Cut (Stoer-Wagner, Karger)
951
+ - **Matching**: Bipartite Matching, Graph Isomorphism
952
+ - **Link Prediction**: Common Neighbors, Adamic-Adar
953
+ - **Research Algorithms**: SynC, TeraHAC, GRSBM
954
+
663
955
  ## Examples
664
956
 
665
957
  The library includes comprehensive examples demonstrating each algorithm. Find them in the [examples directory](https://github.com/graphty-org/algorithms/tree/main/examples):
@@ -676,6 +968,9 @@ The library includes comprehensive examples demonstrating each algorithm. Find t
676
968
  - [Betweenness Centrality](https://github.com/graphty-org/algorithms/blob/main/examples/betweenness-centrality-example.js) - Bridge nodes
677
969
  - [Closeness Centrality](https://github.com/graphty-org/algorithms/blob/main/examples/closeness-centrality-example.js) - Central nodes
678
970
  - [PageRank](https://github.com/graphty-org/algorithms/blob/main/examples/pagerank-example.js) - Node ranking algorithm
971
+ - [Eigenvector Centrality](https://github.com/graphty-org/algorithms/blob/main/examples/eigenvector-centrality-example.js) - Influence from important nodes
972
+ - [Katz Centrality](https://github.com/graphty-org/algorithms/blob/main/examples/katz-centrality-example.js) - Weighted path counting
973
+ - [HITS Algorithm](https://github.com/graphty-org/algorithms/blob/main/examples/hits-algorithm-example.js) - Hub and authority scores
679
974
 
680
975
  ### Graph Structure
681
976
  - [Connected Components](https://github.com/graphty-org/algorithms/blob/main/examples/connected-components-example.js) - Find graph components
@@ -688,13 +983,30 @@ The library includes comprehensive examples demonstrating each algorithm. Find t
688
983
  - [Label Propagation](https://github.com/graphty-org/algorithms/blob/main/examples/label-propagation.ts) - Fast community detection
689
984
  - [Girvan-Newman](https://github.com/graphty-org/algorithms/blob/main/examples/girvan-newman-example.js) - Hierarchical communities
690
985
 
986
+ ### Clustering
987
+ - [Hierarchical Clustering](https://github.com/graphty-org/algorithms/blob/main/examples/hierarchical-clustering.ts) - Graph clustering
988
+ - [K-Core Decomposition](https://github.com/graphty-org/algorithms/blob/main/examples/k-core-decomposition.ts) - Core analysis
989
+ - [Spectral Clustering](https://github.com/graphty-org/algorithms/blob/main/examples/spectral-clustering-example.js) - Eigenvalue-based clustering
990
+ - [MCL Clustering](https://github.com/graphty-org/algorithms/blob/main/examples/mcl-clustering-example.js) - Markov clustering
991
+
992
+ ### Matching
993
+ - [Bipartite Matching](https://github.com/graphty-org/algorithms/blob/main/examples/bipartite-matching-example.js) - Job assignment, dating apps
994
+ - [Graph Isomorphism](https://github.com/graphty-org/algorithms/blob/main/examples/graph-isomorphism-example.js) - Structural equivalence
995
+
996
+ ### Link Prediction
997
+ - [Common Neighbors](https://github.com/graphty-org/algorithms/blob/main/examples/common-neighbors-example.js) - Friend suggestions
998
+ - [Adamic-Adar](https://github.com/graphty-org/algorithms/blob/main/examples/adamic-adar-example.js) - Weighted predictions
999
+
691
1000
  ### Advanced Algorithms
692
1001
  - [A* Pathfinding](https://github.com/graphty-org/algorithms/blob/main/examples/astar-pathfinding.ts) - Heuristic pathfinding
693
1002
  - [Flow Algorithms](https://github.com/graphty-org/algorithms/blob/main/examples/flow-algorithms.ts) - Maximum flow and applications
694
1003
  - [Ford-Fulkerson Flow](https://github.com/graphty-org/algorithms/blob/main/examples/ford-fulkerson-flow.ts) - Maximum flow implementation
695
1004
  - [Minimum Cut](https://github.com/graphty-org/algorithms/blob/main/examples/min-cut.ts) - Graph partitioning
696
- - [Hierarchical Clustering](https://github.com/graphty-org/algorithms/blob/main/examples/hierarchical-clustering.ts) - Graph clustering
697
- - [K-Core Decomposition](https://github.com/graphty-org/algorithms/blob/main/examples/k-core-decomposition.ts) - Core analysis
1005
+
1006
+ ### Research Algorithms
1007
+ - [SynC Clustering](https://github.com/graphty-org/algorithms/blob/main/examples/sync-example.js) - Deep learning based clustering
1008
+ - [TeraHAC](https://github.com/graphty-org/algorithms/blob/main/examples/terahac-example.js) - Scalable hierarchical clustering
1009
+ - [GRSBM](https://github.com/graphty-org/algorithms/blob/main/examples/grsbm-example.js) - Explainable community detection
698
1010
 
699
1011
  ## Advanced Usage Examples
700
1012
 
@@ -849,6 +1161,77 @@ interface CommunityResult {
849
1161
  communities: Map<NodeId, number>;
850
1162
  modularity: number;
851
1163
  }
1164
+
1165
+ interface ComponentResult {
1166
+ components: NodeId[][];
1167
+ componentMap: Map<NodeId, number>;
1168
+ }
1169
+
1170
+ interface HITSResult {
1171
+ hubs: CentralityResult;
1172
+ authorities: CentralityResult;
1173
+ }
1174
+
1175
+ interface SpectralClusteringResult {
1176
+ communities: NodeId[][];
1177
+ clusterAssignments: Map<NodeId, number>;
1178
+ }
1179
+
1180
+ interface MCLResult {
1181
+ communities: NodeId[][];
1182
+ attractors: Set<NodeId>;
1183
+ iterations: number;
1184
+ converged: boolean;
1185
+ }
1186
+
1187
+ interface BipartiteMatchingResult {
1188
+ matching: Map<NodeId, NodeId>;
1189
+ size: number;
1190
+ }
1191
+
1192
+ interface LinkPredictionScore {
1193
+ source: NodeId;
1194
+ target: NodeId;
1195
+ score: number;
1196
+ }
1197
+
1198
+ interface HierarchicalClusteringResult<T> {
1199
+ root: ClusterNode<T>;
1200
+ dendrogram: ClusterNode<T>[];
1201
+ clusters: Map<number, Set<T>[]>;
1202
+ }
1203
+
1204
+ interface KCoreResult<T> {
1205
+ cores: Map<number, Set<T>>;
1206
+ coreness: Map<T, number>;
1207
+ maxCore: number;
1208
+ }
1209
+
1210
+ interface IsomorphismResult {
1211
+ isIsomorphic: boolean;
1212
+ mapping?: Map<NodeId, NodeId>;
1213
+ }
1214
+
1215
+ interface SynCResult {
1216
+ communities: NodeId[][];
1217
+ clusterAssignments: Map<NodeId, number>;
1218
+ embeddings: Map<NodeId, number[]>;
1219
+ iterations: number;
1220
+ converged: boolean;
1221
+ }
1222
+
1223
+ interface TeraHACResult {
1224
+ root: TeraHACClusterNode;
1225
+ dendrogram: TeraHACClusterNode[];
1226
+ clusters: NodeId[][];
1227
+ mergeDistances: number[];
1228
+ }
1229
+
1230
+ interface GRSBMResult {
1231
+ clusters: GRSBMCluster[];
1232
+ hierarchy: Map<number, number[]>;
1233
+ totalModularity: number;
1234
+ }
852
1235
  ```
853
1236
 
854
1237
  ## Performance Considerations
@@ -868,6 +1251,9 @@ interface CommunityResult {
868
1251
  - Edmonds-Karp: O(VE²)
869
1252
  - Louvain/Leiden: O(n log n) average case
870
1253
  - Hierarchical Clustering: O(n² log n)
1254
+ - SynC: O(kni) where k is clusters, n is nodes, i is iterations
1255
+ - TeraHAC: O(n log n) with sampling
1256
+ - GRSBM: O(m log n) where m is edges
871
1257
  - **Memory Usage**: O(V + E) for graph storage
872
1258
  - **Browser Optimization**: Algorithms use iterative approaches where possible to avoid stack overflow
873
1259
 
@@ -913,8 +1299,48 @@ npm run lint:pkg # Check for unused dependencies
913
1299
 
914
1300
  # Git
915
1301
  npm run commit # Conventional commit helper
1302
+
1303
+ # HTML Examples
1304
+ npm run examples:html # Run interactive HTML examples
1305
+ npm run build:gh-pages # Build for GitHub Pages deployment
916
1306
  ```
917
1307
 
1308
+ ### Development Server
1309
+
1310
+ The project includes interactive HTML examples demonstrating each algorithm. To run them locally:
1311
+
1312
+ 1. **Copy the environment configuration:**
1313
+ ```bash
1314
+ cp .env.example .env
1315
+ ```
1316
+
1317
+ 2. **Configure the server (optional):**
1318
+ Edit `.env` to set your preferred host and port:
1319
+ ```bash
1320
+ # Server host (defaults to true for network exposure)
1321
+ HOST=localhost # For local-only access
1322
+ # HOST=0.0.0.0 # For network access
1323
+ # HOST=my.server.com # Custom domain
1324
+
1325
+ # Server port (defaults to 9000)
1326
+ PORT=9000 # Must be between 9000-9099
1327
+ ```
1328
+
1329
+ 3. **Start the development server:**
1330
+ ```bash
1331
+ npm run examples:html
1332
+ ```
1333
+
1334
+ 4. **Open your browser** to `http://localhost:9000` (or your configured host/port)
1335
+
1336
+ The HTML examples provide:
1337
+ - Interactive visualizations for each algorithm
1338
+ - Step-by-step execution with play/pause controls
1339
+ - Multiple graph types for testing
1340
+ - Real-time parameter adjustment
1341
+ - Educational information about complexity and use cases
1342
+ - Mobile debugging console (Eruda) for testing on mobile devices
1343
+
918
1344
  ### Project Structure
919
1345
 
920
1346
  ```
@@ -929,6 +1355,11 @@ src/
929
1355
  ├── types/ # TypeScript type definitions
930
1356
  └── utils/ # Utility functions
931
1357
 
1358
+ examples/
1359
+ ├── html/ # Interactive HTML examples
1360
+ │ ├── shared/ # Shared utilities and styles
1361
+ │ └── algorithms/ # Algorithm-specific examples
1362
+
932
1363
  test/
933
1364
  ├── unit/ # Unit tests
934
1365
  ├── browser/ # Browser-specific tests
@@ -957,4 +1388,4 @@ MIT © Adam Powers
957
1388
  ## Related Projects
958
1389
 
959
1390
  - [@graphty/layout](https://github.com/graphty-org/layout) - Graph layout algorithms
960
- - [@graphty/graphty-element](https://github.com/graphty-org/graphty-element) - 3D graph visualization web component
1391
+ - [@graphty/graphty-element](https://github.com/graphty-org/graphty-element) - 3D graph visualization web component