Is it possible to implement DFS algorithm without using backtracking method? If it is, then please explain how it can be done.
The DFS algorithm cannot be implemented without using backtracking.
Think about it, the core nature of DFS is to explore as far as possible from a root node, until it has to go back to explore other potential paths. This means as soon as the algorithm hits a leaf node, you will be backtracking to the node before that path was explored to find other options.
To further justify this https://medium.com/#andreaiacono/backtracking-explained-7450d6ef9e1a defines backtracking as "a general algorithm ... that incrementally builds candidates to the solutions, and abandons each partial candidate (“backtracks”) as soon as it determines that the candidate cannot possibly be completed to a valid solution.". See how this applies to DFS.
Related
I had this question asked in the interview today. I told them its traversal and DFS can be used to see if the graph is connected. They said it was too simple.
What are some more important practical uses of DFS and BFS?
On a lighter note. This always comes to my mind when I hear DFS or BFS.
Note: This does not provide the direct answer to your question.
BFS :
Minimum Spanning Tree or shortest path
Peer to peer networking
Crawler for search engine
Social network websites - to find people with a given distance k from a person using BFS till k levels.
DFS :
Minimum Spanning Tree
Topological sorting
To solve puzzle/maze which has one solution
Here some points which come in my mind while reading your question:
DFS:
not usable on infinite trees (because you might go down an infinite branch). Or if there are cycles in your search graph you must take precaution to avoid running in a cycle forever.
you will most likely not find the nearest solution first
you need only O(depth) memory
BFS
the first solution you find is one of the nearest ones
you will need quite a lot of memory, because the search tree might get very broad already at quite little depth.
works on infinite trees and cyclic structures without any precaution
Of cause you will find much more on wikipedia
BFS
DFS
I think I am fairly certain that the DFS algorithm for the problem should not be any different from a normal DFS, but just wanted to get some feedback from other. Here is my problem:
I would like to perform DFS on a graphs for which I do not know all the nodes. When I start the search all I know is just the start node. Based on the start node's properties, I can determine it's set of child nodes. The children of the nodes that have just been discovered can be further discovered as above.
I am planning to use an algorithm similar to a normal DFS (where the Graph is known before hand) except that every time I reach a node, I now need to discover it's child nodes.
Is this a reasonable approach? I am I missing something?
That seems like a perfectly reasonable approach.
However, without knowing the exact details of what you're trying to do, it's next-to-impossible to say for sure whether it will work or be the best approach.
If this is a large (possibly infinite) graph (or it contains cycles and there are too many nodes to keep track of all of them as you do the DFS to prevent getting stuck in a cycle) and you're looking for some node not too deep in the graph, either BFS or DFS with iterative deepening might be a better idea.
DFS stands for Depth First Search. and by "Search" it means it does not know what is ahead of it. So DFS on a known graph is no different from DFS on a graph where you get to know the child just at the time you reach the parent.
I know we can use DFS for maze exploration. But I think we can also use BFS for maze exploration. I'm little bit confused here because most of the books and articles that I've read had used DFS for this problem.
What I think is that the Best Case time complexity of DFS will be better as compared to BFS. But Average and Worst Case time complexity will be same for both BFS & DFS and thats why we prefer DFS over BFS.
Am I right or I'm having some misconception
I'm quite amazed that nobody has mentioned so far about the difference in results given by DFS and BFS.
The main difference between these two algorithms is that BFS returns the shortest path and DFS returns just a path.
So if you want to get the shortest path use BFS, otherwise consider other pros and cons (memory etc.)
They have similar running time, but either may greatly outperform the other on any given problem simply due to the order in which the cells are visited.
In terms of space usage, BFS will on average use more memory for trees, but for more general graphs, in certain cases, it could use significantly less memory.
For mazes specifically (if we define a maze as there being only one way to reach a cell from the starting point without backtracking, meaning it's essentially a tree), BFS will generally use more memory, as we'll need to keep multiple paths in memory at the same time, where DFS only needs to keep track of a single path at any given time.
For more general grids, it's much less obvious which one will be better in terms of memory, especially when considering how we keep track of cells we've visited thus far to prevent repeatedly visiting cells.
If you're not concerned about memory, you can pick either. If you're fairly comfortable with recursion, DFS should be easier to implement.
However, if you're looking for the shortest path to some given cell in a general grid, use BFS (or A*), as that guarantees to find the shortest path, where DFS does not (you can still use either in a maze where there's only a single path to any given cell).
Both should be equivalent. DFS is used more because it is a bit easier to implement.
BFS take too much memory, its not good for huge maze.
I have read about DFS and BFS many times but I have this doubt lingering my mind since long. In a lot of articles it is mentioned that DFS can get stuck in infinite loops.
As far as I know, this limitation can easily be removed by keeping track of the visited nodes. In fact, in all the books that I have read, this little check is a part of DFS.
So why are 'infinite loops' mentioned as a disadvantage of DFS? Is it just because the original DFS algorithm did not have this check for visited nodes? Please explain.
(1) In graph search algorithms [used frequently on AI], DFS's main advantage is space efficiency. It is its main advantage on BFS. However, if you keep track of visited nodes, you lose this advantage, since you need to store all visited nodes in memory. Don't forget the size of visited nodes increases drastically over time, and for very large/infinite graphs - might not fit in memory.
(2) Sometimes DFS can be in an infinite branch [in infinite graphs]. An infinite branch is a branch that does not end [always has "more sons"], and also does not get you to your target node, so for DFS, you might keep expanding this branch inifinitely, and 'miss' the good branch, that leads to the target node.
Bonus:
You can overcome this flaw in DFS, while maintaining relatively small memory size by using a combination of DFS and BFS: Iterative Deepening DFS
a conventional DFS algorithm does track down nodes. A local search algorithm does not track down states and behaves with amnesia. So I think the loop mainly refers to the one an infinite branch(a branch with infinite possible states). In that case, DFS simply goes down and become too focused on one branch.
If you do not check for cycles, then DFS can get stuck in one and never find its target whereas BFS will always expand out to all nodes at the next depth and therefore will eventually find its target, even if cycles exist.
Put simply:
If your graph can have cycles and you're using DFS, then you must account for cycles. On the other hand, BFS provides the option to ignore cycles at the expense of efficiency, which is often acceptable when searching a small number of nodes.
I keep reading about iterative deepening, but I don't understand how it differs from depth-first search.
I understood that depth-first search keeps going deeper and deeper.
In iterative deepening you establish a value of a level, if there is no solution at that level, you increment that value, and start again from scratch (the root).
Wouldn't this be the same thing as depth-first search?
I mean you would keep incrementing and incrementing, going deeper until you find a solution. I see this as the same thing! I would be going down the same branch, because if I start again from scratch I would go down the same branch as before.
In a depth-first search, you begin at some node in the graph and continuously explore deeper and deeper into the graph while you can find new nodes that you haven't yet reached (or until you find the solution). Any time the DFS runs out of moves, it backtracks to the latest point where it could make a different choice, then explores out from there. This can be a serious problem if your graph is extremely large and there's only one solution, since you might end up exploring the entire graph along one DFS path only to find the solution after looking at each node. Worse, if the graph is infinite (perhaps your graph consists of all the numbers, for example), the search might not terminate. Moreover, once you find the node you're looking for, you might not have the optimal path to it (you could have looped all over the graph looking for the solution even though it was right next to the start node!)
One potential fix to this problem would be to limit the depth of any one path taken by the DFS. For example, we might do a DFS search, but stop the search if we ever take a path of length greater than 5. This ensures that we never explore any node that's of distance greater than five from the start node, meaning that we never explore out infinitely or (unless the graph is extremely dense) we don't search the entire graph. However, this does mean that we might not find the node we're looking for, since we don't necessarily explore the entire graph.
The idea behind iterative deepening is to use this second approach but to keep increasing the depth at each level. In other words, we might try exploring using all paths of length one, then all paths of length two, then length three, etc. until we end up finding the node in question. This means that we never end up exploring along infinite dead-end paths, since the length of each path is capped by some length at each step. It also means that we find the shortest possible path to the destination node, since if we didn't find the node at depth d but did find it at depth d + 1, there can't be a path of length d (or we would have taken it), so the path of length d + 1 is indeed optimal.
The reason that this is different from a DFS is that it never runs into the case where it takes an extremely long and circuitous path around the graph without ever terminating. The lengths of the paths are always capped, so we never end up exploring unnecessary branches.
The reason that this is different from BFS is that in a BFS, you have to hold all of the fringe nodes in memory at once. This takes memory O(bd), where b is the branching factor. Compare this to the O(d) memory usage from iterative deepening (to hold the state for each of the d nodes in the current path). Of course, BFS never explores the same path multiple times, while iterative deepening may explore any path several times as it increases the depth limit. However, asymptotically the two have the same runtime. BFS terminates in O(bd) steps after considering all O(bd) nodes at distance d. Iterative deepening uses O(bd) time per level, which sums up to O(bd) overall, but with a higher constant factor.
In short:
DFS is not guaranteed to find an optimal path; iterative deepening is.
DFS may explore the entire graph before finding the target node; iterative deepening only does this if the distance between the start and end node is the maximum in the graph.
BFS and iterative deepening both run in time O(bd), but iterative deepening likely has a higher constant factor.
BFS uses O(bd) memory, while iterative deepening uses only O(d).
There is a decent page on wikipedia about this.
The basic idea I think you missed is that iterative deepening is primarily a heuristic. When a solution is likely to be found close to the root iterative deepening is will find it relatively fast while straightfoward depth-first-search could make a "wrong" decision and spend a lot of time on a fruitless deep branch.
(This is particularly important when the search tree can be infinite. In this case they are even less equivalent since DFS can get stuck forever while BFS or iterative deepening are sure to find the answer one day if it exists)
Just adding to what's already here, but here are some videos from University of Denver's Moving AI Lab that show the differences.
http://movingai.com/dfid.html
You can see in their examples iterative deepening wins when the goal is shallow (solution depth 3, tree depth) and the solution is on the right, but DFS wins no matter what if the solution is in the last row.
I got into this reading about chess programming, next up for me was thinking about quiescence search check that out if you want to know more about search strategies for AI programming.