I´ m trying to implement the A* search algorithm in Java, and I have a question:
How many times I need to run a A* loop, until there is clearly no existing path?
For Example: If i have a for-loop; how long should "i" increase?
When you have explored all nodes that you can reach with A*, without finding your goal, then you can assume that there is no path.
I think you are thinking of A* the wrong way.
You run it until there are no more nodes to search. If you havent reached your target by then there is no path.
Psuedo:
//Our list of still open nodes
List<Node> nodesToSearch = new List<Node>();
while (nodesToSearch.Count > 0)
{
//SearchNode, if its our target we are done
//Add reachable neighbours to the list of nodes to search. So next iteration we will continue on searching those
//Remove current node.. since its searched
}
//If we end up here without a target there is no path.
//That means we have searched all nodes and their neighbours etc etc etc. Without reaching the target.
Related
I need java code that chooses the shortest path between two words with each step only changing one letter. I could only implement code that returns with the shortest path.
Problem Restatement
In this question, the find function (remark: the name find does not seem to
be appropriate. Better use findPath, IMHO) returns a list of words from a
dictionary of words stored in a string list. A sample dictionary text file
for the example below can be found in the question.
The findPath function takes three arguments:
A starting word,
a target word,
a dictionary (a list of words).
The find function tries to 'connect' the starting word to the target
word through a finite 'path' made of different 'steps', i.e. different
words all belonging to the dictionary, but each one differing only by one
letter from the previous word.
For example,
>>> find('hide', 'seek', words)
['hide', 'bide', 'bids', 'beds', 'bees', 'sees', 'seek']
This is a 6-step Path made of 7 words.
The current implementation yields only one path amongst all possible shortest
paths connecting two words, or 'None' if no such path exists. The question is
then:
How should I modify it to yield instead a list of all possible paths of a
certain length, given that no words should be connected only once in
a valid path?
Analysis of the current algorithm
The algorithm will be described by a graph analogy.
The algorithm builds the 'visited' dictionary as a tree that originates with
'None', goes to the 'start' word, then branches from the 'start' word to every
word that can be connected to it.
The algorithm then continues by examining every new single added node ('curr'
string), in the order it was added to the tree. The algorithm keeps track of
the words that have been included in the tree with the 'queue' list, so that
if a word is met again, it will not be considered again.
Once the 'target' word is added to the tree, nothing happens, and this is a
small pity. One must wait that the 'target' word is examined, to
detect that a path has been found.
When the 'target' word is examined, then the path is returned in a quick
and elegant way by simply browsing back the tree to the root
if curr == target:
path = []
while curr:
path.insert(0, curr)
curr = visited[curr]
return path
Current algorithm properties
In the current form and with the sample dictionary, the tree starting with
'None->lead' has the following branches:
bead dead head mead read load lend leud lewd leaf leak leal lean leap lear leas
Please note that the current algorithm returns a path that is a function
of the order in which the words are considered, basically the order of
the words in the dictionary and the order of the given arguments. Therefore,
as stated in the comment, the current algorithm is able to find one
or two shortest path, since we can invert the order of the arguments, e.g.
>>> find("hide", "seek", words))
['hide', 'bide', 'bids', 'beds', 'bees', 'sees', 'seek']
but
>>> find("seek", "hide", words)
['seek', 'meek', 'merk', 'mirk', 'mire', 'hire', 'hide']
so that hide->hire->mire->mirk->merk->meek->seek can be found immediately
as an alternate shortest path.
Problem analysis
There are two levels of innovation in the question you ask. Firstly, the
algorithm should cover all possible shortest paths, not only the first path
being found. Secondly, the algorithm should take an additional number 'n'
and yield back all possible paths of length 'n'.
Covering all possible shortest paths
The shortest possible path, if it exists, has at least so many
number of steps as letters differing in the two words.
Suppose that you want to connect 'lead' to 'heal'. There are two letters
difference and a possible shortest path is 'lead->head->heal'. If 'head' was
missing in the dictionary and 'leal' was present, then an alternate shortest
path would be 'lead->leal->heal'. If both 'head' and 'leal' were missing, the
shortest path would be longer than 2.
In general, if you scramble your dictionary (change the order
of the words), you should be able to obtain a different shortest path
with the same algorithm. But to be sure to obtain all possible paths,
you should perform an extremely high number of scramble operations
and that looks to me inefficient.
Covering all possible paths
Suppose that you want to connect 'lead' to 'heal'. A possible shortest
path is 'lead->head->heal'.
If you want to consider all possible paths,
you must consider also 'lead->dead->head->heal', 'lead->read->head->heal',
'lead->dead->read->head->heal', etc., and in some cases some paths that
have the same content of words as other paths, but with partly permutated order as for
'lead->read->dead->head->heal'
Conclusions
It is evident that the current tree structure is unfit to describe all of
the possible paths, because in the tree structure a single node is
asymmetrically connected on one side with its parent, and on the other
side with all of his children. This asymmetry prevents any possibility
to consider all possible paths, unless you are ready to duplicate the
tree a very large number of times (but I would not suggest doing so), to cover
all possibly existing trees.
Suggestions
1) Divide your problem in two different steps, the first 'covering all
possible shortest paths', the second 'covering all possible paths of length n'.
Attack the easiest problem and solve it considering the second problem, i.e.
do not accept a solution that would be incompatible with the second problem.
2) Reduce the size of your dictionary to a dozen words that you select such to
offer you the possibility to test quickly your algorithm. e.g.
heal
head
leal
real
seal
lead
read
some
more
word
allows you to test if you can find or not the two possible shortest paths between
'lead' and 'heal'.
3) Change of data structure. Leave behind the visited dictionary and its tree,
and use instead another data structure. I would suggest to use a list of lists
covering all possible shortest paths, i.e. in the example above there could
be one different list for each possible path
[lead, leal]
[lead, head]
[lead, read]
[lead, leal, real]
[lead, leal, seal]
[lead, leal, heal] *solution*
[lead, head, read]
[lead, head, heal] *solution*
4) Build a solid testbench : determine by yourself what is the
expected output for a given problem and work on the code until your test
succeed. Only then, complexify your test and debug your code again.
I have a project that is given on my Artificial Intelligence course. I need to implement Greedy Search algorithm for my program. Description of my project is:
Two text files called “tree.txt” and “heuristic.txt” are given. “tree.txt” will define the search tree where each line will contain a parent-child relation and a path cost between them. Each data will be seperated with a space.
e.g.
A B 5
A C 3
B D 6
The first character in the first line will be the Start node (A in here) and the goal node will be “G”.
“heuristic.txt” will define the heuristic, h(n), values. Each line will contain the heuristic value of each node. Each data will be seperated with a space.
e.g.
A 20
B 15
C 18
Output:
The program should give the solution path and the path cost from start node to goal.
Now my problem is that i am familiar with Greedy Search theoretically, but never implemented it practically in coding. I really dont know from where to start. We are free to develop our program in any language. Mostly, i have skills in Java and C#. If anybody can give me some ideas, or help me with any similar examples or tutorials. Any kind of help will be greatly appreciated. Sorry for so much writing. Thank you in advance:)))
I suggest this solution using python.
To implement the graph in your program use a simple python dictionary. Here's the code:
class Tree:
def _init_(self,dict,heuristic):
self.tree=tree
self.heuristic=heuristic
def getHeuristicValue(self,state)
value=self.heuristic.get(state)
return value
The constructor call is something like:
g = Graph({'A':{'B':5,'C':3},'B':{'D':6}},{'A':20,'B':15,'C':18})
The getHeuristic python function pass accepts a state as an argument and returns the value of the heuristic of this state.
To learn about python's dictionary class I suggest you read the tutorial
To implement the search algorithm with python you should implement this simple pseudocode:
function Tree-Search(initialNode,goalNode) returns a solution,or failure
frontier.push(initialNode) with the value of the function heuristic(initialNode.state)+the path cost to reaxh this node
while(frontier)
node<-frontier.pop()
if node.state==GoalNode.state
return node
expand node, adding the resulting nodes to the frontier
return None
For the frontier you must use a priority queue because you must pop the node with the lower value of g(n)+h(n) (where g(n) is the path cost to reach this node and h(n) is the value of the heuristic function).
To implement priority queue you should use a heap of the standard library heapq
The node is a data structure that must contain four components:
node.state:the state in the state space to which the node corresponds.
node.parent:the node in the search tree that generated this node.
node.action: the action that was applied to the parent to generated the node.
node.pathCost: is g(n),the cost of the path from the initial state to the node.
Lastly, for expanding the node, you can use this python function:
def actions(self,state):
'''return a tuple that contain the state child of state '''
return tuple(self.tree.get(state))
I suggest you to look this for your problem.
You can get the solution simply go back from the node.state that returns from the output of the algorithm while node.parent is not null that is your solution.
I hope this is useful for your project.
i have an assignement to find the longest path in a maze using recursion. i also have to show the process of searching for the path. I think i get the idea of how its supposed to be done but i get myself into truble when it comes to the code. Now i don't want the code done for me. I just need some pointers and some tips on my logic. . this is my recursive method so far. I guess there is no point sharing the graphics methods since the recursive method is where im stuck at.
void findPath(Point a){ // starting point
if (a == mazeEnd){
pathAdd(a);
return;
}
if (wall(a)) return;
if (visited(a)) return;
if (a == mazeStart) pathAdd(a);
length++
printPath;
findPath(new Point(a.x+1, a.y));
findPath(new Point(a.x, a.y+1));
findPath(new Point(a.x-1, a.y));
findPath(new Point(a.x, a.y-1));
}
UPDATE: ok thank you all for the tips and let me further explain. the entire board is a grid. i read the walls, starting and enting point from a file. i create a list for the walls and palce them on the board. wall(a) checks if a coordinate is the walls array. pathAdd is a method taht adds a coordinate to the path array. but doesnt that means that after it has complyted all the paths, the path array will have every coordinate in that board except the ones that are walls? At least in the wway i have coded it. Thats my major issue i think. If i can get the list to only hold one path i guess ill figure out how to get the largest out of it.
There's a few omissions I see.
You never add the current point to your path - you only ever add the start or the end.
You never mark any points as visited.
You check to see if things are visited, but you don't have a way of knowing if they were visited in this path or some other path. Consider the scenario where there is some islands of walls, and you could reach a point via two or more routes: one of those routes may be longer than the other routes, but you're more likely to reach it via the short route first. It will end up being ignored, when it should be considered as a candidate for both routes.
You are triggering length++ on every call to find path. If you do your first node, and then the 4 nodes around it, you're going to have a length of 5 when your longest is 2. That's no good!
If you passed a list into the method, when you found a path that made it to the end of the maze, you could add it to the list. then when recursion finishes, you can iterate through the list to find the longest path.
You are restricting to move further when a cell/point is visited. But I didn't see you marked a cell/point as visited in your code. You can do this just before moving into the four directions. If you do not do this, your recursion will never get an end.
findPath(a) should return a length. Specifically it should return the max(findPath(up) || findpath(down) || findPath(left) || findPath(right)) + 1. If wall(a) or visisted(a), you can return a large negative number and for mazeEnd(a) return 1. To print the path you need to add the new Point that returns the greatest length with pathAdd(). Hope that helps :)
I am using a Breadth first search in a program that is trying to find and return the shortest path between two nodes on an unweighted digraph.
My program works like the wikipedia page psuedo code
The algorithm uses a queue data structure to store intermediate results as it traverses the graph, as follows:
Enqueue the root node
Dequeue a node and examine it
If the element sought is found in this node, quit the search and return a result.
Otherwise enqueue any successors (the direct child nodes) that have not yet been discovered.
If the queue is empty, every node on the graph has been examined – quit the search and return "not found".
If the queue is not empty, repeat from Step 2.
So I have been thinking of how to track number of steps made but I am having trouble with the limitations of java (I am not very knowledgeable of how java works). I originally was thinking that I could create some queue made up of a data type I made that stores steps and nodes, and as it traverses the graph it keeps track of the steps. If ever the goal is reached just simply return the steps.
I don't know how to make this work in java so I had to get rid of that idea and I moved on to using that wonky Queue = new LinkedList implementation of a queue. So basically I think it is a normal integer queue, I couldn't get my data type I made to work with it.
So now I have to find a more basic approach so I tried to use a simple counter, this doesn't work because the traversal algorithm searches down many paths before reaching the shortest one so I had an idea. I added a second queue that tracked steps, and I added a couple counters. Any time a node is added to the first queue I add to the counter, meaning I know that I am inspecting new nodes so I am not a distance further away. Once all those have been inspected I can then increase the step counter and any time a node is added to the first queue I add the step value to the step queue. The step queue is managed just like the node queue so that when the goal node is found the corresponding step should be the one to be dequeued out.
This doesn't work though and I was having a lot of problems with it, I am actually not sure why.
I deleted most of my code in panic and frustration but I will start to try and recreate it and post it here if anyone needs me to.
Were any of my ideas close and how can I make them work? I am sure there is a standard and simple way of doing this as well that I am not clever enough to see.
Code would help. What data structure are you using to store the partial or candidate solutions? You say your using a queue to store nodes to be examined, but really the objects stored in the queue should wrap some structure (e.g. List) that indicates the nodes traversed to get to the node to be examined. So, instead of simple Nodes being stored in the queue, some more complex object would be needed to make available the information necessary to know the complete path taken to that point. A simple node would only have information about itself, and it's children. But if you're examining node X, you also need to know how you arrived to node X. Just knowing node X isn't enough, and the only way (I know of) to know the path taken to node X is to store the path in the object that represents a "partial solution" or "candidate solution". If this is done, then finding the length of the path is trivial, because it's just the length of this list (or whichever data structure chosen). Hope I'm making some sense here. If not, post code and I'll take a look.
EDIT
These bits of code help show what I mean (they're by no means complete):
public class Solution {
List<Node> path;
}
Queue<Solution> q;
NOT
Queue<Node> q;
EDIT 2
If all you need is the length of the path, and not the path, per se, then try something like this:
public class Solution {
Node node; // whatever represents a node in you algorithm.
int len; // the length of the path to this node.
}
// Your queue:
LinkedList<Solution> q;
With this, before enqueuing a candidate solution (node), you do something like:
Solution sol = new Solution();
sol.node = childNodeToEnqueue;
sol.len = parentNode.len + 1;
q.add(sol);
The easiest solution in order to track distance during a traversal is to add a simple array (or a map if you vertices are not indexed by integers).
Here is pseudo code algorithm:
shortest_path(g, src, dst):
q = new empty queue
distances = int array of length order of g
for i = 0 to order: distances[i] = -1
distances[src] = 0
enqueue src in q
while q is not empty:
cur = pop next element in q
if cur is dst: return distances[dst]
foreach s in successors of cur in g:
if distances[s] == -1:
distances[s] = distances[cur] + 1
enqueue s in q
return not found
Note: order of a graph is the number of vertices
You don't need special data structures, the queue can just contains vertices' id (probably integers). In Java, LinkedList class implements the Queue interface, so it's a good candidate for your queue. For the distances array, if your vertices are identified by integers an integer array is enough, otherwise you need a kind of map.
You can also separate the vertex tainting (the -1 in my algo) using a separate boolean array or a set, but it's not really necessary and will waste some space.
If you want the path, you can also do that with a simple parent array: for each vertex you store its parent in the traversal, just add parent[s] = cur when you enqueue the successor. Then retrieving the path (in reverse order) is a simple like this:
path = new empty stack
cur = dst
while cur != src:
push cur in path
cur = parent[cur]
push src in path
And there you are …
By independent nodes, I mean that the returned set can not contain nodes that are in immediate relations, parent and child cannot both be included. I tried to use Google, with no success. I don't think I have the right search words.
A link, any help would be very much appreciated. Just started on this now.
I need to return the actual set of independent nodes, not just the amount.
You can compute this recursive function with dynamic programming (memoization):
MaxSet(node) = 1 if "node" is a leaf
MaxSet(node) = Max(1 + Sum{ i=0..3: MaxSet(node.Grandchildren[i]) },
Sum{ i=0..1: MaxSet(node.Children[i]) })
The idea is, you can pick a node or choose not to pick it. If you pick it, you can't pick its direct children but you can pick the maximum set from its grandchildren. If you don't pick it, you can pick maximum set from the direct children.
If you need the set itself, you just have to store how you selected "Max" for each node. It's similar to the LCS algorithm.
This algorithm is O(n). It works on trees in general, not just binary trees.
I would take-and-remove all leaves first while marking their parents as not-to-take, then remove all leaves that are marked until no such leaves are left, then recurse until the tree is empty. I don't have a proof that this always produces the largest possible set, but I believe it should.
I've provided an answer to a question for the same problem, although the solution is in python, the explanation, algorithm, and test cases could be applicable.