How to model this Depth First Search solution - java

I have a puzzle game that has a State depending on the arrangement of the pieces in the puzzle. I am trying to solve this puzzle using Depth First Search, however I am confused on how to approach it. From my understanding, Depth First Search will search a graph to find a solution, but my puzzle isn't in graph form. All I know is the current state and the states achievable from that state.
Am I supposed to build this graph as I discover all possible states from the state I am currently at? Wouldn't that defeat the purpose though - first building a graph with every possible state, then search the entire graph for the solution?
I have a method that can explore all the possible states from the current state using a Move, which I'm sure will come in handy except I don't know how to put it to use.

You don't have to explicitly build a graph. You can represent your problem as a graph, conceptually, where the nodes are the states and the edges are the transitions between the states. Depth first search is to follow an edge all the way until you hit an end state, before moving on to another edge. So it would look something like this (pseudocode):
def search(state):
if is_end_state(state):
# search down this branch finished, do something
return something
for move in possible_moves_from(state):
search(apply_move(state, move))
You end up implicitly building the graph, via the recursive calls and the stack state, as you go.
Note that if you have cycles (e.g. you can move left, then move right to get back to the exact same state) then you will have to keep track of already-visited states or you'll loop forever. Something like this:
def search(state, seen_states):
if state in seen_states:
# already visited, don't visit again
return
seen_states.add(state)
# same as before:
if is_end_state(state):
return something
for move in possible_moves_from(state):
search(apply_move(state, move), seen_states)
In terms of how to implement this, I recommend you have seen_states be a HashSet<State> and you make your State hashable.

Sounds to me like depth first is the wrong way about it. If you have a state, and you know all states that you can get to from that state, then breadth first may be more appropriate. With BFS you would know that the first solution you come to is the shortest solution.
If you are certain that there is a solution then you wouldn't have to worry about infinite recursion because any paths caught in a loop wouldn't be the shortest in the end anyway, they would just cause unnecessary work.
An iterative solution using a queue would work.
/** pseudocode **/
Queue q = new LinkedList();
q.put(myState)
while ( !q.isEmpty()) {
State s = q.remove();
if ( endState.equals(s)) {
return something;
}
for ( State newState : s.getNextStates()) {
q.add(newState);
}
}
If you do want to go with a depth first search, then simply change the queue to a stack but then you will have to deal with the cycles.
If your queue item was a wrapper that that contained the path to the current state instead of just the current state then you could easily get to the depth and path that was traversed for the shortest route (or at least, first shortest route discovered if there are multiple routes of the same depth.)

Related

Count number of agents at a node

I have set up a polygonal node (called area_wait) that a single type of agent remain at whilst in a queue. I'm trying to find the number of agents at a node using a function. I don't want to count the agents in the queue as I have set up one queue for all waiting agents which might be at different nodes.
I'm using the following code which always returns zero.
int count_X = area_wait.agents().size();
In fact the list is empty when I check with:
List list_X = area_wait.agents();
What am I doing wrong? Thanks in advance.
I will give you the same answer I gave in the anylogic users group which can be found here: https://www.linkedin.com/feed/update/urn:li:activity:6721800348408791040
so this function you are trying to use doesn't work... unless the thing that is inside the node is a transporter and only if the node has a speed or access restriction... this might either be a bug or something explained poorly on the documentation, but it sounds like a bug to me
If you want to know the number of agents in a node you can use the alternative method count(myAgents,a->a.getNetworkNode()!=null && a.getNetworkNode().equals(yourNode)) but this fails if you change the node position without a moveTo block or some other natural movement (such as defining your node in the agent location parameter of a block)... so.. that's another bug, but maybe it won't apply to you
So summary... no easy and safe solution as far as I know

Shortest route with fewest turns

I had a requirement to generate shortest route. The first solution which suited my requirement was Dijkstra's algorithm, and hence I implemented the same (Java). Later, I had to modify the implementation to generate the shortest route "with least number of turns". After some head-scratching, i came up with a solution, although with a lot of conditions added into the existing Dijkstra's algorithm implementation. Now my query is, is there a better approach for this problem(like, any existing algorithm which already does this)? My solution includes storing additional turns information in each of the nodes in the route calculation iteration, and use the same while back-tracking the route.
You shouldn't need any backtracking or substantial tweaks to Dijkstra. Simply keep track (as you do), for each node, of the least number of turns on the currently shortest route to that node. Whenever you relax an edge, if the resulting path is equally short as the currently shortest route, you pick the one with the fewest turns.
Edit: as pointed out in the comments, this approach disregards the fact that the direction of the incoming edge of the chosen route affects the number of turns for the subsequent path. That will be fixed by storing in each node the shortest distance+turns for each incoming edge or for each unique incoming angle (however you measure that).
Alternatively, in order to get by with fewer modifications of Dijkstra, you can modify the graph beforehand: Split each node into one node per incoming edge (so that each resulting node has only one of the original node's incoming edges), but copy all the outgoing edges so that each resulting node has all the outgoing edges of the original node (each of which must be directed to the appropriate copy of the node at the other end of the edge). You might see that some of the resulting nodes have multiple incoming edges, but in that case, the nodes on the other ends of those edges are all copies of the same original node and thus represent the "same" original edge - therefore, each outgoing edge can be unambiguously labeled with whether that edge represented a turn out of that node (relative to the node's incoming edges) or not. Note that the best path in the original graph will still exist in the new graph (and no better paths will have been introduced). Now, Dijkstra just needs to be modified to track the number of turns associated with the shortest path to each node. Whenever an edge from u to v is relaxed and the candidate path is as short as the shortest path you have previously found for v, compare u's turn count plus the edge's turn count (0 or 1 depending on whether the edge constituted a turn) to v's turn count, and use that as a tiebreaker.
Ultimately path finding algorithms are designed to find the lowest cost path. The definition of cost depends on the scenario. In one scenario cost might be distance but in other scenarios it might include terrain, slope, tolls etc. In your case the easiest way to model 'shortest route with least number of turns' is to derive cost from both distance and number of turns. In other words, include a cost for turning.
For example, if you are using the A* algorithm, your cost calculation between two nodes could include a cost for the distance and an additional cost if this move requires a change of direction. If a different path does not require a change of direction then it will be lower cost and the algorithm will choose that path.
The only tricky thing here will be to keep the context of the previous moves to detect the turns. In A* you are generally keeping references back to the previous node so it should be fairly straightforward to decide if the next move requires a turn.
I do not know, why no one else has stated this and why there is an accepted answer.
The problem you are trying to solve (i.e., generate the shortest route with least number of turns) is an example of the weight-constrained shortest path problem.
It is therefore NP-Complete and cannot be solved efficiently.
You can find papers that discuss solving this problem e.g. http://web.stanford.edu/~shushman/math15_report.pdf
Here's a simple heuristic. Like others have pointed out, heuristic is the game in AStar.
if (Cost > CanMaxMove) Heuristic += 1000;
// for cost per grid pt typically 10 to 30
// Cost = PtCost + CostSoFar
// higher is worse (more costly)
You simply find the best path as per usual in AStar, but discount by a large margin moves that would be out of turn. This is a very hard problem as pointed out, but easily solveable given the following condition:
Every turn a new path can and will be searched anyway: this is easily
believable, because until next turn circumstance can easily change. If
not, those are not really turns as we know them.
If that condition is ok with you, just do the above snippet. Heuristic must be discounted by the same value for all "out of this turn" moves and NOT smoothly (e.g. Heuristic += (Cost - CanMove) * 100) i.e. there must be a large difference between "this turn" and "not this turn".

Identifying cheapest path with A* algorithm

So I am writing a Java program that uses the A* search algorithm. The program runs on a 2 dimensional array. It has a start location, a goal and obstacles to move around. Every object on the grid is a node.
SRRRRRRR
RXXRRXXX
RRRXXXRX
RXRRXRRR
XXXRRXRR
RRRRRRRR
XXRXRRXR
XXXXRRRG
S = Start, G = Goal, R = Valid movement tile, X = Illegal movement tile
I have two arraylists:
- openList
- closedList
openList is a list of possible movements sorted from cheapest to most expensive. closedList is a list of nodes that have been visited and will not be visited again. The algorithm will always move into the first node in the openList. This node will then be removed from openList and added to the end of closedList.
My algorithm can successfully navigate from start to goal. The problem that I am having is that I am not sure how to filter out the true path from my list of closed nodes. A* will always look for the cheapest option which means that it may not go directly to the goal. The openList ranks nodes according to the cost of movement so even if the algorithm is sitting one Node away from the goal, if there is a node that is cheaper to move into somewhere earlier on the path then it will take that cheaper node. This means that I am guaranteed to find the cheapest path, but also that at the end my closed list will be full of nodes that are not on the best path to the goal.
At the end my closedList gives me the exact path my algorithm took, not the cheapest path.
My question is: Of all the nodes that my algorithm will explore, how do I differentiate between nodes that are on the cheapest path and nodes that are not?
I would highly, HIGHLY recommend Amit Patel's A* pages, which will go into very good detail about everything you may want to know about Pathfinding.
To solve your specific problem, you need to in some way store the node you came from when you visit a node, so when you reach the goal, you just walk your way backwards along the path. This can be done with a Map<Node, Node>, or, you can make use of references to the parent node by storing something other than a Node: Something that contains the node, and a reference to the node from which you came to visit that node when you add to your lists.
It sounds like your cost function may be broken.
In A*, the cost function is always the sum of the actual cost of the path traversed so far plus a lower bound on the distance remaining. There are rules for admissability of the heuristic - the same as for a metric space IIRC.
Obvious heuristics to use for the lower-bound remaining distance in this case are...
Euclidean distance remaining - sqrt (xdist^2 + ydist^2).
Manhattan distance remaining - xdist + ydist
If the total cost estimate after taking a step along the indirect path isn't greater than after stepping directly to the goal, the only way that can be valid is if the total cost estimate is the same either way. A* won't avoid taking extra steps unless you add a tie-breaker to your cost-comparing tests. But it won't choose a higher-cost route when a direct route is available - unless your cost function is deceiving it (or your code has bugs).
In any case, that same-cost-either-way should never happen in a square grid if a possible move is directly to the goal.
There's a chance you may have implemented Dijkstra rather than A*. The cost function for Dijstra is simply the total distance travelled so far. There's no attempt to estimate distance remaining and therefore nothing to guide the search towards the goal - it explores in all directions equally.
One way to accidentally end up with Dijkstra is to use the obvious "uninformed" (but admissable) lower bound on the remaining distance - zero.
At the end it's still, of course, likely that you will have searched nodes that are off the optimum path - usually fewer than if you've got a good A* heuristic but even that can be wrong for awkward maps. See moveaway00s answer - "you need to in some way store the node you came from when you visit a node". For each node you explore, there's only one possible shortest-possible-distance to get there - if the node is on the shortest path, that backward step is a reverse step along the shortest path.
For Dijkstra, the first time you explore a location is always for the shortest way to get there. For A* that's not necessarily true IIRC (it's true for the goal node, not necessarily for other nodes explored), so you may need to store the shortest distance to the node along with the backward step.

Why does A* path finding sometimes go in straight lines and sometimes diagonals? (Java)

I'm in the process of developing a simple 2d grid based sim game, and have fully functional path finding.
I used the answer found in my previous question as my basis for implementing A* path finding. (Pathfinding 2D Java game?).
To show you really what I'm asking, I need to show you this video screen capture that I made.
I was just testing to see how the person would move to a location and back again, and this was the result...
http://www.screenjelly.com/watch/Bd7d7pObyFo
Different choice of path depending on the direction, an unexpected result. Any ideas?
If you're looking for a simple-ish solution, may I suggest a bit of randomization?
What I mean is this: in the cokeandcode code example, there is the nested-for-loops that generate the "successor states" (to use the AI term). I refer to the point where it loops over the 3x3 square around the "current" state, adding new locations on the pile to consider.
A relatively simple fix would (should :)) be isolate that code a bit, and have it, say, generated a linkedlist of nodes before the rest of the processing step. Then Containers.Shuffle (or is it Generics.Shuffle?) that linked list, and continue the processing there. Basically, have a routine say,
"createNaiveNeighbors(node)"
that returns a LinkedList = {(node.x-1,node.y), (node.x, node.y-1)... } (please pardon the pidgin Java, I'm trying (and always failing) to be brief.
Once you build the linked list, however, you should just be able to do a "for (Node n : myNewLinkedList)" instead of the
for (int x=-1;x<2;x++) {
for (int y=-1;y<2;y++) {
And still use the exact same body code!
What this would do, ideally, is sort of "shake up" the order of nodes considered, and create paths closer to the diagonal, but without having to change the heuristic. The paths will still be the most efficient, but usually closer to the diagonal.
The downside is, of course, if you go from A to B multiple times, a different path may be taken. If that is unnacceptable, you may need to consider a more drastic modification.
Hope this helps!
-Agor
Both of the paths are of the same length, so the algorithm is doing its job just fine - it's finding a shortest path. However the A* algorithm doesn't specify WHICH shortest path it will take. Implementations normally take the "first" shortest path. Without seeing yours, it's impossible to know exactly why, but if you want the same results each time you're going to have to add priority rules of some sort (so that you're desired path comes up first in the search).
The reason why is actually pretty simple: the path will always try to have the lowest heuristic possible because it searches in a greedy manner. Going closer to the goal is an optimal path.
If you allowed diagonal movement, this wouldn't happen.
The reason is the path you want the algorithm to go.
I don't know the heuristic your A* uses but in the first case it has to go to the end of the tunnel first and then plans the way from the end of the tunnel to the target.
In the second case the simplest moves to the targets are going down till it hits the wall and then it plans the way from the wall to the target.
Most A* I know work with a line of sight heuristic or a Manhattan Distance in the case of a block world. This heuristics give you the shortest way but in case of obstacles that force to go a way that is different from the line of sight the ways depend on your starting point.
The algorithm will go the line of sight as long as possible.
The most likely answer is that going straight south gets it closest to its goal first; going the opposite way, this is not a choice, so it optimizes the sub-path piecewise with the result that alternating up/across moves are seen as best.
If you want it to go along the diagonal going back, you are going to have to identify some points of interest along the path (for example the mouth of the tunnel) and take those into account in your heuristic. Alternatively, you could take them into account in your algorithm by re-computing any sub-path that passes through a point of interest.
Back in the day they used to do a pre-compiled static analysis of maps and placed pathfinding markers at chokepoints. Depending on what your final target is, that might be a good idea here as well.
If you're really interested in learning what's going on, I'd suggest rendering the steps of the A* search. Given your question, it might be very eye-opening for you.
In each case it's preferring the path that takes it closer to its goal node sooner, which is what A* is designed for.
If I saw right, the sphere is moving first to the right in a straigt line, because it cannot got directly toward the goal (path is blocked).
Then, it goes in a straight line toward the goal. It only looks diagonal.
Does your search look in the 'down' direction first? This might explain the algorithm. Try changing it to look 'up' first and I bet you would see the opposite behavior.
Depending on the implementation of your astar you will see different results with the same heuristic, as many people have mentioned. This is because of ties, when two or more paths tie the way you order your open set will determine the way the final path will look. You will always get the optimal path if you have an admissible heuristic, but the nodes visited will increase with the number of ties you have(relative to a heuristic producing not as many ties).
If you dont think visiting more nodes is a problem i would suggest using the randomization (which is your current accepted answer) suggestion. If you think searching more nodes is a problem and want to optimize i would suggest using some sort of tiebreaker. It seems you are using manhattan distance, if you use euclidian distance when two nodes tie as a tiebreaker you will get more straight paths to the goal and you will visit fewer nodes. This is ofcourse given no traps or block of line of sight to the goal.
To avoid visiting nodes with blocking elements in the line of sight path i would suggest finding a heuristic which takes into account these blocking elements. Ofcourse a new heuristic shouldnt do more work than a normal A star search would do.
I would suggest looking at my question as it might produce some ideas and solutions to this problem.

Java TreeNode: How to prevent getChildCount from doing expensive operation?

I'm writing a Java Tree in which tree nodes could have children that take a long time to compute (in this case, it's a file system, where there may be network timeouts that prevent getting a list of files from an attached drive).
The problem I'm finding is this:
getChildCount() is called before the user specifically requests opening a particular branch of the tree. I believe this is done so the JTree knows whether to show a + icon next to the node.
An accurate count of children from getChildCount() would need to perform the potentially expensive operation
If I fake the value of getChildCount(), the tree only allocates space for that many child nodes before asking for an enumeration of the children. (If I return '1', I'll only see 1 child listed, despite that there are more)
The enumeration of the children can be expensive and time-consuming, I'm okay with that. But I'm not okay with getChildCount() needing to know the exact number of children.
Any way I can work around this?
Added: The other problem is that if one of the nodes represents a floppy drive (how archaic!), the drive will be polled before the user asks for its files; if there's no disk in the drive, this results in a system error.
Update: Unfortunately, implementing the TreeWillExpand listener isn't the solution. That can allow you to veto an expansion, but the number of nodes shown is still restricted by the value returned by TreeNode.getChildCount().
http://java.sun.com/docs/books/tutorial/uiswing/components/tree.html#data
scroll a little down, there is the exact tutorial on how to create lazy loading nodes for the jtree, complete with examples and documentation
I'm not sure if it's entirely applicable, but I recently worked around problems with a slow tree by pre-computing the answers to methods that would normally require going through the list of children. I only recompute them when children are added or removed or updated. In my case, some of the methods would have had to go recursively down the tree to figure out things like 'how many bytes are stored' for each node.
If you need a lot of access to a particular feature of your data structure that is expensive to compute, it may make sense to pre-compute it.
In the case of TreeNodes, this means that your TreeNodes would have to store their Child count. To explain it a bit more in detail: when you create a node n0 this node has a childcount (cc) of 0. When you add a node n1 as a child of this one, you n1.cc + cc++.
The tricky bit is the remove operation. You have to keep backlinks to parents and go up the hierarchy to subtract the cc of your current node.
In case you just want to have the a hasChildren feature for your nodes or override getChildCount, a boolean might be enough and would not force you to go up the whole hierarchy in case of removal. Or you could remove the backlinks and just say that you lose precision on remove operations. The TreeNode interface actually doesn't force you to provide a remove operation, but you probably want one anyway.
Well, that's the deal. In order to come up with precomputed precise values, you will have to keep backlinks of some sorts. If you don't you'd better call your method hasHadChildren or the more amusing isVirgin.
There are a few parts to the solution:
Like Lorenzo Boccaccia said, use the TreeWillExpandListener
Also, need to call nodesWereInserted on the tree, so the proper number of nodes will be displayed. See this code
I have determined that if you don't know the child count, TreeNode.getChildCount() needs to return at least 1 (it can't return 0)

Categories