-
Notifications
You must be signed in to change notification settings - Fork 0
/
connected-components-undirected.R
65 lines (56 loc) · 1.7 KB
/
connected-components-undirected.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#
# Sami Hossain
# 04-22-2021
# Intuitive connected components algorithm for undirected edges
# using BFS
#############
### SETUP ###
#############
library(igraph)
nodes <- 20
graph <- erdos.renyi.game(nodes, 7*(nodes/10), type = "gnm", directed = F, loops = F)
plot(graph)
################
### ALGORITHM ##
################
visited <- c()
components <- list()
bfs <- function(verts) {
neighbors <- c()
for(i in verts) {
temp <- setdiff(which(graph[i,] != 0), visited) #all neighbors that havent been visited yet
neighbors <- c(neighbors, temp)
}
if(!is.null(neighbors)){
visited <<- c(visited, verts) #add current nodes to visited before recursing
bfs(neighbors)
}
}
for(i in 1:nodes){
if(!(i %in% visited)){
bfs(c(i))
if(length(components) == 0){
components[[1]] <- visited #to keep a running total on the visited nodes
components[[2]] <- visited
} else {
components[[length(components)+1]] <- setdiff(visited, components[[1]]) #diff between previous bfs's visited vector and curr
components[[1]] <- visited
}
}
}
components <- components[-1] #remove the running total
remove(i,visited)
################
### VISUALIZE ##
################
V(graph)$sets <- 0
for(i in 1:length(components)){
scc <- components[[i]]
for(j in 1:length(scc)){
V(graph)$sets[scc[j]] <- i #apply a value to each node uniquely referencing which scc it is in
}
}
remove(i,j,scc)
V(graph)$color <- rainbow(nodes)[V(graph)$sets] #assign distinct colors for each individual scc
plot(graph, mark.groups = split(1:nodes, V(graph)$sets))
print(paste0("there are: ", length(components), " connected components"))