问题
I found the time complexity of Prims algorithm everywhere as O((V + E) log V) = E log V. But as we can see the algorithm:
It seems like the time complexity is O(V(log V + E log V)). But if its time complexity is O((V + E) log V). Then the nesting must have to be like this:
But the above nesting is seems to be wrong.
回答1:
MST-PRIM(G, w, r)
1 for each u ∈ G.V
2 u.key ← ∞
3 u.π ← NIL
4 r.key ← 0
5 Q ← G.V
6 while Q ≠ Ø
7 u ← EXTRACT-MIN(Q)
8 for each v ∈ G.Adjacent[u]
9 if v ∈ Q and w(u, v) < v.key
10 v.π ← u
11 v.key ← w(u, v)
Using a Binary Heap
The time complexity required for one call to
EXTRACT-MIN(Q)
isO(log V)
using a min priority queue. The while loop at line 6 is executing total V times.soEXTRACT-MIN(Q)
is calledV
times. So the complexity ofEXTRACT-MIN(Q)
isO(V logV)
.The
for
loop at line 8 is executing total2E
times as length of each adjacency lists is2E
for an undirected graph. The time required to execute line 11 isO(log v)
by using theDECREASE_KEY
operation on the min heap. Line 11 also executes total2E
times. So the total time required to execute line 11 isO(2E logV) = O(E logV)
.The
for
loop at line 1 will be executedV
times. Using the procedure to perform lines 1 to 5 will require a complexity ofO(V)
.
Total time complexity of MST-PRIM
is the sum of the time complexity required to execute steps 1 through 3 for a total of O(VlogV + (E logV + V) = O(E logV)
.
Using a Fibonacci Heap
- Same as above.
- Executing line 11 requires
O(1)
amortized time. Line 11 executes a total of2E
times. So the total time complexity isO(E)
. - Same as above
So the total time complexity of MST-PRIM
is the sum of executing steps 1 through 3 for a total complexity of O(V logV + E + V)=O(E + V logV)
.
回答2:
Your idea seems correct. Let's take the complexity as
V(lg(v) + E(lg(v)))
Then notice that in the inner for loop, we are actually going through all the vertices, and not the edge, so let's modify a little to
V(lg(v) + V(lg(v)))
which means
V(lg(v)) + V*V(lg(v))
But for worst case analysis(dense graphs), V*V is roughly equal to number of edges, E
V(lg(v)) + E(lg(v))
(V+E((lg(v))
but since V << E
, hence
E(lg(v))
回答3:
The time complexity of Prim's algorithm is O(VlogV + ElogV). It seems like you understand how the VlogV
came to be, so let's skip over that. So where does ElogV
come from? Let's start by looking at Prim's algorithm's source code:
| MST-PRIM(Graph, weights, r)
1 | for each u ∈ Graph.V
2 | u.key ← ∞
3 | u.π ← NIL
4 | r.key ← 0
5 | Q ← Graph.V
6 | while Q ≠ Ø
7 | u ← EXTRACT-MIN(Q)
8 | for each v ∈ Graph.Adj[u]
9 | if v ∈ Q and weights(u, v) < v.key
10| v.π ← u
11| v.key ← weights(u, v)
Lines 8-11 are executed for every element in Q
, and we know that there are V
elements in Q
(representing the set of all vertices). Line 8's loop is iterating through all the neighbors of the currently extracted vertex; we will do the same for the next extracted vertex, and for the one after that. Djistkra's Algorithm does not repeat vertices (because it is a greedy, optimal algorithm), and will have us go through each of the connected vertices eventually, exploring all of their neighbors. In other words, this loop will end up going through all the edges of the graph twice at some point (2E
).
Why twice? Because at some point we come back to a previously explored edge from the other direction, and we can't rule it out until we've actually checked it. Fortunately, that constant 2
is dropped during our time complexity analysis, so the loop is really just doing E
amounts of work.
Why wasn't it V*V
? You might reach that term if you just consider that we have to check each Vertex and its neighbors, and in the worst case graph the number of neighbors approaches V
. Indeed, in a dense graph V*V = E
. But the more accurate description of the work of these two loops is "going through all the edges twice", so we refer to E
instead. It's up to the reader to connect how sparse their graph is with this term's time complexity.
Let's look at a small example graph with 4 vertices:
1--2
|\ |
| \|
3--4
Assume that Q
will give us the nodes in the order 1, 2, 3, and then 4.
- In the first iteration of the outer loop, the inner loop will run 3 times (for 2, 3, and 4).
- In the second iteration of the outer loop, the inner loop runs 2 times (for 1 and 4).
- In the third iteration of the outer loop, the inner loop runs 2 times (for 1 and 4).
- In the last iteration of the outer loop, the inner loop runs 3 times (for 1, 2, and 3).
The total iterations was 10, which is twice the number of edges (2*5
).
Extracting the minimum and tracking the updated minimum edges (usually done with a Fibonacci Heap, resulting in log(V)
time complexity) occurs inside the loop iterations - the exact mechanisms involve end up needing to occur inside the inner loop enough times that they are controlled by the time complexity of both loops. Therefore, the complete time complexity for this phase of the algorithm is O(2*E*log(V))
. Dropping the constant yields O(E*log(V))
.
Given that the total time complexity of the algorithm is O(VlogV + ElogV)
, we can simplify to O((V+E)logV)
. In a dense graph E > V
, so we can conclude O(ElogV)
.
回答4:
actually as you are saying as for is nested inside while time complexity should be v.E lg V is correct in case of asymptotic analysis. But in cormen they have done amortized analysis thats why it comes out to be (Elogv)
来源:https://stackoverflow.com/questions/20430740/time-complexity-of-prims-algorithm