Is this the correct order for BFS and DFS? - depth-first-search

Below I have a tree and I need to list the order of marking vertices as visited for both DFS and BFS. I have my list below but just wondering if I did it correctly. It starts from 0.

The question says you have a tree, but this is not a tree; it is a graph. The answer therefore depends on whether this is an undirected graph or a directed graph. I suspect whoever created the diagram intended the graph to be directed, with vertical positioning indicating direction, but they should have made this clearer by using arrowheads to indicate the edge directions. As it is, it looks like edges coming into a node are at the top of it, and edges coming out of a node are at the bottom of it.
The correct order also depends on which order a node's neighbours are visited in. For DFS, this will depend on the implementation of DFS; a recursive DFS will usually visit children in ascending order, whereas an iterative DFS using a stack will sometimes visit in descending order (because the stack's LIFO behaviour means they'll be popped in reverse order), unless the children are pushed to the stack in reverse order.
Normally BFS will visit children in ascending order, and there is no particular reason an implementation of BFS would visit them in descending order (since a queue is FIFO, they are polled in the same order they're inserted into the queue).
If the graph is directed, then DFS order would be 0 1 2 3 4 5 6 if you visit children in ascending order, or (coincidentally) 0 6 5 4 2 3 1 if you visit children in descending order.
If you assumed the graph is directed, then your answer for DFS cannot be correct because it ends with 2 1 3. If 3 isn't visited yet, then it should be visited immediately after 2, before backtracking.
Alternatively, if the graph is undirected then DFS order would (coincidentally) be 0 1 2 3 4 5 6 if children are visited in ascending order, or (coincidentally) 0 6 5 4 2 3 1 if they are visited in descending order.
If you assumed the graph is undirected then your answer for DFS is inconsistent, because you start by going from node 0 to node 6 (i.e. descending order), but then when you reach node 2 you visit node 1 before node 3 (i.e. ascending order).
Your answer for BFS is correct whether the graph is directed or undirected.

Related

Does Dijkstra's algorithm work with negative edges if there is no "processed" check?

Typically, in Dijkstra's algorithm, for each encountered node, we check whether that node was processed before attempting to update the distances of its neighbors and adding them to the queue. This method is under the assumption that if a distance to a node is set once then the distance to that node cannot improve for the rest of the algorithm, and so if the node was processed once already, then the distances to its neighbors cannot improve. However, this is not true for graphs with negative edges.
If there are no negatives cycles then if we remove that "processed" check, then will the algorithm always work for graphs with negative edges?
Edit: an example of a graph where the algorithm would fail would be nice
Edit 2: Java code https://pastebin.com/LSnfzBW4
Example usage:
3 3 1 <-- 3 nodes, 3 edges, starting point at node 1
1 2 5 <-- edge of node 1 and node 2 with a weight of 5 (unidirectional)
2 3 -20 <-- more edges
1 3 2
The algorithm will produce the correct answer, but since nodes can now be visited multiple times the time complexity will be exponential.
Here's an example demonstrating the exponential complexity:
w(1, 3) = 4
w(1, 2) = 100
w(2, 3) = -100
w(3, 5) = 2
w(3, 4) = 50
w(4, 5) = -50
w(5, 7) = 1
w(5, 6) = 25
w(6, 7) = -25
If the algorithm is trying to find the shortest path from node 1 to node 7, it will first reach node 3 via the edge with weight 4 and then explore the rest of the graph. Then, it will find a shorter path to node 3 by going to node 2 first, and then it will explore the rest of the graph again.
Every time the algorithm reaches one of the odd indexed nodes, it will first go to the next odd indexed node via the direct edge and explore the rest of the graph. Then it will find a shorter path to the next odd indexed node via the even indexed node and explore the rest of the graph again. This means that every time one of the odd indexed nodes is reached, the rest of the graph will be explored twice, leading to a complexity of at least O(2^(|V|/2)).
If I understand your question correctly, I don't think its possible. Without the processed check the algorithm would fall into infinite loop. For example, for a bidirected graph having two nodes i.e. a and b with one edge from "a" to "b" or "b" to "a", it will first insert node "a" inside the priority queue, then as there have an edge between "a" to "b", it will insert node "b" and pop node "a". And then as node "a" is not marked processed for node "b" it will again insert node "a" inside the priority queue and so on. Which leads to an infinite loop.
For finding shortest path in the graphs with negative edges Bellmen-ford algorithm would be the right way.
If negative edges release from start node, dijkstra's algorithm works. But in the other situation Usually it dosen't works for negative edges.

Breadth First Search vs Depth First Search

Can anybody give a simple explanation on BFS and DFS?
I want to understand when to prefer BFS over DFS.
BFS and DFS are both graph traversing algorithms, the difference between them is the way each algorithm traverses the graph.
DFS, Imagine you have the following graph and we want to start traversing from node 1:
1
/ \
2 3
/ \ \
4 5 6
DFS means Depth first search, so it will traverse the graph in this way:
start from node 1 then look for its children. It finds node 2.
go to node 2 then look for its children. It finds node 4.
go to node 4 then it finds that it has no children.
go Up to node 2 again and see its other children. It finds node 5.
go to node 5 then it find that it has no children.
go up again to node 2 and find out that it has no more children.
go up to node 1 then look for its children. It finds node 3.
go to node 3 then look for its children. It find node 6.
go to node 6 and find out that it has no children.
go up to node 3 and find out that it has no more children.
go up to node 1 and find out that it has no more children, hence the graph traversal has finished at this point.
If you note here how this algorithm goes in depth first, so once it found that node 2 is a child of node 1 it went for it and started looking for its children without caring about the rest of children of node 1 (node 3) at this point of time, then after going to deepest possible node (nodes 4, 5) it started to go Up looking for the rest of children of node 1.
On the other hand, consider we want to traverse the same graph using BFS algorithm. When using BFS you start thinking of graph nodes as levels, each level is closer than the level after it relative to the node you start traversing from. which means:
1 (level 0)
/ \
2 3 (level 1)
/ \ \
4 5 6 (level 2)
So traversing the graph will be:
start from node 1 then look for its children (nodes 2, 3) [the next level].
traverse nodes of level 1 (2, 3) and look for their children (nodes 4, 5, 6) [the next level].
traverse nodes of level 2 (4, 5, 6) and look for this children (no children) [no next level].
then graph traversal ends at this point.
You can realize here that the direct children of a node (the next level) are always the closest nodes to it, and hence the advantage of using BFS over DFS is that it can guarantee for you that you reach from node x to node y using the shortest path possible.
But be aware that BFS algorithm can't find you the shortest path for all types of graph. The graph I mentioned in this example is unweighted graph (a graph in which all edges/paths are the same). If your graph is weighted (edges/paths have weights and not the same) then you have to use another algorithm that takes this into consideration (like Dijkstra).

Confusions on finding a cycle in a possibly unconnected directed graph

I am confused about this answer. Why can't DFS decide if there is a cycle in a directed graph while visiting each node and each edge at most once? Using the white, gray, black method, one should be able to find a cycle if there is a backward edge.
For an unconnected directed graph, why can't one do the following: run DFS from an arbitrary node v and visit as many nodes as v is connected to, then run DFS on another unvisited arbitrary node in the graph, if any, until all nodes are visited?
It seems to me that DFS should be able to find a cycle if it exists in at most o(|V|+|E|) time. Is this claim in the above mentioned answer wrong?
"It is possible to visit a node multiple times in a DFS without a
cycle existing"
Moreover, as this other answer suggest, if a cycle exists, DFS should find it after exploring a maximum of |V| edges, so the run time is really O(|V|).
What am I missing?
Update and conclusions:
Based on Pham Trung's comments, it looks like the "simple DFS" in that answer refers to a DFS starting from one node in a strongly connected graph. As I understand it, for a general case that the graph might be unconnected, the following statements should be true:
Using DFS and starting from an arbitrary unvisited node in an unconnected graph, it is true that each node might be visited more than once, but using white-gray-black coloring, a cycle -if exists - will be correctly found.
The run time of such a DFS algorithm is O(d.|V|+|E|), where d is the max in-degree among all nodes (i.e. the max time that we can visit each node using such DFS-based algorithm)
Moreover, as this other answer suggest, if after exploring O(|V|) edges, a cycle was not found, it does not exist. So the runtime is really O(|V|).
Imagine we have this simple graph with these edges:
1 -> 3
2 -> 3
1 ----->3
^
|
2--------
So, in our first dfs, we discover node 1 and 3. And, we continue to do dfs with node 2, now, we encounter node 3 again, but is this a cycle? obviously not.
One more example:
1 -> 3
1 -> 2
2 -> 3
1----->3
| ^
| |
| |
v |
2-------
So, starting with node 1, we visit node 3, back to node 2, and now, we encounter node 3 one more time, and, this case, it is not a cycle also.
As far as I understand the simple depth-first-search from Jay Conrod's answer means, a normal, original DFS (only checking for connected component). In the same answer, he also described how to modify simple DFS to find the existence of cycle, which is exactly the algorithm OP has cited. And right below, another answer also mentioned a lemma in the famous Introduction to algorithm book
A directed graph G is acyclic if and only if a depth-first search of G yields no back edges
In short, OP's understanding to detect cycle in directed graph is correct, it is just some complexities and shortcuts have lead to misunderstanding.

How to classify an edge that is not traversed in a depth-first search?

I have an assignment that requires one to perform a depth-first search on a directed graph and to classify all edges of the graph. However, I'm confused as to how one would classify an edge that is not traversed during the course of the depth-first search, seeing as how these edges are classified during the course of a search.
Let me summarize a depth-first search on the above pictured graph.
First we go from 1 to 2. Then we pop 2 off the stack, because there is nowhere to go, so we're back at 1. Then we go from 1 to 3. Next we go from 3 to 4.
Ok, so assuming I got that part right, then all the edges traversed are Tree edges correct? So, how would one classify the edges between 3 to 2 and the edge from 4 to 3?
Your DFS should still traverse the edges from 3->2 and 4->3. They would be a cross edge and a back edge, respectively, IIRC.
You'll only actually push a node onto the stack the first time you see it, but when you do visit it, you look at all of its outgoing edges, whether their destinations have already been visited or not.

What are the articulation points of this directed graph?

5 nodes in this directed graph.
Edges:
1 -> 2
2 -> 3
2 -> 4
4 -> 5
(Graphical image : http://i.imgur.com/hafBv.jpg )
Am I correct in thinking that the articulation points are node 2 and 4 ?
(If you remove node 2 or node 4, the graph becomes disconnected)
But the definition I've seen everywhere says something similar to:
a node u is an articulation point, if for every child v of u, there is no back edge from v to a node higher in the DFS tree than u.
How does this work for a directed graph? For example, Node 3 does not have a back edge to a node higher in the DFS tree than 2. Does this classify Node 3 as an articulation point? But its removal does not cause the graph to be broken into 2 or more pieces (That is my layman definition of an articulation node).
Disclaimer: My memory is vague.
Directed graphs have three kinds of connectedness.
"Strongly connected" if there is a path from every vertex to every other vertex,
"Connected" if there is a path between any two nodes, but not in both directions.
"Weakly connected" if the graph is only connected if the arcs are replaced with undirected arcs.
eg
1->2 , 2->3 , 3->1
Strongly connected, you can get from every node to every other node
1->2 , 2->3
You can't get from 3 to 1 but you can from 1 to 3 so it's connected
1->2 , 3->2
There is no way to get from 1 to 3 or from 3 to 1, so it's only weakly connected.
What nodes are articulation points depends on what kind of connectedness you are considering.
Your graph is only weakly connected since there's no way to get from 3 to 4 or from 4 to 3.
Which would mean that the only way it makes sense to talk about articulation points is if you treat the arcs as undirected. In which case 2 and 4 would be the articulation points, as you said.
Articulation point should always have children and parent. This is something that is missing from your definition and makes nodes 1 and 3 articulation points whilst they are not.
Also note that in your reasoning for node 3 you consider the node itself not its children. If you apply the definition carefully you will see that you should consider the children instead. In your case - empty set and, with the extended by me definition, 3 is no longer articulation point.
Node 3 does not have a back edge to a node higher in the DFS tree than 2
Node 3 doesnt have children, so it cannot be an articulation point (from def).
If we put this definition in the context of a directed tree, then the articular points are all the points except the root and the leaf node
but when we follow the method we used to solve the undirected graph we get the respected (num,low) values for nodes are node-1(1,1)
2 (2,2) ,node 3 (3,3), node 4(4,4).node 5(5,5).
so following the def of articulation point and finding the node with 2 children
and satisfying the rule (low(child)>=num(node))
we get only the node 2 so that is the articulation point .
but the theory can be applied because it is still a connected graph i.e where every node is reachable but when we are finding we had to take care of tree and back edges and the rest is same as that of undirected graph.
The definition of articulation is not as clear as in case of undirected graphs. However if we choose two particular nodes: source and sink and call any point that must occur on the path from source to sink articulation point, the definition is clear.
I call them unavoidable points and have got simple solution for finding them on my GitHub

Resources