DFS and BFS Outputs? - algorithm

So I'm confused with the outputs of both of the BFS and DFS algorithms.
As much as I understood BFS takes as input a graph suppose G and a vertex suppose x.
Output : returns a graph, which in for every vertex in G, the new graph
has the shortest way from vertex x to any other vertex in the graph.
is that right? if not, what is?
and how about DFS ? DFS's input is only a graph, does it mean DFS doesn't care where you start from? and what's DFS's Output?
Thanks

I'm not completely sure what it is that you wanted, but I'll give it a shot.
Let's say we have the following graph:
X - 1 - 2 - 3
| \
1 1
| \
2 2
| \
3 3
In this graph, X marks the node where we will start traversing from, and a number denotes a value that a particular node holds. This time X has 3 immediate neighboring nodes, that all hold a value 1.
For the sake of the example, let us assume that any node cannot be traversed twice. Let us also assume that the program always prints the value of the node it's standing on.
Without really getting in depth with the way BFS and DFS work (at all), the output would be like this:
BFS: X 1 1 1 2 2 2 3 3 3
DFS: X 1 2 3 1 2 3 1 2 3
Hope this answers your question.

DFS is a Graph traversal technique which takes the graph and a starting vertex(random) as input and gives a sequence of vertices as output.
The sequence contains those vertices which are reachable from the starting vertex.
i.e we are finding whether any vertex is reachable from any other vertex in a graph or not?

Related

Computing level of nodes in a graph

I want to compute the level of each node in a directed graph. I'm currently applying a depth-first search algorithm on vertices that have no incoming edges. Considering the graph below, for instance:
The expected result is:
Vertex | Level
1 | 0
2 | 1
3 | 2
4 | 1
5 | 3
6 | 4
In this particular case, if we start by applying DFS on 4, then all results for vertices 4, 3, 5 and 6 are going to be wrong, since 1 has level 0. I've tried to always consider the greatest result for each one of the nodes, so in this case the results for 3, 5, and 6 are replaced when applying DFS on 1. It works, but I can't find a way to correctly compute the level of vertex 4.
I'm working only with directed acyclic graphs.
I'm not including any code here because it is a pretty straightforward DFS implementation and I'm not struggling implementation-wise.
Any hint would be much appreciated.
You can compute the levels starting from each vertex without having an incoming edge. Then you can store the maximum value for each vertex until the end. For eg :- Vertex 3 will have values 1 and 2 when traversed from starting points vertex 1 and vertex 4 respectively. At last, you can update the vertices not having the incoming edge(number on child -1). If there's a situation where there multiple children of such a vertex, then you might want to select the child with maximum number on it for replacement and then run the algorithm from that vertex again to see if changes the numbers assigned to any of the other children.

Finding corresponding graph from given shortest paths

Given n by n points and the distance d between these points, I need to find the corresponding undirected weighted graph that would result in these distances. I tried using Prim's algorithm to find the MST, however this set is of size n-1 and does not include the n needed edges. E.g. given n by n distances
0 3 5
3 0 4
5 4 0
I need to find the corresponding edges:
1 - 2 = 3
1 - 3 = 5
2 - 3 = 4
Which results in the graph:
3
1 --------- 2
\ /
\5 /4
\ /
\ /
3
However Prim's would return only the first 2 edges since a MST doesn't contain any cycles.
One graph that would result in these distances is the graph that has an edge from every node to every other node and the length of that edge is the distance according to the matrix. (I'm not sure what you mean by unweighted directed because the example you give appears to be undirected and I'm not sure what the difference is between weights and lengths here).
Another option would be to consider the distances in increasing order, as you have done with Prim's algorithm, and, as well as checking to see if the edge is required to connect its two ends, check to see if the minimum distance between those ends in the graph reconstructed so far is the same as the distance in the matrix. If it is not, add the edge even if the ends are connected in the graph so far.

Finding Strongly Connected Components in a graph through DFS

I was reading the graph algorithms about BFS and DFS. When I was analyzing the algorithm for finding strongly connected component in a Graph through DFS, a doubt came to my mind. For finding the strongly connected component, what book(Coremen)does, first it ran the DFS on the Graph in order to get the finish time of the vertices then again ran the DFS on the transpose of the graph in decreasing order of the finish time which we got from the first DFS. But I am not able to grasp why the second DFS must be run according to finish time.
What I mean is that even if we directly run the DFS (ignoring the finish time) on the transpose of the graph, could it also have given us the connected components because by doing the transpose we have already blocked the path to other components.
Edit- Here's some good in-depth videos from stanford university on the topic:
http://openclassroom.stanford.edu/MainFolder/CoursePage.php?course=IntroToAlgorithms (See 6. CONNECTIVITY IN DIRECTED GRAPHS)
My explanation:
It's possible that you would incorrectly identify the entire graph as a single strongly connected component(SCC) if you don't run the second dfs according to decreasing finish times of the first dfs.
Notice that in my example, node d would always have the lowest finish time from the first dfs. One of nodes a, b, or c will have the highest finish times. Lets assume a has the highest finish time, and so if we ran the second dfs according to decreasing finish times, a would be first.
Now, if you ran the second dfs starting with node d in the transpose of G, you would produce a depth first forest containing the entire graph, and so conclude that the entire graph is a SCC, which is clearly false. However, if you start the dfs with a, then you would not only discover a, b, and c, as being an SCC, but the important part is that they would be marked as visited by being colored grey or black. Then when you continue the dfs on d, you wouldn't traverse out of its SCC because you would realize that its adjacent nodes have been visited.
If you look at cormens code for DFS,
DFS(G)
1 for each vertex u in G.V
2 u.color = WHITE
3 u.π = NIL
4 time = 0
5 for each vertex u in G.V
6 if u.color == WHITE
7 DFS-VISIT(G, u)
DFS-VISIT(G, u)
1 time = time + 1 // white vertex u has just been discovered
2 u.d = time
3 u.color = GRAY
4 for each v in G.adj[u]
5 if v.color == WHITE
6 v.π = u
7 DFS-VISIT(G, u)
8 u.color = BLACK // blacken u; it is finished
9 time = time + 1
10 u.f = time
if you didn't use decreasing finish time, then line 6 of DFS would only be true once, because DFS-VISIT would visit the entire graph recursively. This produces a single tree in the depth first forest, and each tree is an SCC. The reasoning for a single tree is because a tree is identified by its root node having a nil predecessor.

Are paths in graph connected

I have a problem with paths in graph. We have a graph, for example:
5 verticles and 4 edges
1 2 first is connected to second, etc
2 3
3 4
5 1
And now I would like answer on questions(for example):
If vertex 1 is conneted to
vertex 3. Answer is YES - becauese we have path" 1 -> 2 -> 3.
What Do you advise me?
I have no idea how to do it.
This will require some research on your part. The idea is to use a graph traversal algorithm like depth-first or breadth-first. Start from a vertex (like 1 in your example) and keep traversing the graph until you either reach the target node (3 in your example) or you cannot find any more paths to follow.
DFS or BFS (I'd prefer DFS because it would result in less backtracking) from the starting node, if the algorithm completes without finding the node it is not reachable.

Shortest path in absence of the given edge

Suppose we are given a weighted graph G(V,E).
The graph contains N vertices (Numbered from 0 to N-1) and M Bidirectional edges .
Each edge(vi,vj) has postive distance d (ie the distance between the two vertex vivj is d)
There is atmost one edge between any two vertex and also there is no self loop (ie.no edge connect a vertex to
itself.)
Also we are given S the source vertex and D the destination vertex.
let Q be the number of queries,each queries contains one edge e(x,y).
For each query,We have to find the shortest path from the source S to Destination D, assuming that edge (x,y) is absent in original graph.
If no any path exists from S to D ,then we have to print No.
Constraints are high 0<=(N,Q,M)<=25000
How to solve this problem efficiently?
Till now what i did is implemented the simple Dijakstra algorithm.
For each Query Q ,everytime i am assigning (x,y) to Infinity
and finding Dijakstra shortest path.
But this approach will be very slow as overall complexity will be Q(time complexity of Dijastra Shortes path)*
Example::
N=6,M=9
S=0 ,D=5
(u,v,cost(u,v))
0 2 4
3 5 8
3 4 1
2 3 1
0 1 1
4 5 1
2 4 5
1 2 1
1 3 3
Total Queries =6
Query edge=(0,1) Answer=7
Query edge=(0,2) Answer=5
Query edge=(1,3) Answer=5
Query edge=(2,3) Answer=6
Query edge=(4,5) Answer=11
Query edge=(3,4) Answer=8
First, compute the shortest path tree from source node to destination.
Second, loop over all the queries and cut the shortest path at the edge specified by the query; this defines a min-cut problem, where you have the distance between the source node and the frontier of one partition and the frontier of the another and the destination; you can compute this problem very easily, at most O(|E|).
Thus, this algorithm requires O(Q|E| + |V|log|V|), asymptotically faster than the naïve solution when |V|log|V| > |E|.
This solution reuses Dijkstra's computation, but still processes each query individually, so perhaps there are room to improvements by exploiting the work did in a previous query in successive queries by observing the shape of the cut induced by the edge.
For each query the graph changes only very slightly, so you can reuse a lot of your computation.
I suggest the following approach:
Compute the shortest path from S to all other nodes (Dijkstras Algorithm does that for you already). This will give you a shortest path tree T.
For each query, take this tree, pruned by the edge (x,y) from the query. This might be the original tree (if (x,y) was no where on the tree) or a smaller tree T'.
If D is in the T', you can take the original shortest path
Otherwise start Dijkstra, but use the labels you already have from the T' (these paths are already smallest) as permanent labels.
If you run the Dijkstra in step 2 you can reuse the pruned of part of tree T in the following way: Every time you want to mark a node permanent (which is one of the nodes not in T') you may attach the entire subtree of this node (from the original tree T) to your new shortest path tree and label all its nodes permanent.
This way you reuse as much information as possible from the first shortest path run.
In your example this would mean:
Compute shortest path tree:
0->1->2->3->4->5
(in this case a very simple)
Now assume we get query (1,2).
We prune edge (1,2) leaving us with
0->1
From there we start Dijkstra getting 2 and 3 as next permanent marked nodes.
We connect 1 to 2 and 1 to 3 in the new shortest path tree and attach the old subtree from 3:
2<-0->1->3->4->5
So we got the shortest path with just running one additional step of Dijkstras Algorithm.
The correctness of the algorithm follows from all paths in tree T being at most as long as in the new Graph from the Query (where every shortest path can only be longer). Therefore we can reuse every path from the tree that is still feasible (i.e. where no edge was removed).
If performance matters a lot, you can improve on the Dijkstra performance through a lot of implementation tricks. A good entry point for this might be the DIMACS Shortest Path Implementation Challenge.
One simple optimization: first run Dijkstra on complete graph (with no edges removed).
Then, for each query - check if the requested edge belongs to that shortest path. If not - removing this edge won't make any difference.

Resources