Graphs Algorithm
Boruvka's Algorithm

Boruvka's Algorithm

Boruvka's Algorithm is a greedy algorithm used to find the minimum spanning tree (MST) of a connected, undirected graph. The algorithm works by merging the components of the graph and selecting the minimum-weight edges that connect these components. Boruvka's Algorithm was one of the earliest algorithms to find the MST.

How Boruvka's Algorithm Works

  1. Initialization:

    • Start with each vertex as a separate component in the forest of the MST.
  2. Phase 1: Components and Minimum Edges:

    • For each component, select the minimum-weight edge incident to each component.
    • Merge the components connected by these selected edges.
  3. Repeat Merging:

    • Repeat the phase until there's only one component left.
  4. Completion:

    • The final one-component graph is the Minimum Spanning Tree.

Key Features

  • Greedy Approach: Boruvka's Algorithm makes locally optimal choices to build a globally optimal solution.

  • Minimum Spanning Tree: It finds the MST, ensuring the least possible total edge weight to connect all vertices.

Efficiency

  • Time Complexity: The time complexity of Boruvka's Algorithm is O(E log V), where E is the number of edges and V is the number of vertices.

  • Space Complexity: The space complexity depends on the data structures used. In the worst case, it can be O(E + V).

Applications

  • Network Design: Boruvka's Algorithm is used in network design for laying down minimum-length electrical wires or connecting a set of houses with minimal cost.

  • Clustering: It can be applied in clustering problems, like partitioning data points into clusters while minimizing the total inter-cluster distance.

  • MST Construction: Boruvka's Algorithm is used to find MSTs in various applications, including computer networks and geographic information systems.

Limitations

  • Sensitivity to Edge Weights: The algorithm's performance can vary based on the choice of edge weights. Different edge weight assignments can result in different minimum spanning trees.

  • Must Be Connected: Boruvka's Algorithm requires the graph to be connected. If the graph has disconnected components, it needs to be run separately on each component.

  • High Time Complexity: While relatively efficient, Boruvka's Algorithm might not be the best choice for extremely large graphs.

Boruvka's Algorithm Implementation in JavaScript

Here's an example of Boruvka's Algorithm implemented in JavaScript:

Graphs/brks.js
class Graph {
    constructor() {
        this.vertices = [];
        this.edges = [];
    }
 
    addVertex(vertex) {
        this.vertices.push(vertex);
    }
 
    addEdge(vertex1, vertex2, weight) {
        this.edges.push({ vertex1, vertex2, weight });
    }
 
    boruvkaMST() {
        const mst = [];
        let numVertices = this.vertices.length;
 
        while (numVertices > 1) {
            let closestEdges = Array(numVertices).fill(null);
 
            for (const edge of this.edges) {
                const root1 = this.findRoot(edge.vertex1);
                const root2 = this.findRoot(edge.vertex2);
 
                if (root1 !== root2) {
                    if (closestEdges[root1] === null || edge.weight < closestEdges[root1].weight) {
                        closestEdges[root1] = edge;
                    }
                    if (closestEdges[root2] === null || edge.weight < closestEdges[root2].weight) {
                        closestEdges[root2] = edge;
                    }
                }
            }
 
            for (let i = 0; i < numVertices; i++) {
                if (closestEdges[i] !== null) {
                    const root1 = this.findRoot(closestEdges[i].vertex1);
                    const root2 = this.findRoot(closestEdges[i].vertex2);
 
                    if (root1 !== root2) {
                        mst.push(closestEdges[i]);
                        this.union(root1, root2);
                        numVertices--;
                    }
                }
            }
        }
 
        return mst;
    }
 
    findRoot(vertex) {
        if (this.vertices.includes(vertex)) return vertex;
        return this.findRoot(this.vertices[vertex]);
    }
 
    union(root1, root2) {
        this.vertices[root2] = root1;
    }
}
 
// Example usage
const graph = new Graph();
const vertices = ["A", "B", "C", "D", "E"];
vertices.forEach((vertex) => graph.addVertex(vertex));
 
graph.addEdge("A", "B", 2);
graph.addEdge("A", "C", 3);
graph.addEdge("B", "C", 1);
graph.addEdge("B", "D", 1);
graph.addEdge("C", "D", 1);
graph.addEdge("C", "E", 4);
graph.addEdge("D", "E", 2);
 
const mst = graph.boruvkaMST();
console.log("Minimum Spanning Tree (MST):", mst);