How to determinate the final path in A* [duplicate] - java

Blue-Walls
Green highlighted cells = open list
Red Highlighted cells = closed list
Hello, can anyone tell me how can i implement backtracking in a a star search algorithm?
I've implemented the a star search according to wiki, but it does not backtrack, what i mean by backtrack is that the open list(green cells) contains 2,0 and 3,3 as shown in the picture, upon reaching 2,0 the current node would "jump" to 3,3 since the cost is now more than 3,3 and continue the search from there, how can it be done so that it would backtrack from 2,0->2,1->2,2... all the way back to 3,3 and start the search from there?

your image is like 2d grid map
But your text suggest graph approach which is a bit confusing.
For 2D grid map the costs must be different between cells on path
You got too much of cost=100 in there and therefore you can not backtrack the path. You have to increase or decrease cost on each step and fill only cells that are near last filled cells. That can be done by recursion on big maps or by scanning whole map or bounding box for last filled number on small maps.
Look here for mine C++ A* implementation
The backtracking
Can be done by scanning neighbors of start/end cells after A* filling moving always to the smallest/biggest cost
In this example start filling from (2,0) until (3,3) is hit and then backtrack from (3,2) cost=8 to the smallest cost (always cost-1 for incremental filling). If you need the path in reverse order then start filling from (3,3) instead ...
speedup
Sometimes double filling speed up the process so: Start filling from both ends and stop when they join. To recognize which cell is filled from which point you can use positive and negative values, or some big enough ranges for costs.

You can follow backpointers from the two nodes until you reach the common ancestor (0,2), then print the nodes you visited when following from (2,0), followed by the the nodes you visited when following from (3,3), printed in reverse.
To find the common ancestor of two nodes in an A* search tree, just maintain the two "current nodes", and follow the backpointer of whichever has the higher g-cost, until the two current nodes are in the same place.
It bears mentioning that this is a weird thing to do, though. A* is not a stack-based traversal, so it doesn't backtrack.

Related

Fastest way to take top N closest vectors by cosine distance

I have a huge list of vectors (~100k) (representing words and calculated using random indexing) and have to find given 1 input word the top N closest vectors. The way I'm doing it now is do a complete sort by distance and then extract the top N results but this takes too much time to be usable, as I have to compute 100k distances. Is there a more efficient way to do it? The vectors are already normalized, so I just have to compute the dot product when calculating the distance.
The vectors are stored in a a Java HashMap<String, Vector>, where Vector is la4j class for sparse vectors.
You can put your vectors into a spatial-aware container, such as R-tree or k-d tree or PK-Tree.
This way you’ll be able to find the points without iterating through all your dataset, by only looking in a few adjacent cells. Don‘t forget you’ll need to search not just in a single cell, but in the adjacent cells as well, and in multi-dimensional space there’re a lot of neighbors.
Update: You still need to measure the distance manually. However, you will not need to iterate through all vectors.
One simple solution — define max distance, iterate all vectors within the cells within that distance, sort, pick the top N.
The most optimal solution (much harder to develop) — iterative search process. For example, start with the single cell where your input vector vX is, find N closest vectors in this cell. If the distance between vX and the N-th found vector (the farthest one) is less than the distance between vX and the nearest point of any cell that’s not yet being searched, then you have your N results. Otherwise, add the vectors from the nearest cell that was not yet searched, and repeat the process. The most complex thing here — keeping track on what cells are already searched and what to do next (esp. for the PK-tree where the tree is of variable height).
The tradeoff solution (not that hard to develop, could be reasonably optimal for you) — iterative search process where you go up the tree all the time. You start with the leaf node containing the vX, if it doesn’t have N vectors or if the vX is closer to a boundary of the cell then the N-th found vector, you go one level up, and add the complete sub-tree starting from the parent node. This way the algorithm is much simpler because the searched area is always rectangular. However, the worst case (which is, if vX lies on the border between the 2 root cells), is much worse — you’ll have to iterate through all your 100k points.
If you know your vectors are more or less evenly distributed in your N-dimensional space, you don’t need all that complexity with the spatial trees.
Instead, you can split your space into regular hypercubic grid so that average grid cell contains under 20 vectors, and store the cells in HashMap<List<Integer>, List<Vector>> where the keys are integer coordinates of the grid cell, and values are list of vectors that are inside the corresponding cells.

Finding space on a Java component to draw

I have a java component on which I draw 100 by 40 rectangles to represent nodes of a graph. When a new node is added, I would like to be able to position it in a useful position. Currently, I simply choose the next available space on the x-axis. However, this means when I load a graph, I get a large chain of nodes spanning off the view to the right - not ideal!
A better solution may involve adding a node at the point closest to the center-point of the user's view. I'm sure there are many solutions to this problem I am unable to think of a reasonable way to achieve this.
I have three methods that are relevant to this problem:
positionNode(Node) // which tries to find suitable x,y to place a node
setPos(x,y) // which moves a node to the respective position
findElementAt(x,y) // which returns a node's model if such a node exists at (x,y)
A potential solution may somehow involve spiraling around the center point but I am unable to imagine a good solution for performing this.
Graph rendering is a hard problem which is the subject of a lot of research.
If you want to make the nodes into a sort of a bundle, rather than a line of nodes, the main disadvantage will be that lines coming out of the nodes will get overlapped by the other children.
You can make a square bundle or a round bundle. To make a square bundle, take the square root of the number of nodes and add one. For example, if you have 17 nodes, the sides of the square is 4 + 1 = 5. So you have a 5 x 5 square. Position each node in a cell of the square.
To make a round bundle draw concentric circles. So first node is at center. Then calculate an imaginary circle around that node. Divide the circle into segments by degrees according to how much space you need. Then locate each additional node in the center of each segment.
Note that you might want to overlap nodes. Depending on how your interface works, overlapping might allow you to fit more nodes in.
Sounds like an opportunity for force based layout:
http://en.wikipedia.org/wiki/Force-based_algorithms_(graph_drawing)
When you say graph I assume nodes are connected with each other so drawing them so their lines minimally criss cross to make it easier to visualize what the graph is telling you seems important. Forced based layout can help arrange the graph so it isn't under "stress" with lots of lines intersecting each other.

algorithm for drawing dendrogram stepwise from clustered objects in a tree

I want to draw a dendrogram from objects which I have already clustered and saved in a (leave)tree. My Cluster object in Java can be represented by these pictures. Each leaves contains an object and each node contains the distance between its children.
Now, I want to draw a dendrogram stepwise, so first object 1 and 2 should be drawn, then object 3 should be added to those. Then 5 and 6 together etc.. to the end where everything is connected. I already have all the tools to draw this easily, but I cannot find an efficient way in walking through the tree correctly.
This should be the result so far in the example (EDIT: There's a mistake, the distance from 5 to 6 now looks smaller than the distance from 3 to 1&2, but that isn't the case in my example!):
Does anyone have some tips for this recursive algorithm?
you're rendering depth first - you may find you need to keep track of depth to get the layout to work right - also note you have to draw non-terminal notes as well ("*" gets drawn before 3)
basically
draw(node)
{
if(hasleft) draw(left)
if(hasright) draw(right)
drawme()
}
this does assume a binary tree, but that is what you've drawn - and this is going to get a lot more complicated because of layout issues - you really want to consider drawing breadth first from the top down, it makes layout a lot less painful

Shortest path between raw geo coordinates and a node of a graph

I have implemented a simple Dijkstra's algorithm for finding the shortest path on an .osm map with Java.
The pathfinding in a graph which is created from an .osm file works pretty well. But in case the user's current location and/or destination is not a node of this graph (just raw coordinates) how do we 'link' those coordinates to the graph to make pathfinding work?
The simple straightforward solution "find the nearest to the current location node and draw a straight line" doesn't seem to be realistic. What if we have a situation like on the attached picture? (UPD)
The problem here is that before we start any 'smart' pathfinding algorithms (like Dijkstra's) we 'link' the current position to the graph, but it is just dumb formula (a hypotenuse from Pythagorean theorem) of finding the nearest node in terms of geographical coordinates and this formula is not 'pathinding' - it can not take obstacles and types of nodes into account.
To paraphrase it - how do we find the shortest path between A and B if B is a node in a graph, and A is not a node?
Have you heard of any other solutions to this problem?
The process you're describing is "map matching," and it uses a spatial index to find the nearest node.
One common approach is to construct a quadtree that contains all your nodes, then identify the quad that contains your point, then calculate the distance from your point to all nodes in the quad (recognizing that longitudinal degrees are shorter than latitudinal degrees). If there are no nodes in the quad then you progressively expand your search. There are several caveats with quadtrees, but this should at least get you started.
Practically speaking, I would just ignore the problem and use your suggested algorithm "straight line to nearest node". It is the user's responsibility to be as close as possible to a routable entity. If the first guess you suggested was missleading, user can change the starting position accordingly.
The user who really starts his journey in no man's land hopefully knows the covered area much more than your algorithm. Trust him.
BTW, this is the algorithm that OpenRouteService and Google Maps are using.
If still not convinced, I suggest to use the "shortest straight line that does not cross an obstacle". If this is still not enough, define a virtual grid of say 5mx5m and its diagonals. Than span a shortest path algorithm until you reach a graph-vertex.
You could treat the current location as a node, and connect that node to a few of the nearest nodes in a straight line. GPS applications would consider this straight line as being 'off road', so the cost of this line is very big compared to the other lines between nodes.
However, I didn't see your attached picture, so not sure this is a good solution for you.
If you have constraints in your path, you should consider using a linear programming formulation of the same shortest path problem.
http://en.wikipedia.org/wiki/Shortest_path_problem
Your objective would be to minimize the sum of the distance of each "way" taken between the starting and ending "nodes" defined in your .osm file. Any obstacles would be formulated as constraints. To implement with Java, see the link below.
http://javailp.sourceforge.net/
Really nice question!
Quad tree is a solution, as you can also index lines/edges into it, not only nodes.
But the problems with this 'naive' approach is that these solutions are memory intensive. E.g. if you already have a very big graph for shortest path calculation then you need the same or more memory for the quad tree (or I was doing something very stupid).
One solution is as follows:
use an array which is a grid over the used area. I mean you can devide your area into tiles, and per tile you have an array entry with the list of nodes.
so per array entry you'll have a list of nodes in that tile. For an edge you can just add both nodes to the entry. Take care when there are edges crossing a tile without having its node in this tile. The BresenhamLine algorithm will help here.
querying: converte the input ala (lat,lon) into a tile number. now get all points from the array entry. Calculate the nearest neighbor of the nodes AND edges to your point A using euclidean geometry (which should be fine as long as they are not too far away which is the case for nearest neighbor).
Is this description clear?
Update
This is now implemented in graphhopper!
To get a more memory efficient solution you have to simply exclude identical nodes for one entry (tile).
A bit more complicated technic to reduce mem-usage: if a graph traversal respects the tile bounds you can imagine that the graph is then devided into several sub-graphs for that tile (ie. a graph traversal wouldn't reach the other sub-graph within the tile-bounds). Now you don't need all nodes but only the nodes which lay in a different sub-graph! This will reduce the memory usage, but while querying you need to traverse not only one edge further (like in the current graphhopper implementation)! Because you need to traverse the full tile - i.e. as so long as the tile bounds are not exceeded.

A good Minimax representation in Gomoku?

I am trying to code a Gomoku (five in a row) game in Java as an individual project. For the AI, I understand that the use of a Minimax function with Alpha-beta Pruning is a good way to approach this. However, I'm having a little trouble envisioning how this would work.
My question is this: what is a good representation for a node in a minimax tree?
I'm thinking my evaluation function will "weight" all the empty spaces on the board. It will then take the best value from that board as the node of the minmax decision tree. Am I on the right direction?
And any other tips are also welcome!
Thanks in advance!
The state space search is through the different states of the board. There are a lot of moves, since you can place a stone anywhere unoccupied. Each state can be represented as a e.g. 9x9 matrix, with 3 values -- white, black, or unoccupied. With a 9x9 board, there are therefore 3 ^ 81 possible board states.
From any board state, the number of moves is the number of unoccupied vertices. You can place a stone on any of these vertices. You can only play your own color. So, at most there are 81 possible moves .. 81 for the first move, 80 for the second, and so on. So you can search to depth 5 reasonably, and possibly more .. not too bad.
The proper representation is, as mentioned, a 2D matrix -- this can just be a 2D array of ints, with values e.g. 0 for unoccupied, 1 for white, 2 for black. ... int[9,9].
Your evaluation function doesn't sound very good. Instead, I would give points for the following:
-- get 5 in a row -- basically give it the max score for this one, since it's a win
-- 4 in a row with 2 open ends -- also max score, since opponent can't block you from getting 5.
-- 4 in a row with 1 open end -- still a very threatenning position, since opponent has to play
in one spot to block.
-- 3 in a row with 2 open ends -- very high score again
--- 4, 3, 2, 1 with both closed ends -- 0, since can't ever make 5 in a row.
and so on.
Then, you just apply the standard minimax algorithm -- i.e. alpha beta pruning -- it would be exactly the same as chess, but you have a different state space generator and evaluation function.
I'd consider an evaluation function of the following form: consider each set of, say, 6 positions in a line. (On a 19x19 board there are 14 along each line and varying numbers from 0 to 14 along each diagonal; I think that comes to 742 of these on the whole board. My arithmetic may be wrong.) For each set there are 729 possible arrangements of black, white and empty spaces. Or, er, 378 if you take end-to-end symmetry into account. Or, er, um, fewer than that but I can't be bothered to work out how many fewer if you take black/white symmetry into account too.
So now your evaluation function will consist of a table-lookup for each block of 6 stones, in a 378-or-however-many-element table (or perhaps two of them, one for horizontal and vertical lines, one for diagonal ones). Add up the results and that's your evaluation of the position.
It may turn out that actually a larger table (derived from a longer row of positions) works better.
But what goes in the table? Let your program work that out. Start with arbitrary values in the table (you might, e.g., take eval(line) = #black(line)-#white(line) or something). Let your program play itself, using alpha-beta search. Now update the table entries according to what happens. There are many different ways of doing this; here are a (sketchily-described) few.
During each game, keep track of how many times each pattern occurred in each player's positions. When the game's over, adjust each pattern's score so that patterns seen more often by the winning player look better.
Each time you do a search, adjust the scores for the patterns in the current position to bring the current static score nearer to the score obtained by search.
Each time a move is made, adjust the scores for each pattern in the "before" position to make the "before" score match the "after" score better.
Have lots of different tables (hence lots of different variants of the evaluation function). Let them play against one another. Apply some sort of evolution (e.g., play all against all, then throw out the worst performers and replace them with mutants derived from the better performers).
For a more sophisticated version of these ideas (applied to chess, but the same ideas would work fine for gomoku), take a look at http://cs.anu.edu.au/~Lex.Weaver/pub_sem/publications/knightcap.pdf .

Categories