Constructing a tree from an array for a DFS solver - c++

I am making a maze solver using DFS and I want to implement the search tree for it but I am a bit new to artificial intelligence and I want a little bit of help on this matter.
Let me give a maze example first:
char maze[5][9] =
"#########",
"# # #",
"# ## # #",
"# # #",
"#########",
So my search tree for DFS should be something like this:
"#########",
"#12#15 10 11 #",
"#3##14 9 #12 #",
"#456 7 8 #13 #",
"#########",
1st child of parent -> Right Cell if it is empty
2nd child of parent -> Bottom Cell if it is empty
3rd child of parent -> Left Cell if it is empty
4th child of parent -> Top Cell if it is empty
My solver will receive as an argument my maze array. My questions are these:
1st question: Is this actually the way the nodes are going to get visited by my actor?
2nd question: In the code do I need to declare 15 as child of 10? (also in other cases like 9 with 14)
3rd question: When my solver receives the array do I need to make a pre-process on the array and construct the tree from the array or will my actor construct it as he goes?

I also assume the rule of "do not include a node in the solution tree if it was already in the tree"? Because that sure helps.
Typically the tree is implicit, and you only construct the parts of the tree you actually visit, often tearing things down as you roll it back.
Your solver keeps track of the current steps along the tree. You probably also want to keep track of what cells you have explored in the maze. If the maze has only # and characters, use * to indicate you have visited the cell in this solver.
You start at some location. If that location is valid, you mark it with a * so you don't come back to it, and add that location (say, (1,1))to your "stack" of your path.
Now, you follow the rules you wrote above. Check the cell under your current location. Is it empty? (not a # or a *) If so, recurse, asking if that finds the way out.
If it finds the way out, take the path it found, prepend your current node, and return that path as the way out.
If it does not, search in the next adjacent cell (by the order above).
Finally, wrap the above recursive routine with a function that calls it, then removes the * marks from the map.
The tree you walk is implicitly coded. Building the tree forces you to visit every node, and you only want to build the parts that you have to.
This can be optimized in a number of ways. You can avoid writing to the map by working on a "ghost" copy of it. You can avoid prepending by passing the stack to the recursive versions, which carefully remove any extra nodes if they fail, and leave them on if they succeed. Or you can use a real stack, and encode the path backwards, with a wrapping function that (after all the work is done) reverses the path so it is in a more conventional order.

Related

Dijkstra by means of Heap and pred-field

I have the following task, but I have no idea how to do it?
Calculate (lexicographically) the shortest path from V1-node to the other nodes by means of Dijkstra. Please write the current Heaps and corresponding Pred-fields as well. Start with new Heap and pred-field before the ExtractMin-Call.
I got this result via Dijkstra, but how should I add it to the min-heap (tree)?
I found exactly this task in an old exam I use for learning algorithms. I wasn't sure how to solve it so I searched several books for any explanation on how the minheap works along with Dijkstra and didn't find any. Finally I figured it out. So I hope this helps to understand how to solve this problem.
Step 1: Draw the heap lexicographically: V1 -> root, and then the
other nodes from left to right. V1 has the value 0, all other nodes
inf.
Step 2: ExtractMin(): swap root (which has the lowest value)
with the very last node and cut it off.
Step 3: Relaxation: Update new values for the nodes, if value decreases. "What is the new value from start to X when
I walk via the node, I just extracted, respecting its predecessors? Is it less than the old value, then update."
Step 4: Update the predecessor field if there is a better path.
Step 5: Call Heapify(): Resort the heap, so that
the node with the lowest value becomes root.
Repeat Step 2 to 5 until there are no nodes left.

maze solver in C++ [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have made a maze generator using Depth First Search which returns an array of pounds and spaces to indicate a maze. Example:
char maze[height][width] =
{
"#########",
"# # #",
"# ### # #",
"# # # #",
"# # # ###",
"# # # #",
"# ### # #",
"# # #",
"#########",
};
The agent will always start at the top left corner (maze[1][1]) and exit at the bottom right corner (maze[7][7]).
I am trying to make the solver now using Depth First Search.
The problem is I am quite a beginner to intermediate programmer so I am having a hard time understanding how to implement the Depth First Search in C++ and I'm having an even harder time implementing it for the maze.
I have a basic knowledge of stacks, queues etc. I also know how DFS works in a tree (pretty much in theory) but my main problem is how I would go to implement this in a maze which is stored in a 2D array.
I want to learn specifically DFS so I can get started and then I'll implement other search tactics (like BFS for example) to start getting a hand on AI.
EDIT: I don't want ready code!!! I want you to help me understand how to transfer pseudocode to C++ for a maze!
So the basic operation of a depth first search is:
This works the same for any arbitrary graph as for a tree. A tree is just a special case. You can even visualize your maze as a tree:
#########
#123# #
#4### # #
#5# # #
# # # ###
# # # #
# ### # #
# # #
#########
The only difference between using this algorithm on a tree vs. an arbitrary graph is that it's implicitly known which nodes in a tree have been visited, due to the hierarchical structure of a tree. With an arbitrary graph you might have a structure like:
#####
#187#
#2#6#
#345#
#####
And when examining node eight you don't want to treat node one as a new place to visit.
With your maze one way to remember which nodes have been visited would be to fill them in with '#' as soon as you encounter them.
I have pretty much figured out how to represent the position of the agent, how to move him around and such but my problem mostly is in how to use the stack for keeping track of which places the agent has been. By what I've found in google some keep a stack of the visited places but I never really understood when to remove positions from the stack, that's my biggest confusion
The stack itself is not used to keep track of which places are visited. It only keeps track of the current 'path' taken through the maze. When you reach a dead end nodes get removed from the stack; Those nodes must remain marked as visited even though they are removed from the stack. If removing those nodes also causes those nodes to be 'unvisited' then your search may continually try and retry dead ends.
I recommend that you first draw out a few little mazes and walk through them by hand using the flow chart above. This will give you a better understanding of the algorithm. Here are some example mazes:
Start at O, finish at X
#### ##### ##### #####
#OX# #O X# #O#X# #O #
#### ##### ##### # #X#
#####
Then consider each box in the flow chart and think about what data it uses, how to represent that data, and how to implement the box's action in code using that data.

Convert array to nodes

Let me start off with saying that I have very basic knowledge of nodes and graphs.
My goal is to make a solver for a maze which is stored as an array. I know exactly how to implement the algorithm for solving (I'm actually implementing a couple of them) but what my problem is, is that I am very confused on how to implement the nodes that the solver will use in each empty cell.
Here is an example array:
char maze[5][9] =
"#########",
"# # #",
"# ## ## #",
"# # #",
"#########"
My solver starts at the top left and the solution (exit) is at the bottom right.
I've read up on how nodes work and how graphs are implemented, so here is how I think I need to make this:
Starting point will become a node
Each node will have as property the column and the row number
Each node will also have as property the visited state
Visited state can be visited, visited and leads to dead end, not visited
Every time a node gets visited, every directly adjacent, empty and not visited cell becomes the visited node's child
Every visited node gets put on top of the solutionPath stack (and marked on the map as '*')
Every node that led to a dead end is removed from the stack (and marked on the map as '~')
Example of finished maze:
"#########",
"#*~#****#",
"#*##*##*#",
"#****~#*#",
"#########"
Basically my question is, am I doing something really stupid here with my way of thinking (since I am really inexperienced with nodes) and if it is could you please explain to me why? Also if possible provide me other websites to check which implement examples of graphs on real world applications so I can get a better grasp of it.
The answer really depends on what you find most important in the problem. If you're searching for efficiency and speed - you're adding way too many nodes. There's no need for so many.
The efficient method
Your solver only needs nodes at the start and end of the path, and at every possible corner on the map. Like this:
"#########",
"#oo#o o#",
"# ## ## #",
"#o oo#o#",
"#########"
There's no real need to test the other places on the map - you'll either HAVE TO walk thru them, or won't have need to even bother testing.
If it helps you - I got a template digraph class that I designed for simple graph representation. It's not very well written, but it's perfect for showing the possible solution.
#include <set>
#include <map>
template <class _nodeType, class _edgeType>
class digraph
{
public:
set<_nodeType> _nodes;
map<pair<unsigned int,unsigned int>,_edgeType> _edges;
};
I use this class to find a path in a tower defence game using the Dijkstra's algorithm. The representation should be sufficient for any other algorithm tho.
Nodes can be of any given type - you'll probably end up using pair<unsigned int, unsigned int>. The _edges connect two _nodes by their position in the set.
The easy to code method
On the other hand - if you're looking for an easy to implement method - you just need to treat every free space in the array as a possible node. And if that's what you're looking for - there's no need for designing a graph, because the array represents the problem in a perfect way.
You don't need dedicated classes to solve it this way.
bool myMap[9][5]; //the array containing the map info. 0 = impassable, 1 = passable
vector<pair<int,int>> route; //the way you need to go
pair<int,int> start = pair<int,int>(1,1); //The route starts at (1,1)
pair<int,int> end = pair<int,int>(7,3); //The road ends at (7,3)
route = findWay(myMap,start,end); //Finding the way with the algorithm you code
Where findWay has a prototype of vector<pair<int,int>> findWay(int[][] map, pair<int,int> begin, pair<int,int> end), and implements the algorithm you desire. Inside the function you'll probably need another two dimensional array of type bool, that indicates which places were tested.
When the algorithm finds a route, you usually have to read it in reverse, but I guess it depends on the algorithm.
In your particular example, myMap would contain:
bool myMap[9][5] = {0,0,0,0,0,0,0,0,0,
0,1,1,0,1,1,1,1,0,
0,1,0,0,1,0,0,1,0,
0,1,1,1,1,1,0,1,0,
0,0,0,0,0,0,0,0,0};
And findWay would return a vector containing (1,1),(1,2),(1,3),(2,3),(3,3),(4,3),(4,2),(4,1),(5,1),(6,1),(7,1),(7,2),(7,3)

Binary tree Breadth-first search

I'm using OCaml. I have type:
type 'a bt = Empty | Node of 'a * 'a bt * 'a bt;;
Also I have example BST:
let tree = Node(1,Node(2,Node(4,Empty,Empty),Empty),Node(3,Node(5,Empty,Node(6,Empty,Empty)),Empty));
I need to write function: breadthBT : 'a bt -> 'a list which will be Breadth-first search traversal. For above example tree it should returns [1; 2; 3; 4; 5; 6]
How to write that function? I can write only following function which uses DST :
let rec breadthBT tree =
if tree=Empty then []
else let Node(w,l,r)=tree in (w::breadthBT l)#breadthBT r;;
Above function returns (for example tree) [1; 2; 4; 3; 5; 6]. But I can't write function which uses BFS. Could you help me?
It is not a compilable solution. Just a tip.
You should iterate from top level root node to deep level nodes. Let our function receives accumulator for the answer and list of nodes (your 'a bt values) as second parameter. You can map this list by getting first element of triple and than you receive next part of answer. Also you need to evaluate next level of tree. For every node there are at most two descendants. You can map your list and apply _a_function_to receive list of descendants. It will be next level of your tree. And than --- recursion.
A will not specify this _a_function_. Try to study what is concatMap in google.
Happy hacking!
Imagine you stick your nose to the tree. Is it possible to traverse the tree in the breadth-first manner without bookmarking positions in your notepad? No, because the order can make you jump from one branch to another unrelated branch. So you need a notepad with "remaining positions to visit". You pick the next remaining position from the notepad and jump to it blindly. Since you erase visited positions from the notepad, you are at a node you have not visited yet. And since you cannot get up the tree without visiting intermediate nodes, you haven't visited the two nodes now above you. But you resist the instinct to climb the branches directly -- heck, this is breadth first order. You do not want to forget about these two unvisited nodes, so you want to put them into the notebook. Where do you put them, in front of the notebook or on its back? On the back of course, otherwise you would pick one of them immediately and that's what we want to avoid. Et voila: your notepad is a FIFO queue of nodes, which you keep (i.e. pass) around as an accumulator, but also consume to pick a subtree to visit.

Adding data to binary tree

I need help with adding data to a tree. For example if i have 7+8*9-18/(1+2), how am I supposed to add it to a binary tree in a way that i can compute the result using a binary tree. I am beginner in learning tree structures so I am not very familiar with it.
After converting the post fix expression to infix, follow the below steps to construct a tree.
If it is number, add it to add to the stack.
If is is an operator, make the operator as parent node,
pop the element and make it as right child to the parent node,
pop the element and make it as left child to the parent node
and add the parent node to the stack.
See How to write an evaluator for a string like "(1+3 * ( 5 / 4)) and get a numeric result and the Shunting Yard Algorithm