From 78bb1ccc36df72bf4d72f13d3e061cca81777450 Mon Sep 17 00:00:00 2001 From: Shashmitha Date: Sat, 12 Oct 2024 22:37:59 +0530 Subject: [PATCH 1/5] Create README.md --- Algorithms_and_Data_Structures/Minimum Spanning Tree/README.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 Algorithms_and_Data_Structures/Minimum Spanning Tree/README.md diff --git a/Algorithms_and_Data_Structures/Minimum Spanning Tree/README.md b/Algorithms_and_Data_Structures/Minimum Spanning Tree/README.md new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/Algorithms_and_Data_Structures/Minimum Spanning Tree/README.md @@ -0,0 +1 @@ + From 225b8c1afef11cc3784934f9f35b8b1e2a708c39 Mon Sep 17 00:00:00 2001 From: Shashmitha Date: Sat, 12 Oct 2024 23:25:32 +0530 Subject: [PATCH 2/5] Update README.md --- .../Minimum Spanning Tree/README.md | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/Algorithms_and_Data_Structures/Minimum Spanning Tree/README.md b/Algorithms_and_Data_Structures/Minimum Spanning Tree/README.md index 8b13789179..97349a194d 100644 --- a/Algorithms_and_Data_Structures/Minimum Spanning Tree/README.md +++ b/Algorithms_and_Data_Structures/Minimum Spanning Tree/README.md @@ -1 +1,59 @@ +# Minimum Spanning Tree (MST) Algorithms +This project demonstrates three algorithms for finding the Minimum Spanning Tree (MST) in a graph. A Minimum Spanning Tree is a subgraph that connects all vertices with the minimum total edge weight, without any cycles. + +### Algorithms included: +- Prim's Algorithm +- Kruskal's Algorithm +- SciPy's Minimum Spanning Tree +## 1. Prim's Algorithm +**Description:** Prim’s algorithm grows the MST one edge at a time. It starts from an arbitrary vertex and adds the smallest edge connecting the growing MST to a new vertex. + +**How it works:** + - Begin with any node as the starting point. + - Repeatedly add the smallest edge connecting a visited node to an unvisited node. + - Stop when all vertices are included in the MST. + +**Time Complexity:** +- Using an adjacency matrix and a simple priority queue (heap), the time complexity is` O(V²)`, where V is the number of vertices. +- If using an adjacency list and a min-heap, the time complexity is `O(E log V)`, where E is the number of edges. +- Usage: Prim’s algorithm is efficient for dense graphs (many edges). It efficiently adds the next closest vertex to the existing tree. + +## 2. Kruskal's Algorithm +**Description:** Kruskal’s algorithm sorts all the edges by weight and builds the MST by adding the smallest edge, ensuring no cycles are formed. It uses a Union-Find data structure to detect cycles. + +**How it works:** +- Sort all edges by their weights. +- Pick the smallest edge and add it to the MST if it doesn’t form a cycle. +- Stop when the MST contains `V-1` edges (for a graph with V vertices). + +**Time Complexity:** +- O(E log E), which simplifies to O(E log V), since sorting the edges takes O(E log E) and each find and union operation in the Union-Find structure takes nearly constant time, `O(log*V)`. +- Usage: Kruskal’s algorithm is efficient for sparse graphs (few edges) and uses sorting and union-find to ensure efficiency. + +## 3. Minimum Spanning Tree using SciPy +**Description:** SciPy provides a built-in function to compute the Minimum Spanning Tree using the Compressed Sparse Row (CSR) matrix representation of a graph. + +**How it works:** +- The graph is represented as a sparse matrix, where non-zero entries represent edge weights. +- SciPy’s minimum_spanning_tree() function efficiently computes the MST. + +**Time Complexity:** +- For sparse graphs, using SciPy’s implementation, the time complexity is typically `O(E log V)`. +- Usage: This method is very efficient when working with large, sparse graphs. The sparse matrix format saves memory and speeds up computation. + +**Installation and Requirements**
+To run the algorithms, you will need: +- Python 3.x +- `SciPy` for the SciPy Minimum Spanning Tree + +To install SciPy, use: +``` python +pip install scipy +``` +## Conclusion +These three algorithms are fundamental for solving the Minimum Spanning Tree problem, each suited for different graph structures: + +1. Prim’s algorithm is ideal for dense graphs. +2. Kruskal’s algorithm works well for sparse graphs. +3. SciPy’s MST function is an efficient option for large, sparse graphs. From 6e83a5913e72eadd404ed50bf8a0e1d30248e539 Mon Sep 17 00:00:00 2001 From: Shashmitha Date: Sun, 13 Oct 2024 21:09:34 +0530 Subject: [PATCH 3/5] Add files via upload added kruskal's algorithm --- .../Kruskal's Algorithm.py | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 Algorithms_and_Data_Structures/Minimum Spanning Tree/Kruskal's Algorithm.py diff --git a/Algorithms_and_Data_Structures/Minimum Spanning Tree/Kruskal's Algorithm.py b/Algorithms_and_Data_Structures/Minimum Spanning Tree/Kruskal's Algorithm.py new file mode 100644 index 0000000000..316ed1074d --- /dev/null +++ b/Algorithms_and_Data_Structures/Minimum Spanning Tree/Kruskal's Algorithm.py @@ -0,0 +1,86 @@ +class Graph: + def __init__(self, vertices): + self.V = vertices + self.graph = [] + + # Function to add an edge to the graph + def addEdge(self, u, v, w): + self.graph.append([u, v, w]) + + # A function to find the subset of an element i (with path compression) + def find(self, parent, i): + if parent[i] != i: + parent[i] = self.find(parent, parent[i]) + return parent[i] + + # A function that does union of two subsets x and y (uses union by rank) + def union(self, parent, rank, x, y): + xroot = self.find(parent, x) + yroot = self.find(parent, y) + + # Attach smaller rank tree under root of higher rank tree + if rank[xroot] < rank[yroot]: + parent[xroot] = yroot + elif rank[xroot] > rank[yroot]: + parent[yroot] = xroot + else: + parent[yroot] = xroot + rank[xroot] += 1 + + # Function to construct MST using Kruskal's algorithm + def KruskalMST(self): + result = [] + + # Step 1: Sort all the edges in non-decreasing order of their weight + self.graph = sorted(self.graph, key=lambda item: item[2]) + + parent = [] + rank = [] + + # Create V subsets with single elements + for node in range(self.V): + parent.append(node) + rank.append(0) + + e = 0 # Number of edges in MST + i = 0 # Index variable used for sorted edges + + # Number of edges in MST will be V-1 + while e < self.V - 1: + + # Step 2: Pick the smallest edge and increment the index for next iteration + u, v, w = self.graph[i] + i += 1 + + x = self.find(parent, u) + y = self.find(parent, v) + + # If including this edge doesn't cause a cycle, include it in result + if x != y: + e += 1 + result.append([u, v, w]) + self.union(parent, rank, x, y) + + return result + +if __name__ == "__main__": + # Input number of vertices + V = int(input("Enter the number of vertices: ")) + g = Graph(V) + + # Input number of edges + E = int(input("Enter the number of edges: ")) + + # Input the edges + print("Enter the edges in the format 'u v w' where u and v are vertices, and w is the weight:") + for _ in range(E): + u, v, w = map(int, input().split()) + g.addEdge(u, v, w) + + # Get the Minimum Spanning Tree (MST) using Kruskal's algorithm + mst = g.KruskalMST() + + # Output the MST + print("Edges in the Minimum Spanning Tree:") + for u, v, weight in mst: + print(f"{u} -- {v} == {weight}") From f99daaec383b62ae16bb6c3c119458d0144a0361 Mon Sep 17 00:00:00 2001 From: Shashmitha Date: Sun, 13 Oct 2024 21:10:21 +0530 Subject: [PATCH 4/5] Add files via upload added algorithms --- ...im's Algorithm (using a priority queue).py | 59 +++++++++++++++++++ .../Minimum Spanning Tree/Using SciPy.py | 15 +++++ 2 files changed, 74 insertions(+) create mode 100644 Algorithms_and_Data_Structures/Minimum Spanning Tree/Prim's Algorithm (using a priority queue).py create mode 100644 Algorithms_and_Data_Structures/Minimum Spanning Tree/Using SciPy.py diff --git a/Algorithms_and_Data_Structures/Minimum Spanning Tree/Prim's Algorithm (using a priority queue).py b/Algorithms_and_Data_Structures/Minimum Spanning Tree/Prim's Algorithm (using a priority queue).py new file mode 100644 index 0000000000..08c1f1e677 --- /dev/null +++ b/Algorithms_and_Data_Structures/Minimum Spanning Tree/Prim's Algorithm (using a priority queue).py @@ -0,0 +1,59 @@ +import heapq +from collections import defaultdict + +class Graph: + def __init__(self, vertices): + self.V = vertices + self.graph = defaultdict(list) + + def addEdge(self, u, v, w): + # Adding edge (u, v) with weight w + self.graph[u].append((v, w)) + self.graph[v].append((u, w)) + + def PrimMST(self): + result = [] + # Set to keep track of visited vertices + visited = set() + # Priority queue to pick the edge with the smallest weight + pq = [(0, 0)] # (weight, vertex) + + while pq: + # Get the vertex with the smallest weight + weight, u = heapq.heappop(pq) + if u in visited: + continue + #Mark this vertex as visited + visited.add(u) + #Add the vertex and the weight to the result + result.append((u, weight)) + + #Traverse all the adjacent vertices of u + for v, w in self.graph[u]: + if v not in visited: + #Push adjacent vertices to the priority queue + heapq.heappush(pq, (w, v)) + + # Returning the MST result + return result + +if __name__ == "__main__": + # Take number of vertices as input + V = int(input("Enter the number of vertices in the graph: ")) + + g = Graph(V) + + # Take number of edges as input + E = int(input("Enter the number of edges in the graph: ")) + + # Input the edges (u, v, w) from the user + print("Enter the edges in the format 'u,v,w' where u and v are vertices and w is the weight:") + for _ in range(E): + u, v, w = map(int, input().split()) + g.addEdge(u, v, w) + + # Get the Minimum Spanning Tree (MST) + mst = g.PrimMST() + + # Output + print("Minimum Spanning Tree:", mst) diff --git a/Algorithms_and_Data_Structures/Minimum Spanning Tree/Using SciPy.py b/Algorithms_and_Data_Structures/Minimum Spanning Tree/Using SciPy.py new file mode 100644 index 0000000000..994994a642 --- /dev/null +++ b/Algorithms_and_Data_Structures/Minimum Spanning Tree/Using SciPy.py @@ -0,0 +1,15 @@ +from scipy.sparse import csr_matrix +from scipy.sparse.csgraph import minimum_spanning_tree + +# Create a sparse matrix representing the graph +graph = csr_matrix([[0, 2, 0, 6, 0], + [2, 0, 3, 8, 5], + [0, 3, 0, 0, 7], + [6, 8, 0, 0, 9], + [0, 5, 7, 9, 0]]) + +# Compute the MST +mst = minimum_spanning_tree(graph) + +# Print the MST +print(mst.toarray().astype(int)) \ No newline at end of file From 4eada7dbcbfde6b3cbd287b5374d26cae3646888 Mon Sep 17 00:00:00 2001 From: Shashmitha Date: Sun, 13 Oct 2024 21:11:14 +0530 Subject: [PATCH 5/5] Update README.md --- Algorithms_and_Data_Structures/Minimum Spanning Tree/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Algorithms_and_Data_Structures/Minimum Spanning Tree/README.md b/Algorithms_and_Data_Structures/Minimum Spanning Tree/README.md index 97349a194d..751d43e32f 100644 --- a/Algorithms_and_Data_Structures/Minimum Spanning Tree/README.md +++ b/Algorithms_and_Data_Structures/Minimum Spanning Tree/README.md @@ -42,7 +42,7 @@ This project demonstrates three algorithms for finding the Minimum Spanning Tree - For sparse graphs, using SciPy’s implementation, the time complexity is typically `O(E log V)`. - Usage: This method is very efficient when working with large, sparse graphs. The sparse matrix format saves memory and speeds up computation. -**Installation and Requirements**
+### **Installation and Requirements**
To run the algorithms, you will need: - Python 3.x - `SciPy` for the SciPy Minimum Spanning Tree