My path-finding method is given two objects containing an id, name, x/y coordinates, and path stored in an Array List. The path data is the id of each object that it can directly connect to. The objective is to call my method recursively until it finds its goal using the shortest distance, and when it reaches the end it returns true.
The problem:
If the distance to the node that you came from is shorter than the other nodes in the current nodes path, then it will cause an infinite loop bouncing back and forth between the two nodes. I have struggled with this problem for several hours and could be over thinking it. Any advice or suggestions will be greatly appreciated!
The Algorithm:
while (!pathfound) {
current = findPath(current, end);
}
public static Place findPath(Place curPlace, Place endPlace) {
ArrayList<Integer> path = curPlace.path;
int id;
double lastdist = 999;
double distance;
Place bestPlace = null;
for (int i = 0; i < path.size(); i++) {
id = curPlace.path.get(i);
distance = distance(getPlace(id), curPlace)
+ distance(getPlace(id), endPlace);
if (distance < lastdist) {
bestPlace = getPlace(id);
}
lastdist = distance;
}
if (result.length() == 0) {
result += bestPlace.name;
} else {
result += ", " + bestPlace.name;
}
System.out.println("CURCITY: " + bestPlace.id);
System.out.println(result);
System.out.println(lastdist);
if (bestPlace == endPlace) {
pathfound = true;
}
return bestPlace;
}
You can ignore result, it is for keeping up with the nodes that are passed through. If there are any other details you would like to know, please ask.
If it is acceptable to modify Place you can add a boolean "visited" flag. Reset them all to false prior to running the algorithm; set to true when you visit and false when you leave (don't forget to unset them on the way out of the recursion - if you do this properly you can even avoid having to explicitly reset the flags before starting). Skip nodes where the flag is true.
A more short-sighted option is to pass the last visited Place as a parameter to the function, and skip that one. This will not prevent larger loops but may be entirely appropriate for your situation and is the simplest to implement.
Both of the above are O(1) with minimal overhead. If you cannot modify Place you could store a Set of visited places (remove them from the set on the way out of recursion), and skip places that are already in that set. Depending on your performance requirements, if you use a HashSet you will want to come up with an appropriate hashing function.
Along those lines, at the expense of more memory, if your ID numbers are unique and cover a reasonably sized finite range, a boolean[] indexed by ID number is a constant time alternative to a set here (it is essentially the "visited" flag option with the flags stored externally).
Using a recursive approach to path finding algorithm can be quite tricky, as you always need some kind of global information to evaluate, which one of two paths is more suitable. While following a single path, you can never be sure, if it is the right one. Even if you always follow the nearest node, it doesn't have to be the right path. This is called best-first search strategy and although it is not the best, it can be made to work, but you have to make sure to try other paths as well, because you can't pull it off by simply always sticking to the closest node.
If you want to do a path finding algorithm, you will need to keep track of all the nodes, that you have already explored exhaustively and therefore will never need to visit again. This can be done either explicitly, by storing the list of visited nodes in a structure of some kind, or you can be smarter about it and enforce this by good design of policy for selecting a new node to be visited.
In other words, if you keep track of the nodes to be visited along with the distances to each node (priority queue) and you always make sure to visit the nearest not-yet-visited node, you will never revisit the same nodes again, without having to explicitly enforce it, such as in A* algorithm, or Dijkstra.
Related
As the title states I'm trying to write an algorithm that generates accepted strings to an upper bound from a given DFA (Deterministic Finite Automata) on input.
It should not generate more strings than the upper bound n if it contains cyclic patterns, because obviously I can't print an infinite amount of strings, which leads me to my problem.
Machines with finite languages are very straight forward as I can just do a DFS search and traverse through the graph and concatenate all letters that connect the states recursively, but I have no clue how I should deal with infinite language DFAs unless I hardcode a limit on how many times the DFS should traverse states that can potentially lead to cycles.
So my question is; how should go about approaching this problem. Are there any known algorithms that I could use to tackle this task?
the bound specifies the number of strings, not the length of them. The string length is not allowed to exceed 5000 characters, but should preferably not come near that in length, as the max bound, n, is 1000 at most on the tests.
My current and very naive solution is the following:
public void generateStrings(int currentStateNum, Set<String> output, String prefix, Set<Integer> traversedStates){
State currentState, tempState;
String nextString;
currentState = dfa.get(currentStateNum);
//keeps track of recursion track, i.e the states we've already been to.
//not in use because once there are cyclic patterns the search terminates too quickly
//traversedStates.add(currentStateNum);
//My current, bad solution to avoid endless loops is by checking how many times we've already visited a state
currentState.incrementVisited();
//if we're currently looking at an accepted state we add the current string to our list of accepted strings
if(currentState.acceptedState){
output.add(prefix);
}
//Check all transitions from the current state by iterating through them.
HashMap<Character, State> transitions = currentState.getTransitions();
for (Map.Entry<Character, State> table : transitions.entrySet()) {
//if we've reached the max count of strings, return, we're done.
if (output.size() == maxCount) {
return;
}
tempState = table.getValue();
//new appended string. I realize stringbuilder is more efficient and I will switch to that
//once core algorithm works
nextString = prefix + table.getKey().toString();
//my hardcoded limit, will now traverse through the same states as many times as there are states
if (tempState.acceptedState || tempState.getVisitedCount() <= stateCount) {
generateStrings(tempState.getStateNum(), output, nextString, traversedStates);
}
}
}
It is not really a dfs because I don't check which states I've already visited, because if I do that, everything that will be printed is the simplest path to the nearest accept state, which is not what I want. I want to generate as many strings as required (if the language for the DFA is not finite, that is).
This solution works up until a point where either the "visit limit" that I chose arbritarily no longer cuts it, so my solution is somewhat or entirely incorrect.
As you can see my datastructure for representing automata is an ArrayList with states, where State is a separate class that contains a HashMap with transitions, where the key is the edge char and the value is the state that the transition leads to.
Does anyone have any idea how I should proceed with this problem? I tried hard to find similar questions but I couldn't find anything helpful more than some github repos with code that is way too complicated for me to learn anything from.
Thanks a lot in advance!
I would use a bounded queue of objects representing the current state and the string generated so far, and then proceed with something like the following,
Add {"", start} to the queue, representing the string created so far (which is empty) and the start state of the DFA.
As long as there is something on the queue
Pop the front of queue
If the current state is accepting, add the currentString to your result set.
For each transition from this state, add entries to the queue of the form {currentString+nextCharacter, nextState}
Stop when you've hit enough strings, or if the strings are getting too long, or if the queue is empty (finite language).
I know how to construct a kd tree .But the problem that i am facing is how to find nearest neighbour using KD Tree.I have searched on google but not able to find code for finding nearest neighbour,though algos are given . But I am facing difficulty in converting that algo into code because of Language.
Can you please provide me understandable code for NNSearch in java?
Here is pseudocode that assumes the target point is not stored in the tree. (If it is, just add logic to ignore it):
nearest_point = NULL
nearest_distance = INFINITE;
target_point = <set to the target point>
void nn_search(KD_NODE node) {
FLOAT d = node->point.distance_to(target_point);
if (d < nearest_distance) {
nearest_distance = d;
nearest_point = node->point;
}
BOX left_bb = node->left.bounding_box();
BOX right_bb = node->right.bounding_box();
if (left_bb.contains(target)) {
search_children(node->left, node->right, right_bb);
else { // right_bb must contain target
search_children(node->right, node->left, left_bb);
}
}
void search_children(KD_NODE a, KD_NODE b, BOX b_bb) {
nn_search(a);
// This condition makes the search expected O(log n) time rather than O(n).
// Skip searching the other child unless it might improve the answer.
if (b_bb.contains_point_closer_than(target, nearest_distance)) {
nn_search(b);
}
}
After this has run, nearest_point contains the nearest point to the target. Note that it's simple to compute the bounding boxes as parameters of nn_search rather than storing them inside the nodes, which this code appears to do. In production code you'd want to do that to save the space of 4 floats per node. I've omitted the parameters for simplicity.
The predicate contains_point_closer_than returns true if there exists any point in the bounding box that's closer to the target than the given distance. Happily it's enough to consider only one point in the box. E.g if the current node splits the search space into left and right halves at X, then you only need to consider the point (X, Y_target) and its distance to the target. That distance is just abs(X - X_target)! I'll let you convince yourself of this without further discussion
I know two Java kd-tree implementations that support kNN search, here and here. Theirs performance appears to be roughly equivalent.
I have an implementation of depth-first search for a directed graph with same size edges. This search changes the state of the nodes in my graph. So if I want to do a new search all nodes have to be reset to default.
My implementation:
public void resetGraph() {
ListItem temp = nodes.getHead();
while(temp != null){
DiGraphNode node = temp.key;
node.visitorState = VISITORS.NONE; //Set all nodes their initial state
node.sumOfDistances = 0;
temp = temp.next;
}
}
=> This takes some time for a large graph
Is there a way to do this more time efficient ?
Maybe someting like:
DiGraphNode.someStaticMethod(0);
As your structure stands at the moment there is little you can do - you must visit every node to reset it so you are stuck with an O(n) algorithm.
One possible solution that may improve performance a little would be to keep track of all of your visitorState and sumOfDistances fields in an array. You could then use a int nodeID (generated at node construction time perhaps) to access the state and sum. The benefit of this tweak would be to allow you to use Arrays.fill which may make use of cpu-specific block-set instructions.
You will not be able to change the order of the algorithm but you might find some speed-up this way.
When solving the Chinese postman problem (route inspection problem), how can we find the pairings (between odd vertices) such that the sum of the weights is minimized?
This is the most crucial step in the algorithm that successfully solves the Chinese Postman Problem for a non-Eulerian Graph. Though it is easy to implement on paper, but I am facing difficulty in implementing in Java.
I was thinking about ways to find all possible pairs but if one runs the first loop over all the odd vertices and the next loop for all the other possible pairs. This will only give one pair, to find all other pairs you would need another two loops and so on. This is rather strange as one will be 'looping over loops' in a crude sense. Is there a better way to resolve this problem.
I have read about the Edmonds-Jonhson algorithm, but I don't understand the motivation behind constructing a bipartite graph. And I have also read Chinese Postman Problem: finding best connections between odd-degree nodes, but the author does not explain how to implement a brute-force algorithm.
Also the following question: How should I generate the partitions / pairs for the Chinese Postman problem? has been asked previously by a user of Stack overflow., but a reply to the post gives a python implementation of the code. I am not familiar with python and I would request any community member to rewrite the code in Java or if possible explain the algorithm.
Thank You.
Economical recursion
These tuples normally are called edges, aren't they?
You need a recursion.
0. Create main stack of edge lists.
1. take all edges into a current edge list. Null the found edge stack.
2. take a next current edge for the current edge list and add it in the found edge stack.
3. Create the next edge list from the current edge list. push the current edge list into the main stack. Make next edge list current.
4. Clean current edge list from all adjacent to current edge and from current edge.
5. If the current edge list is not empty, loop to 2.
6. Remember the current state of found edge stack - it is the next result set of edges that you need.
7. Pop the the found edge stack into current edge. Pop the main stack into current edge list. If stacks are empty, return. Repeat until current edge has a next edge after it.
8. loop to 2.
As a result, you have all possible sets of edges and you never need to check "if I had seen the same set in the different order?"
It's actually fairly simple when you wrap your head around it. I'm just sharing some code here in the hope it will help the next person!
The function below returns all the valid odd vertex combinations that one then needs to check for the shortest one.
private static ObjectArrayList<ObjectArrayList<IntArrayList>> getOddVertexCombinations(IntArrayList oddVertices,
ObjectArrayList<IntArrayList> buffer){
ObjectArrayList<ObjectArrayList<IntArrayList>> toReturn = new ObjectArrayList<>();
if (oddVertices.isEmpty()) {
toReturn.add(buffer.clone());
} else {
int first = oddVertices.removeInt(0);
for (int c = 0; c < oddVertices.size(); c++) {
int second = oddVertices.removeInt(c);
buffer.add(new IntArrayList(new int[]{first, second}));
toReturn.addAll(getOddVertexCombinations(oddVertices, buffer));
buffer.pop();
oddVertices.add(c, second);
}
oddVertices.add(0, first);
}
return toReturn;
}
So first of all I'm in a 100 level CS college class that uses Java. Our assignment is to make a tower defense game and I am having trouble with the pathing. I found from searching that A* seems to be the best for this. Though my pathing get's stuck when I put a U around the path. I'll show some beginner psuedo code since I haven't taken a data structures class yet and my code looks pretty messy(working on that).
Assume that I will not be using diagonals.
while(Castle not reached){
new OpenList
if(up, down, left, right == passable && isn't previous node){
//Adds in alternating order to create a more diagonal like path
Openlist.add(passable nodes)
}
BestPath.add(FindLeasDistancetoEnd(OpenList));
CheckCastleReached(BestPath[Last Index]);
{
private node FindLeastDistancetoEnd(node n){
return first node with Calculated smallest (X + Y to EndPoint)
}
I've stripped A* down(too much, my problem most likely). So I'm adding parents to my nodes and calculating the correct parent though I don't believe this will solve my problem. Here's a visual of my issue.
X = impassable(Towers)
O = OpenList
b = ClosedList(BestPath)
C = Castle(EndPoint)
S = Start
OOOOXX
SbbbBX C
OOOOXX
Now the capitol B is where my issue is. When the towers are placed in that configuration and my Nav Path is recalculated it gets stuck. Nothing is put into the OpenList since the previous node is ignored and the rest are impassable.
Writing it out now I suppose I could make B impassable and backtrack... Lol. Though I'm starting to do a lot of what my professor calls "hacking the code" where I keep adding patches to fix issues, because I don't want to erase my "baby" and start over. Although I am open to redoing it, looking at how messy and unorganized some of my code is bothers me, can't wait to take data structures.
Any advice would be appreciated.
Yes, data structures would help you a lot on this sort of problem. I'll try to explain how A* works and give some better Pseudocode afterwards.
A* is a Best-First search algorithm. This means that it's supposed to guess which options are best, and try to explore those first. This requires you to keep track of a list of options, typically called the "Front" (as in front-line). It doesn't keep track of a path found so far, like in your current algorithm. The algorithm works in two phases...
Phase 1
Basically, you start from the starting position S, and all the neighbouring positions (north, west, south and east) will be in the Front. The algorithm then finds the most promising of the options in the Front (let's call it P), and expands on that. The position P is removed from the Front, but all of its neighbours are added in stead. Well, not all of its neighbours; only the neighbours that are actual options to go. We can't go walking into a tower, and we wouldn't want to go back to a place we've seen before. From the new Front, the most promising option is chosen, and so on. When the most promising option is the goal C, the algorithm stops and enters phase 2.
Normally, the most promising option would be the one that is closest to the goal, as the crow flies (ignoring obstacles). So normally, it would always explore the one that is closest to the goal first. This causes the algorithm to walk towards the goal in a sort-of straight line. However, if that line is blocked by some obstacle, the positions of the obstacle should not be added to the Front. They are not viable options. So in the next round then, some other position in the Front would be selected as the best option, and the search continues from there. That is how it gets out of dead ends like the one in your example. Take a look at this illustration to get what I mean: https://upload.wikimedia.org/wikipedia/commons/5/5d/Astar_progress_animation.gif The Front is the hollow blue dots, and they mark dots where they've already been in a shade from red to green, and impassable places with thick blue dots.
In phase 2, we will need some extra information to help us find the shortest path back when we found the goal. For this, we store in every position the position we came from. If the algorithm works, the position we came from necessarily is closer to S than any other neighbour. Take a look at the pseudocode below if you don't get what I mean.
Phase 2
When the castle C is found, the next step is to find your way back to the start, gathering what was the best path. In phase 1, we stored the position we came from in every position that we explored. We know that this position must always be closer to S (not ignoring obstacles). The task in phase 2 is thus very simple: Follow the way back to the position we came from, every time, and keep track of these positions in a list. At the end, you'll have a list that forms the shortest path from C to S. Then you simply need to reverse this list and you have your answer.
I'll give some pseudocode to explain it. There are plenty of real code examples (in Java too) on the internet. This pseudocode assumes you use a 2D array to represent the grid. An alternative would be to have Node objects, which is simpler to understand in Pseudocode but harder to program and I suspect you'd use a 2D array anyway.
//Phase 1
origins = new array[gridLength][gridWidth]; //Keeps track of 'where we came from'.
front = new Set(); //Empty set. You could use an array for this.
front.add(all neighbours of S);
while(true) { //This keeps on looping forever, unless it hits the "break" statement below.
best = findBestOption(front);
front.remove(best);
for(neighbour in (best's neighbours)) {
if(neighbour is not a tower and origins[neighbour x][neighbour y] == null) { //Not a tower, and not a position that we explored before.
front.add(neighbour);
origins[neighbour x][neighbour y] = best;
}
}
if(best == S) {
break; //Stops the loop. Ends phase 1.
}
}
//Phase 2
bestPath = new List(); //You should probably use Java's ArrayList class for this if you're allowed to do that. Otherwise select an array size that you know is large enough.
currentPosition = C; //Start at the endpoint.
bestPath.add(C);
while(currentPosition != S) { //Until we're back at the start.
currentPosition = origins[currentPosition.x][currentPosition.y];
bestPath.add(currentPosition);
}
bestPath.reverse();
And for the findBestOption method in that pseudocode:
findBestOption(front) {
bestPosition = null;
distanceOfBestPosition = Float.MAX_VALUE; //Some very high number to start with.
for(position in front) {
distance = Math.sqrt(position.x * position.x - C.x * C.x + position.y * position.y - C.y * C.y); //Euclidean distance (Pythagoras Theorem). This does the diagonal thing for you.
if(distance < distanceOfBestPosition) {
distanceOfBestPosition = distance;
bestPosition = position;
}
}
}
I hope this helps. Feel free to ask on!
Implement the A* algorithm properly. See: http://en.wikipedia.org/wiki/A%2A_search_algorithm
On every iteration, you need to:
sort the open nodes into heuristic order,
pick the best;
-- check if you have reached the goal, and potentially terminate if so;
mark it as 'closed' now, since it will be fully explored from.
explore all neighbors from it (by adding to the open nodes map/ or list, if not already closed).
Based on the ASCII diagram you posted, it's not absolutely clear that the height of the board is more than 3 & that there actually is a path around -- but let's assume there is.
The proper A* algorithm doesn't "get stuck" -- when the open list is empty, no path exists & it terminates returning a no path null.
I suspect you may not be closing the open nodes (this should be done as you start processing them), or may not be processing all open nodes on every iteration.
Use a Map<GridPosition, AStarNode> will help performance in checking for all those neighboring positions, whether they are in the open or closed sets/lists.