Skip to content

Commit 39bd444

Browse files
committed
feat-prim_mst
1 parent feaa4f1 commit 39bd444

File tree

1 file changed

+88
-0
lines changed

1 file changed

+88
-0
lines changed
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# Prim's Minimum Spanning Tree Algorithm
2+
#
3+
# The Prim algorithm finds the Minimum Spanning Tree (MST) of a connected, undirected, weighted graph.
4+
# It starts from a source vertex and grows the MST by adding the smallest-weight edge connecting
5+
# the MST to a new vertex.
6+
#
7+
# Time Complexity: O(V^2) with adjacency matrix, can be O(E log V) with priority queue
8+
# Space Complexity: O(V)
9+
#
10+
# Input: graph as an adjacency list where each entry is a list of edges with fields
11+
# `vertex` and `weight`, and `source` vertex index (integer)
12+
# Output: A list containing MST edges, total weight
13+
14+
prim_mst <- function(graph, source = 1) {
15+
all_vertices <- unique(c(names(graph), unlist(lapply(graph, function(x) sapply(x, function(e) e$vertex)))))
16+
all_vertices <- as.numeric(all_vertices)
17+
num_vertices <- max(all_vertices)
18+
19+
in_mst <- rep(FALSE, num_vertices)
20+
key <- rep(Inf, num_vertices)
21+
parent <- rep(-1, num_vertices)
22+
23+
key[source] <- 0
24+
25+
for (i in 1:num_vertices) {
26+
# Pick the minimum key vertex not in MST
27+
u <- which.min(ifelse(in_mst, Inf, key))
28+
29+
in_mst[u] <- TRUE
30+
31+
# Update keys and parents for adjacent vertices
32+
for (edge in graph[[as.character(u)]]) {
33+
v <- edge$vertex
34+
w <- edge$weight
35+
if (!in_mst[v] && w < key[v]) {
36+
key[v] <- w
37+
parent[v] <- u
38+
}
39+
}
40+
}
41+
42+
# Build MST edges
43+
mst_edges <- list()
44+
total_weight <- 0
45+
for (v in 1:num_vertices) {
46+
if (parent[v] != -1) {
47+
mst_edges <- append(mst_edges, list(list(from = parent[v], to = v, weight = key[v])))
48+
total_weight <- total_weight + key[v]
49+
}
50+
}
51+
52+
return(list(
53+
edges = mst_edges,
54+
total_weight = total_weight
55+
))
56+
}
57+
58+
# Example usage
59+
cat("=== Prim's Minimum Spanning Tree Algorithm ===\n")
60+
61+
# Example undirected graph
62+
# Graph structure:
63+
# 1 --2--> 2
64+
# 1 --3--> 3
65+
# 2 --1--> 3
66+
# 2 --4--> 4
67+
# 3 --5--> 4
68+
prim_graph <- list(
69+
"1" = list(list(vertex = 2, weight = 2), list(vertex = 3, weight = 3)),
70+
"2" = list(list(vertex = 1, weight = 2), list(vertex = 3, weight = 1), list(vertex = 4, weight = 4)),
71+
"3" = list(list(vertex = 1, weight = 3), list(vertex = 2, weight = 1), list(vertex = 4, weight = 5)),
72+
"4" = list(list(vertex = 2, weight = 4), list(vertex = 3, weight = 5))
73+
)
74+
75+
cat("Graph (adjacency list):\n")
76+
for (v in names(prim_graph)) {
77+
edges <- prim_graph[[v]]
78+
edge_strs <- sapply(edges, function(e) paste0(e$vertex, "(", e$weight, ")"))
79+
cat("Vertex", v, "-> [", paste(edge_strs, collapse = ", "), "]\n")
80+
}
81+
82+
cat("\nRunning Prim's MST from vertex 1:\n")
83+
mst_result <- prim_mst(prim_graph, 1)
84+
cat("MST edges:\n")
85+
for (edge in mst_result$edges) {
86+
cat(edge$from, "--", edge$weight, "-->", edge$to, "\n")
87+
}
88+
cat("Total weight of MST:", mst_result$total_weight, "\n")

0 commit comments

Comments
 (0)