DFS Algorithm Traversal - algorithm

Given the above graph, the DFS traversal with a stack gives me the folowing path...
1-2-3-4-5-6
Is the above path valid? Does there exists another path? (my textbook gives me 1-2-3-6-4-5)
I don't have enough rep to post images over at computer science stack so I had to resort to asking here, not sure if it fits; if it doesn't I am happy to delete it afterwards.
Thanks,

You have listed a perfectly valid DFS traversal of the graph, and the textbook is giving you another totally legal DFS traversal of the graph. There can be many depth-first traversals of the same graph (in fact, there's often exponentially many of them), so if you don't get the same one as your textbook that's not an immediate cause for alarm.
Here are some other orderings:
1 2 5 4 3 6
3 1 6 2 5 4
5 4 2 3 1 6
...
However, if there are some other rules about how nodes ought to be visited (for example, always visiting connected nodes in ascending or descending order), then a DFS search will always produce the same output.
Hope this helps!

The output you describe is not a path, it's the order in which DFS visits the nodes. A path is a list of nodes where each node is connected to the previous and next node.
The output of the DFS traversal can also be seen as a DFS traversal tree, which in your case corresponds to:
1 - 2 - 3 - 4 - 5
|
6
The textbook tree is
1 - 2 - 3 - 6
|
4 - 5
You can get many different DFS trees, because at each point where you have a choice, you can decide where to go first. In your examples, from node 3 you can go to node 4 or node 6, and the different outputs are due to the different choices.

Related

Is this the correct order for BFS and DFS?

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.

How to count the maximum number of times any node has been visited while traveling through a tree several times?

We travel through a given tree (not binary) several times. How do we calculate the most number of times any node in the tree has been visited?
For example: in the tree:
1
/ \
2 3
/ \
4 5
Suppose we are told to travel 2 times, from 2 to 3, then 5 to 3. The travel paths will be (2->1->3 and 5->3). The maximum number of times a node has been visited is 2 (the node is 3). All travels are independent from each other. A given travel starts from a given node A and ends at B.
How to efficiently travel (if we even need to) in order to calculate that, considering that we have over 50,000 nodes and 75,000 paths to cover (like 2 to 3 and 3 to 4 in the example)?
Based on what you are saying, the answer is the amount of children that node has...
Also in your example, going off what you have said, both 1 and 3 are visited the most.
In your example each node is only going to get visited once. The only way you could get multiple visits to one node would be with a tree like:
1 3
\ /
2
Edit:: the most efficient way of traversing is if you have a perfect binary tre
4
2 6
1 3 5 7
Where the max depth is number of ((log base 2 of (number of nodes + 1)) + 1) rounded down
Why not store the travel count of each node separately?
Maintain a HashMap<Node, long> keeping track of how many times each node has been visited.
Then maintain a TreeMap<long, List<Node>> that is keyed on count and contains the list of node whose count it is representing.
This way, the TreeMap's first would contain all the nodes that have the highest count, because there can definitely be more than one node with that highest visit count.
All you now need to do is add bookkeeping code for properly updating the two maps whenever a node is visited as part of a tree traversal.
There's an XY problem here.
Your question states you want to store number of node visits. What you really want though is an efficient traversal strategy.
You have options here. Since the edges are bi-directional the best strategy IMO would be a bi-directional search.
But the search strategy itself is a toss up.
Consider a slightly more elaborate tree as
1 -> 2,3,4; 2 -> 5,6,7; 3->8,9; 4->10,11; 10 -> 12,13. If you have an efficient path from 5 to 4 It doesn't mean you can just start from there to find an efficient path from 5 to 13 because you don;t 13 comes under 4 unless you've already found an efficient path from 4 to 13.
So I would suggest memoizing your traversals in a dictionary of the form <Node Pair>: [Traversal list]
Where you start at a target node and perform a Breadth first search. and each time you visit a node, examine your memoization structure if there exists a an entry for <curnode,targetnode> in the dictionary. If there exists an entry, you are done. If not proceed to the current node's sibling or child.
CAVEAT: THIS IS UNDER THE ASSUMPTION THAT ALL NODES HAVE ONLY 1 PARENT AND CYCLES DON'T HAPPEN
I think people are miss understanding the question. He/she wants to ask which node is visited max number of times given x number of travel. So from his tree edges are {(2-1)(1-3)(3-4),(3-5)} now for example we are traveling in following paths{(1,5), (2,4), (1,3), (1,2), (1,3), (4,5)}. So this example 3 visited 5 times, 1 visited 4 times and so on.
Since it is a tree there is only one path exist from one node to another. Find paths for all combination of nodes in DP way and store it.
Then count for each visit. I know there is more efficient way for counting but cannot think of it right now.

How to build binary tree knowing only which nodes are connected?

I have to build a binary tree but i don't know which node is parent, left child, or right child. I only know which nodes are connected. Example: for input like this:
6 4
5 7
9 7
1 5
10 4
3 4
2 6
7 8
5 6
(from 1 there is always one path) the tree should looks like that:
One the input i have also given number of nodes. Any ideas, tips?
From the list of the edges, one can easily create a tree.
You can find which are the leaf nodes, just search which nodes are appearing only in one edge.
But, it is not possible to know which of the leaf nodes is the head of the tree.
In a tree structure it is possible to choose any leaf, choose it as the head, and reorder the tree, and it'll be a valid tree.
There is also the issue of tree isomorphism, you can swap the right and left sub-trees to get a valid tree.
To summarize, from this list you can get 6 heads and in each 4 possible swaps, so in total 24 different valid trees.

DFS and BFS Outputs?

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?

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.

Resources