I've managed to implement a* and i got the correct path.
The problem is how i can reconstruct the path from start to end, given that every node (from end to start) has a parent link, but not the first one, so my character doesn't know where to go first.
What I'm doing is returning the closed-list and starting from index 0 to x until I reach the end. This usually works well, but I know there's gotta be another way.
Also, what is the best way to check neighboring nodes?
I've made each node to create a rectangle and see if it intersects and that's how I know they're connected. I also use this technique with the player to know when a node has been reached.
Thanks!!
You have your target node (You can simply cache it once it is found).
Go up the tree (using the parent field) until you find a node without it, this node is your root. The path you found by going up the links, is the shortest path in reversed order.
I once addressed a similar question, regarding BFS instead of A*
EDIT: A simple way to reverse the stack back to the original is to put the nodes in a stack while you go from target to source, and when you find the source - start popping elements out the stack.
Related
I got a question which is to find the min cost from the least number node (1) to the largest number node (7).
The cost is the edge between nodes. I labeled them.
This problem got me to think of the Dijkstra which leads the time complexity for O((v+e) log v)
Any other better approach to solving this question efficiently?
The other requirement is to keep the path information, any thought to keep the path?
As others pointed out, the complexity is as you say and cannot be better. As #nico-schertler commented, searching from both sides in parallel (or taking turns) and stopping as soon as something touches is faster than doing just a search from one side, but it will have the same complexity. It is possible in this case (with fixed costs for the bidirectional edges) but it needs not be in the general case (e. g. cost depending on the already taken path) where Dijkstra is still applicable.
Concerning the keeping of the path: Of course, the whole thing often only makes sense if you get the path to be taken as an answer. There are two main approaches to get the path as a result.
One is to store the path already taken to a certain node along with the node in the lists (white/grey in the classical implementation). Each time you add a new node, you extend the path of its former node by one step. If you find the target node, you can directly return the path as a result (along with the cost sum). Of course this way means uses a lot of memory.
The other is to not store the origin node along with each new found node, so each node points to the node it was visited from first. Think of it as putting up signposts in each node how to go back. This way, if you find the target node, you will have to go backwards from each node to the one it was first visited from and build the path in reverse order in the process. Then you can return this path.
There is one thing about a star path finding algorithm that I do not understand. In the pseudocode; if the current node's (the node being analysed) g cost is less than the adjacent nodes g cost then recalculate the adjacent nodes g,h a f cost and reassign the parent node.
Why do you do this?
Why do you need to reevaluate the adjacent nodes costs and parent if it's gCost is greater than the current nodes gCost? I'm what instance would you need to do this?
Edit; I am watcing this video
https://www.youtube.com/watch?v=C0qCR18gXdU\
At at 8.19 he says: When you come across blocks (nodes) that have already been analysed, the question is should we change the properties of the block?
First a tip. You can actually add the time you want as a bookmark to get a video that starts right where you want. In this case https://www.youtube.com/watch?v=C0qCR18gXdU#t=08m19s is the bookmarked time link.
Now the quick answer to your question. We fill in a node the first time we find a path to it. But the first path we found to it might not be the cheapest one. We want the cheapest one, and if we find a cheaper one second, we want it.
Here is a visual metaphor. Imagine a running path with a fence next to it. The spot we want is on the other side of the fence. Actually draw this out, it will help.
The first path that our algorithm finds to it is run down the path, jump over the fence. The second path that we find is run part way down the path, go through the gate, then get to that spot. We don't want to throw away the idea of using the gate just because we already figured out that we could get there by jumping the fence!
Now in your picture put costs of moving from one spot to another that are reasonable for moving along a running path, an open field, through a gate, and jumping a fence. Run the algorithm by hand and you'll see that you figure out first that you can jump the fence, and then later that you really wanted to use the gate.
This guy is totally wrong because he says change the parent node however your succesors are based on your parent node and if you change parent Node then you you can't have a valid path because the path is simply by moving from parent to child.
Instead of changing parent, Pathmax function. It says that if a parent Node A have a child node whose cost (heuristic(A) <= heuristic(A) + accumulated(cost)) then set the cost of child equal to the cost of parent.
PathMax to ensure monotonicty:
Monotonicity: Every parent Node has cost greater or equal then the cost of it's child node.
A* has a property: It says that if your cost is monotonically increasing then the first (sub)path that A* finds is always the part of the final path. More precisely: Under monotonicity each node is reach first through the best path.
Do you see why?
Suppose you have a graph :(A,B) (B,C) (A,E) ,(E,D) here every tuple means they are connected. Suppose cost is monotonically increasing and your algortihm chooses (A,B),(B,C) and at this point you know your algorithm have chosen best path till now and everyother path which can reach this node,must have cost higher but if the cost is not monotonically increasing then it can be the case that (A,E) is cost greater than your current cost and from (E,D) it's zero. so you have better path there.
This algorithm relies on it's heuristic function , if it's underustimated then it gets corrected by accumulated cost but if it's over-estimated then it can explore extra node and i leave it for you why this happends.
Why do you need to re-evaluate an adjacent node that's already in the open list if it has a lower g cost to the current node?
Don't do this because it's just extra work.
Corollary: if you later come the same node from a node p with same cost then simply remove that node from queue. Do not extend it.
I'm trying to implement an algorithm to find a path between two nodes in a digraph which can have cycles.
I have readed a lot but I can't find anything that fits my requirements exactly (Dijkstra, Bellman–Ford, DFS, ...)
In my case, I have a function which gives me the following node (it can have different implementations) so, in the first version of my algorithm I just used that function to traverse the graph.
The problem, I can get blocked in a loop.
Solution 1: store nodes used and do not follow edges to that node.
This is not a good solution for me because I want to get into loops but not for infinite.
Solution 2: store edges used and do not use them twice. I can get into a loop but I can go out from an unused edge. But I still can get blocked if I have used all the edges which go out from a node and I reach that node again. I tried not to take into account used edges in this blocking situation but it's not a good solution because I can get into a llop for infinite (I think / not probed)
Now, I'm at the starting point and I want a good solution for my problem but I can't find it after some investigations.
My idea is to implement a DFS algorithm using a custom function to get the following node but I need to deal with the loop problem somehow.
I need an algorithm to find ANY path from point A to point B in a graph.
The problem is that finding out wich nodes can follow a specific one needs a quite lengthy matlab simulation, so i want to access as few nodes as possible.
I know some heuristics about the graph, I.E. every node has some coordinates and follow-up nodes are always "near" the previous one, but there is not always a connection between two close nodes.
I am not searching for an optimal path, or even a short one. I just need any connection.
My first try was some simple greedy algorithm that always picks a follow up node closest to the final node, but this ended in dead ends very often. This wouldn't be a problem, but i have no idea how to efficiently move out of a deadend, currently i simply move through all nodes inside the dead end until i find a better way.
Here is a drawing of an example where i already know the solution:
There are many nodes, so calculating the edges for every node in this small dead end on the top takes about 1h20min. (You can assume every pixel in the picture is a node.)
To put it in short words: how do i find a good way around the obstacle without looking at every node inside a whole area.
Sorry if this a silly question but i'm an engineer and never had a formal education in programming aside from making a LED blink.
Thanks in advance!
I'm learning about graph and DFS, and trying to do something similar to how ANT resolves the dependency. I'm confused about something and all the articles I read seems to assume everyone knows this.
I'm thinking of having a Map> with key = file, and value = set of files that the key depends on.
The DFS algorithm shows that I have to change the color of the node if it's already visited, that means the reference to the same fileNode must be the same between the one in key and the one in Set<> right?
Therefore, I'm thinking, each time a Node is created (including neighbor nodes), I would add it to one more Collection (maybe another Map?), then whenever a new Node is to be add to the graph (as key), search that Collection and use that reference instead? am I wasting too much space? How is it usually done? is there some other better way?
During my studies the DFS algorithm was implement like this:
Put all the nodes of a graph into a stack (this is a structure, where you can only retrieve and delete the first element).
Retrieve the first element, set it to seen, this can either be done through the coloring or by setting an attribute, lets call it isSeen, to true.
You then look at all the neighbors of that node, and if they are not seen already, you put them in the stack.
Once you looked at all the neighbors, you remove the node from the stack and retrieve the next element of the stack and do the same as for the first.
The result will then be, that all the nodes, that can be reached from the starting node, will have an attribute that is set to seen.
Hope this helped.