Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Complexity of Prims Algorithm using Priority Queue?

I am using an adjacency matrix, priority queue is the data structure.

By my calculation, complexity is V^3 log V:

  • While loop: V
  • Checking adjacent Vertices: V
  • Checking the queue if the entry is already present, and updating the same: V log v

But, I read everywhere that the complexity is V^2

Please explain.

like image 592
Sachin Hadalgi Avatar asked Nov 25 '12 23:11

Sachin Hadalgi


People also ask

What is the time complexity of Prim's algorithm?

The time complexity is O(VlogV + ElogV) = O(ElogV), making it the same as Kruskal's algorithm. However, Prim's algorithm can be improved using Fibonacci Heaps (cf Cormen) to O(E + logV).

Does Prim's algorithm using priority queue?

Prim's algorithm is similar to Dijkstra's algorithm in that they both use a priority queue to select the next vertex to add to the growing graph.

What is time complexity of priority queue?

Generally, The time complexity of insertion in the priority queue in C++ is O ( l o g n ) O(log n) O(logn).

What is the time complexity to extract a vertex from the priority queue in Prim's algorithm?

Therefore the complexity is O(V*V) = O(V^2).


2 Answers

If you use a Fibonacci heap, then extracting the min is O(lg V) amortized cost and updating an entry in it is O(1) amortized.

If we use this pseudo code

while priorityQueue not empty
    u = priorityQueue.exractMin()
    for each v in u.adjacencies
        if priorityQueue.contains(v) and needsWeightReduction(u, v)
            priorityQueue.updateKeyWeight(u, v)

Assume that the implementation has constant time for both priorityQueue.contains(v) and needsWeightReduction(u, v).

Something to note is that you can bound slightly tighter for checking adjacencies. While the outer loop runs V times, and checking the adjacencies of any single node is at worst V operations, you can use aggregate analysis to realize that you will never check for more than E adjacencies(because theres only E edges). And E <= V^2, so this is a slightly better bound.

So, you have the outer loop V times, and the inner loop E times. Extracting the min runs V times, and updating an entry in the heap runs E times.

  V*lgV + E*1
= O(V lgV + E)

Again, since E <= V^2 you could use this fact to substitute and get

  O(V lgV + V^2)
= O(V^2)

But this is a looser bound when considering sparse graphs(although correct).

like image 122
goat Avatar answered Sep 29 '22 22:09

goat


Using a min heap-based priority queue, the time complexity is O(ElogV).

As you said, the outer while loop is O(V) because it is looping through every vertex since each one needs to be added to the MST once.

For each vertex considered in the while loop, the following two steps need to happen:

  1. The next edge is chosen to add to the MST. According to the properties of a min heap-based priority queue, the root element will always be the smallest element. Therefore choosing the next edge, the one with the lowest cost, will be an O(1) extraction of the root element. The remaining values will need to be shifted after the extraction in a way that maintains the priority queue. Since the queue represents a balanced binary tree, this shift can happen in O(logV) in the worst case.

  2. The priority queue is updated. Edges incident to the new vertex may need to have their costs updated in the queue because we will now consider the costs associated with the edges between the newly added vertex and its neighbors (however, if they neighbored a previously added vertex through an edge with a lower cost than the newly introduced edge, the cost will not be updated because we are looking for the minimum costs). Again this will be O(logV) because in the worst case, a vertex will need to be shifted through the entire length of the balanced binary tree that represents the queue.

Step 1 happens V times because it occurs once in the while loop, so it is O(VlogV) total, and step 2 happens E times in the worst case where every edge is attached to the current vertex and therefore they all need to be updated, which means it is O(ElogV) total. The set-up is O(E) because it requires initializing each edge cost in the priority queue to be infinity.

Total time complexity using a min heap based priroty queue = O(E + VlogV + ElogV) = O(ElogV)

When you’re reading that the complexity is O(V^2), you might be looking at implementations that don’t use heaps. In this case, the outer while loop is still O(V). The bottleneck is in the step that chooses the next vertex to add to the MST, which is O(V) because you’ll need to check the cost associated every neighboring node to find the lowest cost, which in the worst case means checking all other nodes. Therefore the complexity is O(V*V) = O(V^2).

Additionally, O(ElogV) in very dense graphs becomes O(V^2) because in any graph there can be a maximum of E = V^2 total edges.

like image 21
Kamala Avatar answered Sep 29 '22 20:09

Kamala