Clarkson's 2-approximation Weighted Vertex Cover Algorithm Runtime analysis - algorithm

A well-known 2-approximation for a Minimum Weighted Vertex Cover Problem is the one proposed by Clarkson:
Clarkson, Kenneth L. "A modification of the greedy algorithm for vertex cover." Information Processing Letters 16.1 (1983): 23-25.
Easy-to-read pseudo code of the algorithm can be found here see section 32.1.2.
The algorithm, according to the paper, has a runtime complexity of O(|E|*log|V|) where E is the set of edges and V the set of vertices. I'm not entirely sure how they get this result.
Let d(v) be the degree of vertex v in a graph, and w(v) be some weight function.
Excluding some of the technicalities from the algorithm, the algorithm looks like this:
while( |E| != 0){ //While there are still edges in the graph
Pick a vertex v \in V for which w(v)/d(v) is minimized;
for( u : (u,v) \in E){
update w(u);
...
}
delete v and all edges incident to it from the graph.
}
The outer loop produces the term |E| in the runtime complexity. That means that picking a vertex out of a list of vertices which minimizes some ratio can be done in log n time. As far as I can tell, finding a minimum value out of a list of values takes n-1 comparisons, not log n. Finally, the inner for loop runs for every neighbor of v, so yields a complexity of d(v) which is dominated by n-1. Hence I would conclude that the algorithm has a runtime complexity of O(|E|*|V|).
What am I missing here?

Keep the vertices in a balanced binary search tree ordered by w(v)/d(v). Finding the min is O(log |V|). Each time we delete an edge uv, we have to update u's key (by removing it and reinserting it into the tree with the new key), which takes time O(log |V|). Each of these steps is done at most |E| times.

Related

Can I detect a cycle in an undirected graph with n edges in O(n log*(n)) ? ( log*(n) is log star function )

I have the following algorithm for detecting a cycle in an undirected graph with a set E of n edges :
for each unvisited edge (u, v) in E:
{
if(Find(u) = Find(v)) // u and v belong to the same set already
{
print "Cycle Detected";
break;
}
else
{
Union(u, v); // put u and v in the same set
}
}
my question is can I implement the union-find by size and path compression method and then claim that the time complexity of the code is O(n log*(n)) worst case?
Assuming you have a connected graph, this algorithm will run in O(n log*(n)) time in the worst case. (In fact, it will even run in O(n α(n)), where α(n) is the extremely slow-growing inverse of the Ackermann function.) If you have a very small number of edges, though, this is not generally true. For instance, consider a graph with n^2 vertices and n edges: even initializing the union-find data structure will take O(n^2) time. If this case matters to you, you could use coordinate compression or implement the union-find structure using hash tables so you only have to deal with vertices present in at least one edge. This will run in O(n α(n)) for any graph.

very hard and elegant question on shortest path

Given a weighed, connected and directed graph G=(V,E) with n vertexes and m edges, and given a pre-calculated shortest path distance's matrix S where S is n*n S(i,j) denotes the weight of shortest path from vertex i to vertex j.
we know just weight of one edge (u, v) is changed (increased or decreased).
for two specific vertex s and t we want to update the shortest path length between these two vertex.
This can be done in O(1).
How is this possible? what is the trick of this answer?
You certainly can for decreases. I assume S will always refer to the old distances. Let l be the new distance between (u, v). Check if
S(s, u) + l + S(v, t) < S(s, t)
if yes then the left hand side is the new optimal distance between s and t.
Increases are impossible. Consider the following graph (edges in red have zero weight):
Suppose m is the minimum weight edge here, except for (u, v) which used to be lower. Now we update (u, v) to some weight l > m. This means we must find m to find the new optimum length.
Suppose we could do this in O(1) time. Then it means we could find the minimum of any array in O(1) time by feeding it into this algorithm after adding (u, v) with weight -BIGNUMBER and then 'updating' it to BIGNUMBER (we can lazily construct the distance matrix because all distances are either 0, inf or just the edge weights). That is clearly not possible, thus we can't solve this problem in O(1) either.

Algorithm to Compute square of a directed graph(represented in form of an adjacency list)

I am working on constructing an algorithm to compute G^2 of a directed graph that is a form of an adjacency list, where G^2 = (V,E'), where E' is defined as (u,v)∈E′ if there is a path of length 2 between u and v in G. I understand the question very well and have found an algorithm which I assume is correct, however the runtime of my algorithm is O(VE^2) where V is the number of vertices and E is the number of Edges of the graph. I was wondering how I could do this in O(VE) time in order to make it more efficient?
Here is the algorithm, I came up with:
for vertex in Vertices
for neighbor in Neighbors
for n in Neighbors
if(n!=neighbor)
then-> if(n.value==neighbor)
add this to a new adjacency list
break; // this means we have found a path of size 2 between vertex and neighbor
continue otherwise
The problem can be solved in time O(VE) using BFS(breadth first search). The thing about BFS, is that it traverses the graph level by level. Meaning that first it traverses all the vertices at a distance of 1 from the source vertex. Then it traverses all the vertices at a distance of 2 from the source vertex and so on. So we can take advantage of this fact and terminate our BFS, when we have reached vertices at a distance of 2.
Following is the pseudocode:
For each vertex v in V
{
Do a BFS with v as source vertex
{
For all vertices u at distance of 2 from v
add u to adjacency list of v
and terminate BFS
}
}
Since BFS takes time O(V + E) and we invoke this for every vertex, so total time is O(V(V + E)) = O(V^2 + VE) = O(VE) .Just remember to start with fresh data structures for every BFS traversal.

Given an undirected graph G = (V, E), determine whether G is a complete graph

I'm pretty sure this problem is P and not NP, but I'm having difficulty coming up with a polynomially bound algorithm to solve it.
You can :
check that number of edges in the graph is n(n-1)/2.
check that each vertice is connected to exaclty n-1 distinct vertices.
This will run in O(V²), which is polynomial.
Hope it helped.
Here's an O(|E|) algorithm that also has a small constant.
It's trivial to enumerate every edge in a complete graph. So all you need to do is scan your edge list and verify that every such edge exists.
For each edge (i, j), let f(i, j) = i*|V| + j. Assuming vertices are numbered 0 to |V|-1.
Let bitvec be a bit vector of length |V|2, initialized to 0.
For each edge (i, j), set bitvec[f(i, j)] = 1.
G is a complete graph if and only if every element of bitvec == 1.
This algorithm not only touches E once, but it's also completely vectorizable if you have a scatter instruction. That also means it's trivial to parallelize.
Here is an O(E) algorithm:
Use O(E) as it is input time, to scan the graph
Meanwhile, record each vertex p's degree, increase degree only if the neighbor is not p itself (self-connecting edge) and is not a vertex q where p and q has another edge counted already (multiple edge), these checking can be done in O(1)
Check if all vertex's degree is |V|-1, this step is O(V), if Yes then it is a complete graph
Total is O(E)
For a given graph G = (V,E), check for each pair u, v in the V, and see if edge (u,v) is in E.
The total number of u, v pairs are |V|*(|V|-1)/2. As a result, with a time complexity of O(|V|^2), you can check and see if a graph is complete or not.

Prim's MST algorithm in O(|V|^2)

Time complexity of Prim's MST algorithm is O(|V|^2) if you use adjacency matrix representation.
I am trying to implement Prim's algorithm using adjacency matrix. I am using this
as a reference.
V = {1,2...,n}
U = {1}
T = NULL
while V != U:
/*
Now this implementation means that
I find lowest cost edge in O(n).
How do I do that using adjacency list?
*/
let (u, v) be the lowest cost edge
such that u is in U and v is in V - U;
T = T + {(u,v)}
U = U + {v}
EDIT:
I understand Prim's algorithm very well.
I know how to implement it efficiently using heaps and priority queues.
I also know about better algorithms.
I want to use adjacency matrix representation of graph and get O(|V|^2) implementation.
I WANT THE INEFFICIENT IMPLEMENTATION
Finding the lowest cost edge (u,v), such that u is in U and v is in V-U, is done with a priority queue. More precisely, the priority queue contains each node v from V-U together with the lowest cost edge from v into the current tree U. In other words, the queue contains exactly |V-U| elements.
After adding a new node u to U, you have to update the priority queue by checking whether the neighboring nodes of u can now be reached by an edge of lower cost than previously.
The choice of priority queue determines the time complexity. You will get O(|V|^2) by implementing the priority queue as a simply array cheapest_edges[1..|V|]. That's because finding minimum in this queue takes O(|V|) time, and you repeat that |V| times.
In pseudo-code:
V = {2...,n}
U = {1}
T = NULL
P = array, for each v set P[v] = (1,v)
while V != U
(u,v) = P[v] with v such that length P[v] is minimal
T = T + {(u,v)}
U = U + {v}
for each w adjacent to v
if length (v,w) < length P[w] then
P[w] = (v,w)
You do it like in Dijkstra's algorithm, by selecting the node that is connected to your current partial tree with the minimum cost edge (that doesn't generate a cycle). I think wikipedia explains Prim better than that pseudocode you have. Give it a look and let me know if you have more questions.
You can sort the edges by the cost and then iterate the edges in the order of the cost, and if that edge joins two distinct subgraphs use that edge.
I have a implementation here. It reads the number of verticles (N), the number of edges (M) and the edges in order (A, B, Cost) and then outputs the edges. This is the Kruskal algorithm.
A implementation of the Prim's algorithm with a heap, using the same input can be found here.

Resources