Proper traversal of undirected graph using depth first search? - depth-first-search

I've got an undirected graph that I need to traverse using depth first search.
The excel chart below shows each node has been marked after traversal in the marked column, and the edgeTo column shows which node brought us to that node. For example, we got to node 1 from node 5, we got to node 2 from node 7, etc.
My question is for node 6 and 8, since they are separated from the main graph, how do I properly traverse it? My guess is that I start at 6 and go to 8, but since 6 will already have been visited at that point, I do not go back to 6 from 8. Hence row 6 is left blank in the edgeTo column.
Am I correct? Is my chart correct?

Depth first search is basically used to find a path between two nodes in a graph. The graph of your example is disconnected, i.e. there exist two nodes in your graph such that no path in your graph has those nodes as endpoints.
6 and 8 are obviously nodes that belong to a different subgraph and therefore you can't find a path between 0 and 8 and the DFS will return IMPOSSIBLE or No path found. Apart from that your chart is correct.

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.

Find previous "chokepoint" in path

I have a "tree"-like structure of nodes and I'm trying to figure out an algorithm that will find previous "chokepoint" when end node is given. Here is a picture to better demonstrate:
So when 15 is specified as end node I want to find 7
And if 7 is specified as end node I want to find 1
But in the example above if anything else than 7,15 or 16 is specified as end node the found node is the previous one since that is the only node connecting to the end node.
So the node I am searching for is the previous node that all paths must go through to get to the end node.
I tried an algorithm where I start from the end node and go backwards (using Breadth-first) and every node I find that has 2 or more outputs I add to a new list and nodes with one output I skip. For example in case with 15 as the end node, I end up adding 10 and 7 to list of potential nodes, but I'm not sure how to from there. Since I should not continue traversing from 7.
Is there potentially an algorithm out there that already does that and if not how could I achieve this?
I believe your "choke points" are what is commonly known as "dominators". In a directed graph, one node X dominates another Y if all paths to Y must go through X. In your graph, 1 and 7 dominate all greater nodes.
See: https://en.wikipedia.org/wiki/Dominator_(graph_theory)
The dominators of a directed graph form a tree. The wikipedia article gives a simple algorithm for finding them all in quadratic time.
You can do it in linear time, but it's tricky. The classic algorithm is from Lengauer and Tarjan. You can find it here: https://www.cs.princeton.edu/courses/archive/fall03/cs528/handouts/a%20fast%20algorithm%20for%20finding.pdf
A topological sort is an ordering of the graph such that each arrow agrees with the order. For example in your example we might come up with the order:
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 15
Do a topological sort using any of the O(n) algorithms for it.
Next, we walk the graph and track how many incoming edges each node has.
Finally we walk the graph in our sorted order and track how many edges we have seen one end of but not the other, and how many nodes have no incoming edges. Any time we come to a node where all outgoing edges have not ended and every future node has incoming edges, that is a chokepoint.
After that, we can prepare two maps. The first is from each node to its topological order. The second is a balanced binary tree of where the chokepoints are.
The analysis in advance is O(n). The actual lookups are now O(log(n)).

find the source of reconvergent fanouts in a DAG

if we have graph like:
the rencovergent nodes are nodes 10 and 11.
by reconvergent nodes i mean the parents of that node come from a common source node.
in the given graph the parents of node 10 are nodes 7, 8 and they both have node 6 as source node(source of reconvergence)
and for node 11 the source node would be node 4.
my question is if we know which nodes are reconvergent nodes in the DAG how could we find the source nodes of their parents?
for my graph structure i use adjacency list representation available at geekforgeeks
i've tried this:
if(Node is reconvergent_node)
for each parents of Node
Do DFS(0, parents[i]) // depth first search from primary source till we reach the parent node
if the paths from 0 to parents[i] (which extracted from DFS) have common node mark that node as source node
is this algorithm correct? although i have not get the right results yet...
if it's correct i thinks it's limited to reconvergent nodes with max of two parents.
what if we have reconvergent_node which has five parents such that parents[1,2] have common source and parents[3,4,5] have different source node?
what should i do in this case?
any suggestion are welcome.
thank you

How do I find the minimum extra amount of edges needed to complete a connection?

Let's say we have been given the number of nodes and edges, N and M respectively. And then we are given which of the nodes are connected.How do we find the minimum amount of extra edge(s) needed to complete the connection, so that you can visit every node? By finding the answer you should be able to traverse to every node, by either going directly or going through another node to get to the goal.
Example on input:
4 2 (Nodes and edges)
0 1 (node 0 and node 1 is connected)
2 3 (node 2 and node 3 is connected)
Which then should give us the answer 1, we need one extra edge to complete the connection.
All that you need is:
1) Find connected components. It can be done by dfs or bfs. In your example these components are 0, 1 and 2, 3 respectively.
2) Then you need to iterate through the all components and connect any two vertexes for every two consequtive components. In this way you connect first and second components, then second and third components and so on... In your example you can connect any of vertexes 0, 1 with any of vertexes 2, 3. For example, you can connect vertexes 0 and 2.
It's easy to see that if the total number of components is equal to C then the answer will be C - 1 additional edges.
The minimum number of connections needed in order for your graph to be connected is N-1. But this holds if there are no nodes with 0 connections.
Try and picture a path resembling the connected list design. Every node has a degree of exactly 2, except from the two ends. That way (let's suppose your connection are not directed), starting from any node, you can reach your target by simply visiting the next not already visited node.
If M>N-1 then you can search for nodes that have more connections than needed and carry on from there.
Try and count the extra connections and compare it with the minimum number needed(N-1).

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.

Resources