Path = { (G,s,t) | G has directed path from s to t }
Clique= { (G,k) | G has k-clique}
I know by now that there is a polynomial reduction from Path to Clique without any assumption.
Why if P=NP then there is polynomial reduction in the opposite direction - from Clique to Path?
Thanks
Related
I have the following algorithm to find the minimum vertex cover of a tree. That is a minimal sized set S of vertices such that for every edge (v,u) in G either v is in S or u is in S.
I have been told the algorithm has linear time complexity, however I don't understand how this is the case, since isn't the number of edges incident to u of the order O(n) and so the complexity would be O(n^2)?
Let T = <V, E> be a Tree. That is, the vertex set is V, the edge set is E. Also suppose the cover set = C. The algorithm can be described as follows:
while V != [] do
Identify a leaf vertex v
Locate u = parent(v), the parent vertex of v.
Add u to C
Remove all the edges incident to u
return C.
In a tree, |E| = |V| - 1, so there are O(n) edges to deal with in total.
The algorithm is as follows:
The algorithm starts by topologically sorting the dag (see Section 22.4) to impose a linear ordering on the vertices. If the dag contains a path from vertex u to vertex v, then u precedes v in the topological sort. We make just one pass over the vertices in the topologically sorted order. As we process each vertex, we relax each edge that leaves the vertex.
Can somebody tell me the intuition behind it? And using that intuition please tell how do we find longest path just be negating the edge weights and running the algorithm
We cannot use Dijkstra's algorithm as edges are allowed to have negative weights.
Finding the shortest path to a vertex is easy if you already know the shortest paths to all the vertices that can precede it. Finding the longest path to a vertex in DAG is easy if you already know the longest path to all the vertices that can precede it.
Processing the vertices in topological order ensures that by the time you get to a vertex, you've already processed all the vertices that can precede it.
Dijkstra's algorithm is necessary for graphs that can contain cycles, because they can't be topologically sorted.
Your question is related to single-source shortest-path problem (SSSP) in DAG.
Topological sorting of a graph represents a linear ordering of the graph. It is allowed to process all vertices in topological order (from left to right), and all shortest paths will be found using relaxation property. Running time of the algorithm is O(|V| + |E|), where V is a set of vertices, E is a set of edges.
If you want to find the longest path (or the critical path) there are the next variants:
First way is to negate the edge weights. The path with the smallest negative value will give the longest path (but for algorithm it will still the smallest path). We can do it because topological sorting may work with negative edge weights.
Second way is to change the relaxation step:
1. Cost of each vertex is initialized to negative infinity
2. Change the relaxation step:
if d(v) < d(u) + w
then d(v) = d(u) + w
else d(v) is remains unchanged
where d - the distance;
u, v - vertices;
w - weight on edge (u, v).
In general case for solving SSSP problem there are Dijkstra's and Bellman-Ford algorithm. The main difference consists in the fact that Bellman-Ford algorithm computes SSSP for any weights in the graph and can detect negative weight cycles in the graph, but Dijkstra's algorithm can work with positive weights.
For more details see Shortest Paths.
Topological sort ensures that we are picking up nodes that come first while travelling from the source, this, in turn, will ensure that every node will have at least one condition that it can be reached from the source.
for (int i = 0; i < N; i++)
if (visited[i] == false)
topologicalSortUtil(i, visited, stack, adj);
for (int i = 0; i < N; i++)
dist[i] = Integer.MAX_VALUE;
dist[s] = 0;
while (stack.empty() == false)
{
int node = (int)stack.pop();
if (dist[node] != Integer.MAX_VALUE)
{
enter code here for(Pair it: adj.get(node)) {
if(dist[node] + it.getWeight() < dist[it.getV()]) {
dist[it.getV()] = dist[node] + it.getWeight();
}
}
}
}
As we are setting dist[src] = 0, it will start from there, the condition dis[node] != infinity will not let any other node than src enter that condition first. Because of topological sort notes coming before src will be discarded.
I have this question
Given a directed graph G with positive edge weights and a landmark vertex x, your goal is to find the length of the shortest path from one vertex v to another vertex w that passes through the landmark x.
It is needed to Describe a O(E log V ) algorithm for the problem.
I know that the complexity of Dijkstra Algorithm is O(ElogV).
Please can you help me in how to start solving this problem.
If you first find the shortest path from v to x, p_1 and from x to w, p_2 using Dijkstra's Algorithm and take the concatenation of these paths, p, then this will be the shortest path from v to w through x.
If there were a shorter path, p', then splitting this path at x would yield a path from v to x, p_1' and one from x to w, p_2' where p_1' is shorter than p_1, or p_2' is shorter than p_2 (otherwise length(p_1'+p_2') > length(p_1+p_2)) which is a contradiction.
EDIT: This is obviously O(E logV) since it is just using Dijkstra twice.
According to the Algorithms book Corman, Dijkstra is applicable for only those graphs whose all edges have non negative weights.
Does that mean, if there is any edge with negative weight it will not work for whole of the graph?
or
Will it not count that negative weight edge?
Please indicate which one is right?
Dijkstra algorithm can work on a graph of some negative edges sometimes,like:
A-->B-->C
while w(A, B) = -1 and w(B, C) = -2.
But when there is at least one negative edge, it can't prove to be always right. like:
A-->B-->C-->D
\ /
\ _____ /
where w(A, B) = 1, w(B, C) = 3, w(C, D) = -5 ,w(A, D) = 2.
If you choose A as sourcepoint, you will get the length of shortest path from A to D is 2 by Dijkstra algorithm, not -1 in fact.
It is because that Dijkstra algorithm is a greedy algorithm, and its proof procedure of correctness uses that all its edges is non-negative to obtain a contradiction.
About its proof procedure, you can look it up at Theorem 24.6 (Correctness of Dijkstra’s algorithm) ,Introduction to Algorithm.
The major problem with negative edges are negative cycles. If a graph contains a negative cycle between vertex S and vertex T, then there is no shortest path between S and T. Dijkstra finds a shortest path, which is incorrect.
Thus, negative edges are not only ignored but contribute to entirely false solutions.
An alternative is Bellman-Ford algorithm which finds those negative cycles in it's |V|-th iteration.
What would be the best algorithm to find localbridge(k) in Graph? A local bridge of degree k is an edge whose removal would enlarge the shortest distance between its two end-points to at least k.
Wikipedia: http://en.wikipedia.org/wiki/Bridge_(interpersonal)#Local_bridge
Run an all-shortest-path-costs algorithm, like the Floyd-Warshall algorithm, but where you use tuples (d1,d2) for distances, instead of the typical real numbers d:
d1 is the length of the shortest path
d2 is the length of the second shortest path
This modification to the Floyd-Warshall algorithm should be straightforward.
When you are done running the all-shortest-path-costs algorithm, the localbridge(k) edges are those edges e = {u, v} such that the distance (1,d2) between u and v satisfies d2 >= k.