Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prims added #11

Merged
merged 1 commit into from
Oct 30, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 108 additions & 0 deletions graph/prims/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# Prim's Alogrithm for Minimum Spanning Tree

A Minimum Spanning Tree is a tree that include all the vertex of a graph such that the total sum of all the edges are minimized. Prims alogorithm suggest a greedy approach for this where we select the minimum weighted edge of all the possible edges.

Let's take a look at the below example to understand it even better

Suppose we have a graph as described below
```

0 -------[4]----------- 1 -----[8]------ 2
| |
| |
[8] -- [7] -------- 5 ------[2]-----|
| / |
| / [6]
| / |
3 ------[1]-------- 4 ---|
```

it can be summarized as
```
Vertex From Vertex To Weight
0 1 4
0 3 8
1 2 8
2 5 2
3 4 1
4 5 6
5 3 7

```

Our Aim is to find the Minimum Spanning Tree From this Graph.
First we will start from the vertex 0 and add it to our MST. Vertex 0 connects to 1 and 3 with weights 4 and 8 respectively. We need to select the minimum weighted edge. Since edge to the vertex 1 has lower weight we will add vertex 1 to out MST.
```

0 -------[4]-------- 1

current MST. total weight 4
```

Now we have two vertex in our MST (0 and 1). We will first check all the edges going from 0 and select the minimum. Here 0 connects to vertex 3 with edge of weight 0 and with 1 but we will not consider 1 as its already in minimum spanning tree. We have one edge from 0 and this will be the minimum edge from vertex 0. We will repeat this for vertex 1 as well. Vertex 1 connects to vertex 0 and vertex 2. We won't consider 0 as its already in the minimum spanning tree, so let's go to the vertex 2 . the edge weight here is also 8. So now we have following scenario
```
vertex A vertex B weight
0 3 8
1 2 8
```
We need to select the minimum out of these edges. Since, these have same weights, we can take any. Let's choose (0-3)[8] and add it to our MST.

Lets have a look at our updated MST .
```

0 -------[4]------- 1
|
[8]
|
3
Total Weight : 12
```

Let's Repeat the above process, we have now 3, 1 and 0 vertices in MST. We will check all the vertex that connects to them and are not already in the MST. We can see 0 is exhausted, we have visited all the vertex that it connects to. So, we have to do comparison between 1 and 3. After selecting minimum edges that connects both of the vertex to an unvisited vertex we will get following edges.
```
vertex A vertex B weight
1 2 8
3 4 1

see here 3 also connects with 5 but the weight is 7 so out of (3-5[7] and 3-4[1]) minimum is 3-4 which has weight 1.
```
Out of them the minimum edge is 3-4 having weight 1 so we add it to our MST

```
0 -------[4]----------- 1
|
|
[8]
|
|
3 ------[1]-------- 4
Total Weight : 13
```

Similarly try implementing the above step on vertices and in the end when all the vertices are visited we will have the following Minimum Spanning Tree.
```
0 -------[4]----------- 1 2
| |
| |
[8] 5 ------[2]-----|
| |
| [6]
| |
3 ------[1]------ 4 -----|

Total Weight : 21
```
Thus we have obtained out Minimum Spanning Tree.

## Algorithm
The Prims algorithm suggests a greedy method to select the Minimum Spanning Tree. The concept is simple, choose the minimum weighted edge of the remaining edges that can connect to one of the vertices already added in MST.

we can create a minimum spanning tree by following algorithm steps :

1. Maintain Visited array and mark it as false for all the vertices intially. basically it is used to track the vertex that are already added to the MST.
2. First We will select first vertex and make it visited.
3. While all the vertex are not added to the MST we do :
a. Get already visited vertices(visited[i]==true) and select all the edges that connects it to the adjacent vertices that are not visited yet . out of all those edges select the minimum. Repeat this for all the visited vertices.
b. After step 'a' we will have some edges, take the minimum edge out of them and add it to our MST.
c. Mark the vertex that the edge connects to as visited.
4. We have got ourself a MST.
128 changes: 128 additions & 0 deletions graph/prims/prims.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
package graph

import (
"fmt"
)

//======================================== Graph Structure Implementation starts========================================//

//Edge => an edge struct which represent a edge from vertex A to vertex B having X Weight
type Edge struct {
From int
To int
Weight int
}

//Graph => graph data structure
type Graph struct {
vertices int
edges [][]Edge
}

//Initialize => initializes the graph
func (g *Graph) Initialize(vertices int) {

//set the vertices we have
g.vertices = vertices

// initialize the vertices
if g.edges == nil {
g.edges = make([][]Edge, vertices)
}

//initialize each vertex as an empty array
for i := 0; i < vertices; i++ {
g.edges[i] = []Edge{}
}
}

//AddEdge => weighted edge add
func (g *Graph) AddEdge(u int, v int, w int) {
currEdge := Edge{u, v, w}

//for undirected graph both should have the entry
currEdgeU := Edge{v, u, w}

//set the v is reachabe from u
g.edges[u] = append(g.edges[u], currEdge)
g.edges[v] = append(g.edges[v], currEdgeU)

}

//Print the graph to see the Adjacency List
func (g *Graph) Print() {

for i := range g.edges {
fmt.Printf("%v\n", g.edges[i])
}

}

//========================================= Graph Implementation Ends Here =======================================//

func getMinimum(arr []Edge, visited []bool) Edge {

min := 99999
//default value
minIdx := Edge{0, 0, 99999}
for i := range arr {
if arr[i].Weight < min && visited[arr[i].To] == false {

minIdx = arr[i]
min = arr[i].Weight
}
}
return minIdx
}

/** PrimsAlgorithm
The prims Algoeithm selects the minimum spanning tree from a graph based on a greed approach the algorithm is as Follows
1. Select The starting edge.
2. Set the node as first node then choose the next minimum which is also connected to current selected nodes.
3. repeat until all vertices are included
**/
func PrimsAlgorithm(g Graph, verbose bool) {

var MST []Edge
visited := make([]bool, g.vertices)
totalEdges := g.vertices - 1

//set the 0 as visited node
visited[0] = true

//In end we want total vertex - 1 edges to connect all the vertex so running a for loop for that
for i := 0; i < totalEdges; i++ {

//Now we will select the minimum edge among all the edges that are connected to current selected vertices based on greedy approach
//for that we will check all the edges that are connected to visited node.
//then we will choose the minimum among them
fmt.Printf("\tCurrently visiting edge %v \n", i)

//this variable will hold the value of the minimum edge in the current iteration
var curEdges []Edge
for idx := range visited {

//we explore the edges of only those vertex tha are already visited
if visited[idx] == true {

//get the minimum weight edge among the edges that originated from the current vertex
minEdge := getMinimum(g.edges[idx], visited)

//append this in the current set of minimum edges
curEdges = append(curEdges, minEdge)
}
}

//out of all the minimum edges from all the vertices choose one which is minimum among them
minEdge := getMinimum(curEdges, visited)
fmt.Printf("\tFound MinEdge %v \n\n\n ", minEdge)

//append that to the Minimum spanning tree
MST = append(MST, minEdge)
visited[minEdge.To] = true

}
fmt.Println("PRINTING THE MST")
fmt.Println(MST)

}
21 changes: 21 additions & 0 deletions graph/prims/prims_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package graph

import (
"testing"
)

func TestGraph(t *testing.T) {
var graph = Graph{}
graph.Initialize(6)
graph.AddEdge(0, 1, 4)
graph.AddEdge(0, 3, 8)
graph.AddEdge(3, 4, 1)
graph.AddEdge(3, 5, 7)
graph.AddEdge(4, 5, 6)
graph.AddEdge(2, 5, 2)
graph.AddEdge(1, 3, 11)
graph.AddEdge(1, 2, 8)
graph.Print()
PrimsAlgorithm(graph)

}