Clusters phase A: community detection core (Louvain, seeded, structural)
detectCommunities(nodes, edges) in src/core/clusters.ts (new dep graphology-communities-louvain): Louvain modularity over the undirected, unweighted follows+supports structure (user-decided 2026-09-13). The random-walk traversal runs on an inlined seeded mulberry32 so the same graph always yields the same partition; community indices are still unstable across edits, which is exactly why labelings (phase B) key to sorted MEMBER SETS. follows+supports between the same pair collapse to one edge; self-loops and dangling edges are skipped defensively; no min-size filter here (the >=3 render threshold is a presentation rule). Tests: two-cliques-plus-bridge split, determinism, singleton/empty graphs, pair collapse, defensive skips, member sorting. 363/363. Real-data smoke over the current notes graph: 338 nodes / 211 edges -> 138 communities, modularity 0.95, and the big ones are exactly the learn-session topics (databases, differential forms, sales, servers, vim, copulas...). 32 communities clear the >=3 render threshold.
This commit is contained in:
Generated
+53
@@ -26,6 +26,7 @@
|
||||
"cmdk": "^1.1.1",
|
||||
"embla-carousel-react": "^8.6.0",
|
||||
"graphology": "^0.26.0",
|
||||
"graphology-communities-louvain": "^2.0.2",
|
||||
"graphology-layout-forceatlas2": "^0.10.1",
|
||||
"katex": "^0.16.47",
|
||||
"linkedom": "^0.18.13",
|
||||
@@ -8837,6 +8838,34 @@
|
||||
"graphology-types": ">=0.24.0"
|
||||
}
|
||||
},
|
||||
"node_modules/graphology-communities-louvain": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/graphology-communities-louvain/-/graphology-communities-louvain-2.0.2.tgz",
|
||||
"integrity": "sha512-zt+2hHVPYxjEquyecxWXoUoIuN/UvYzsvI7boDdMNz0rRvpESQ7+e+Ejv6wK7AThycbZXuQ6DkG8NPMCq6XwoA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"graphology-indices": "^0.17.0",
|
||||
"graphology-utils": "^2.4.4",
|
||||
"mnemonist": "^0.39.0",
|
||||
"pandemonium": "^2.4.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"graphology-types": ">=0.19.0"
|
||||
}
|
||||
},
|
||||
"node_modules/graphology-indices": {
|
||||
"version": "0.17.0",
|
||||
"resolved": "https://registry.npmjs.org/graphology-indices/-/graphology-indices-0.17.0.tgz",
|
||||
"integrity": "sha512-A7RXuKQvdqSWOpn7ZVQo4S33O0vCfPBnUSf7FwE0zNCasqwZVUaCXePuWo5HBpWw68KJcwObZDHpFk6HKH6MYQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"graphology-utils": "^2.4.2",
|
||||
"mnemonist": "^0.39.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"graphology-types": ">=0.20.0"
|
||||
}
|
||||
},
|
||||
"node_modules/graphology-layout-forceatlas2": {
|
||||
"version": "0.10.1",
|
||||
"resolved": "https://registry.npmjs.org/graphology-layout-forceatlas2/-/graphology-layout-forceatlas2-0.10.1.tgz",
|
||||
@@ -11595,6 +11624,15 @@
|
||||
"integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/mnemonist": {
|
||||
"version": "0.39.8",
|
||||
"resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.39.8.tgz",
|
||||
"integrity": "sha512-vyWo2K3fjrUw8YeeZ1zF0fy6Mu59RHokURlld8ymdUPjMlD9EC9ov1/YPqTgqRvUN9nTr3Gqfz29LYAmu0PHPQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"obliterator": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/modern-tar": {
|
||||
"version": "0.8.4",
|
||||
"resolved": "https://registry.npmjs.org/modern-tar/-/modern-tar-0.8.4.tgz",
|
||||
@@ -11993,6 +12031,12 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/obliterator": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.5.tgz",
|
||||
"integrity": "sha512-42CPE9AhahZRsMNslczq0ctAEtqk8Eka26QofnqC346BZdHDySk3LWka23LI7ULIw11NmltpiLagIq8gBozxTw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/oniguruma-parser": {
|
||||
"version": "0.12.2",
|
||||
"resolved": "https://registry.npmjs.org/oniguruma-parser/-/oniguruma-parser-0.12.2.tgz",
|
||||
@@ -12116,6 +12160,15 @@
|
||||
"integrity": "sha512-yQA4H19AmPEoMUeavPMDIe1higySl/gH/yaQrkT/s07Qp+7pp2hYz30N3z2l5BkjVkF9Ow6o0wjJamm2y7Sn0A==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/pandemonium": {
|
||||
"version": "2.4.1",
|
||||
"resolved": "https://registry.npmjs.org/pandemonium/-/pandemonium-2.4.1.tgz",
|
||||
"integrity": "sha512-wRqjisUyiUfXowgm7MFH2rwJzKIr20rca5FsHXCMNm1W5YPP1hCtrZfgmQ62kP7OZ7Xt+cR858aB28lu5NX55g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"mnemonist": "^0.39.2"
|
||||
}
|
||||
},
|
||||
"node_modules/parent-module": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
|
||||
|
||||
Reference in New Issue
Block a user