Skip to content

Commit 0cc66ea

Browse files
committed
feat-louvain_community_detection
1 parent 834142d commit 0cc66ea

File tree

1 file changed

+84
-0
lines changed

1 file changed

+84
-0
lines changed
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# Louvain Method for Community Detection
2+
#
3+
# Detects communities (clusters) in a weighted or unweighted undirected graph.
4+
# It optimizes modularity by iteratively merging nodes into communities
5+
# to maximize modularity gain.
6+
7+
louvain_community <- function(graph, max_iter = 100) {
8+
num_vertices <- max(as.numeric(names(graph)))
9+
community <- 1:num_vertices
10+
11+
modularity <- function(graph, community) {
12+
m <- 0
13+
e_in <- 0
14+
deg <- rep(0, length(graph))
15+
16+
for (i in names(graph)) {
17+
deg[i] <- sum(graph[[i]])
18+
m <- m + sum(graph[[i]])
19+
}
20+
m <- m / 2
21+
22+
for (i in names(graph)) {
23+
for (j in graph[[i]]) {
24+
if (community[as.numeric(i)] == community[j]) {
25+
e_in <- e_in + 1
26+
}
27+
}
28+
}
29+
e_in <- e_in / 2
30+
Q <- e_in / m - sum(sapply(unique(community), function(c) {
31+
sum(deg[community == c]) / (2*m)
32+
})^2)
33+
return(Q)
34+
}
35+
36+
for (iter in 1:max_iter) {
37+
changed <- FALSE
38+
for (i in 1:num_vertices) {
39+
best_comm <- community[i]
40+
best_gain <- 0
41+
comms <- unique(community)
42+
for (c in comms) {
43+
temp_comm <- community
44+
temp_comm[i] <- c
45+
gain <- modularity(graph, temp_comm) - modularity(graph, community)
46+
if (gain > best_gain) {
47+
best_gain <- gain
48+
best_comm <- c
49+
}
50+
}
51+
if (community[i] != best_comm) {
52+
community[i] <- best_comm
53+
changed <- TRUE
54+
}
55+
}
56+
if (!changed) break
57+
}
58+
59+
return(community)
60+
}
61+
62+
# Example usage
63+
cat("=== Louvain Method for Community Detection ===\n")
64+
65+
# Example undirected graph as adjacency list
66+
# 1-2, 1-3, 2-3, 2-4, 3-4, 4-5
67+
louvain_graph <- list(
68+
"1" = c(2,3),
69+
"2" = c(1,3,4),
70+
"3" = c(1,2,4),
71+
"4" = c(2,3,5),
72+
"5" = c(4)
73+
)
74+
75+
cat("Graph (adjacency list):\n")
76+
for (v in names(louvain_graph)) {
77+
cat("Vertex", v, "-> [", paste(louvain_graph[[v]], collapse = ", "), "]\n")
78+
}
79+
80+
cat("\nDetecting communities:\n")
81+
communities <- louvain_community(louvain_graph)
82+
for (i in 1:length(communities)) {
83+
cat("Vertex", i, "-> Community", communities[i], "\n")
84+
}

0 commit comments

Comments
 (0)