Professional Documents
Culture Documents
Submitted to:Mr. Neeraj Kumar Professor (CS & E Department) Submitted on:20-Nov-2011
Prims Algorithm:Prim's algorithm is a greedy algorithm that finds a minimum spanning tree for a connected weighted undirected graph.
Theory & concept:Prims algorithm was developed in 1930 by Czech mathematician Vojtech Jarnk and later independently by computer scientist Robert C. Prim in 1957 and rediscovered by Edsger Dijkstra in 1959. Therefore it is also sometimes called the DJP algorithm, The Jarnik algorithm, or the PrimJarnik algorithm. Prim's algorithm is a greedy algorithm that finds a minimum spanning tree for a connected weighted undirected graph. Prims algorithm continuously increases the size of a Minimum spanning tree, one edge at a time, starting with a tree consisting of a single vertex, until it spans all vertices.
Input: A non-empty connected weighted graph with vertices V and edges E . Initialize: Vnew = {x}, where x is an arbitrary node (starting point) from V, Enew = {} Repeat until Vnew = V:
Choose an edge (u, v) with minimal weight such that u is in Vnew and v is not. if there are multiple edges with the same weight, any of them may be picked.
Add v to Vnew, and (u, v) to Enew Output: Vnew and Enew describe a minimal spanning tree.
MST-PRIM(V, E,w, r )
Q{} for each u in V do key[u] [u] NIL INSERT(Q, u) DECREASE-KEY(Q, r, 0) key[r ] 0 while Q is not empty do u EXTRACT-MIN(Q) for each v in Adj[u] do if v in Q and w(u, v) < key[v] then [v] u DECREASE-KEY(Q, v, w(u, v))
Prims Algorith Example :This is our original weighted graph. The numbers near the edges indicate their weight. Now will find MST using Prims Algorithm :-
Solution :Vertex D has been arbitrarily chosen as a starting point. Vertices A, B, E and F are connected to D through a single edge. A is the vertex nearest to D and will be chosen as the second vertex along with the edge AD.
The next vertex chosen is the vertex nearest to either D or A. B is 9 away from D and 7 away from A, E is 15, and F is 6. F is the smallest distance away, so we highlight the vertex F and the arc DF.
In this case, we can choose between C, E, and G. C is 8 away from B, E is 7 away from B, and G is 11 away from F. E is nearest, so we highlight the vertex E and the arc BE.
Here, the only vertices available are C and G. C is 5 away from E, and G is 9 away from E. C is chosen, so it is highlighted along with the arc EC.
Vertex G is the only remaining vertex. It is 11 away from F, and 9 away from E. E is nearer, so we highlight it and the arc EG.
Now all the vertices have been selected and the minimum spanning tree is shown in green. In this case, it has weight 39.
Edge(u,v)
V\U
{}
{A,B,C,D,E,F,G}
{D}
{A,B,C,E,F,G}
{A,D}
{B,C,E,F,G}
{A,D,F}
{B,C,E,G}
{A,B,D,F}
{C,E,G}
{A,B,D,E,F}
(B,C) = 8 (D,B) = 9 cycle (D,E) = 15 cycle (E,C) = 5 V (E,G) = 9 (F,E) = 8 cycle (F,G) = 11
{C,G}
{A,B,C,D,E,F}
(B,C) = 8 cycle (D,B) = 9 cycle (D,E) = 15 cycle (E,G) = 9 V (F,E) = 8 cycle (F,G) = 11
{G}
{A,B,C,D,E,F,G}
(B,C) = 8 cycle (D,B) = 9 cycle (D,E) = 15 cycle (F,E) = 8 cycle (F,G) = 11 cycle
{}
Analysis of Prims algorithm:The performance of Prim's algorithm depends on how the priority queue is implemented: Suppose Q is a binary heap. Initialize Q and first for loop: O(V lg V) Decrease key of r : O(lg V) while loop: |V| EXTRACT-MIN calls O(V lg V) |E| DECREASE-KEY calls implies that O(E lg V) Total:
O(E lg V)
Suppose we could do DECREASE-KEY in O(1) amortized time. Then |E| DECREASE-KEY calls take O(E) time altogether total time becomes O(V lg V + E). When a Q is implemented as a binary heap:The total time for prim's algorithm using a binary heap is O(|V| lg| V| + |E| lg |V|).
When Q is implemented as a Fibonacci heap:The total time for prim's algorithm using a Fibonacci heap to implement the priority queue Q is O(|V| lg |V| + |E|).
Fibonacci-heap implementation will not make prim's algorithm asymptotically faster for sparse graph.
return 0; } void buildtree() { int i=0,j,count=0; int min,k,v1=0,v2=0; closed[0]=0; while(count<n-1) { min=INF; for(i=0;i<=count;i++) for(j=0;j<n;j++) if(wght[closed[i]][j]<min && !inclose(j,count)) { min=wght[closed[i]][j]; v1=closed[i]; v2=j; } new_wght[v1][v2]=new_wght[v2][v1]=min; count++; closed[count]=v2; printf("\nScan : %d %d---------%d wght = %d \n",count,v1+1,v2+1,min); getch(); } } void main() { int i,j,ed,sum=0; clrscr();
printf("\n\n\tPRIM'S ALGORITHM TO FIND SPANNING TREE\n\n"); printf("\n\tEnter the No. of Nodes : "); scanf("%d",&n); for(i=0;i<n;i++) { vertex[i]=i+1; for(j=0;j<n;j++) { wght[i][j]=INF; new_wght[i][j]=INF; } } printf("\n\nGetting Weight.\n"); printf("\n\tEnter 0 if path doesn't exist between {v1,v2} else enter the wght\n"); for(i=0;i<n;i++) for(j=i+1;j<n;j++) { printf("\n\t%d -------- %d : ",vertex[i],vertex[j]); scanf("%d",&ed); if(ed>=1) wght[i][j]=wght[j][i]=ed; } getch(); clrscr(); printf("\n\n\t\tNODES CURRENTLY ADDED TO SPANNING TREE\n\n"); buildtree(); printf("\n\n\t\tMINIMUM SPANNING TREE\n\n");
printf("\n\t\tLIST OF EDGES\n\n"); for(i=0;i<n;i++) for(j=i+1;j<n;j++) if(new_wght[i][j]!=INF) { printf("\n\t\t%d ------ %d = %d ",vertex[i],vertex[j],new_wght[i][j]); sum+=new_wght[i][j]; } printf("\n\n\t Total Weight : %d ",sum); getch(); }
Output:PRIM'S ALGORITHM TO FIND SPANNING TREE Enter the No. of Nodes : 7 Getting Weight. Enter 0 if path doesn't exist between {v1,v2} else enter the wght 1 -------- 2 : 7 1 -------- 3 : 0 1 -------- 4 : 5 1 -------- 5 : 0 1 -------- 6 : 0 1 -------- 7 : 0 2 -------- 3 : 8 2 -------- 4 : 9 2 -------- 5 : 7 2 -------- 6 : 0 2 -------- 7 : 0
3 -------- 4 : 0 3 -------- 5 : 5 3 -------- 6 : 0 3 -------- 7 : 0 4 -------- 5 : 15 4 -------- 6 : 6 4 -------- 7 : 0 5 -------- 6 : 8 5 -------- 7 : 9 6 -------- 7 : 11 NODES CURRENTLY ADDED TO SPANNING TREE Scan : 1 1---------4 wght = 5 Scan : 2 4---------6 wght = 6 Scan : 3 1---------2 wght = 7 Scan : 4 2---------5 wght = 7 Scan : 5 5---------3 wght = 5 Scan : 6 5---------7 wght = 9 MINIMUM SPANNING TREE LIST OF EDGES 1 ------ 2 = 7 1 ------ 4 = 5 2 ------ 5 = 7 3 ------ 5 = 5 4 ------ 6 = 6 5 ------ 7 = 9 Total Weight : 39
Kruskals Algorithm:-
Kruskal's algorithm is a greedy algorithm that finds a minimum spanning tree fora connectedweighted graph. This means it finds a subset of the edges thatforms a tree that includes every vertex, where the total weight of all theedges in the tree is minimized. It finds a safe edge to add to the growing forest by finding, of all edges that connect any two tree in the forest ,an edge (u,v).
kruskal Algorithm & its Analysis:MST-KRUSKAL(G, w) A for each vertex v V[G] do MAKE-SET(v) sort the edges of E into nondecreasing order by weight w for each edge (u, v) E, taken in nondecreasing order by weight do if FIND-SET(u) FIND-SET(v) then A A U {(u, v)} UNION(u, v) return A
kruskals Algorith Example :-This is our original weighted graph. The numbers near the edges indicate their weight.
Solution: AD and CE are the shortest arcs, with length 5, and AD has been arbitrarily chosen, so it is highlighted.
CE is now the shortest arc that does not form a cycle, with length 5, so it is highlighted as the second arc.
The next arc, DF with length 6, is highlighted using much the same method.
The next-shortest arcs are AB and BE, both with length 7. AB is chosen arbitrarily, and is highlighted. The arc BD has been highlighted in red, because there already exists a path (in green) between B and D, so it would form a cycle (ABD) if it were chosen.
The process continues to highlight the next-smallest arc, BE with length 7. Many more arcs are highlighted in red at this stage: BC
because it would form the loop BCE, DE because it would form the loop DEBA, and FE because it would form FEBAD.
Finally, the process finishes with the arc EG of length 9, and the minimum spanning tree is found.
Analysis:-
Initialize the set A: First for loop: Sort E: Second for loop:
Assuming the implementation of disjoint-set data structure, that uses union by rank and path compression: O((V + E) (V)) + O(E lg E) Since G is connected, |E| |V| 1 O(E (V)) + O(E lg E). (|V|) = O(lg V) = O(lg E). Therefore, Total time is O(E lg E).
Therefore, O(E lg V) time. (If edges are already sorted, O(E (V)), which is almost linear.)
Algorithm Implementation C Program:#include<stdio.h> #define INF 1000 char vertex[10]; int wght[10][10]; int span_wght[10][10]; int source; struct Sort { int v1,v2; int weight; }que[20]; int n,ed,f,r;
int cycle(int s,int d) { int j,k; if(source==d) return 1; for(j=0;j<n;j++) if(span_wght[d][j]!=INF && s!=j) { if(cycle(d,j)) return 1; } return 0; } void build_tree() { int i,j,w,k,count=0; for(count=0;count<n;f++) { i=que[f].v1; j=que[f].v2; w=que[f].weight; span_wght[i][j]=span_wght[j][i]=w; source=i; k=cycle(i,j); if(k) span_wght[i][j]=span_wght[j][i]=INF; else count++; } } void swap(int *i,int *j) { int t; t=*i; *i=*j; *j=t; } void main() {
int i,j,k=0,temp; int sum=0; clrscr(); printf("\n\n\tKRUSKAL'S ALGORITHM TO FIND SPANNING TREE\n\n"); printf("\n\tEnter the No. of Nodes : "); scanf("%d",&n); for(i=0;i<n;i++) { printf("\n\tEnter %d value : ",i+1); fflush(stdin); scanf("%c",&vertex[i]); for(j=0;j<n;j++) {