Modifing AStar algorithm to connect gates in logic scheme - java

I've been working on a logic scheme simulator for a while now. The whole thing is pretty much working but there's an issue that I can't seem to solve.
Connections in a logic scheme should be vertical and horizontal. They should avoid logic gates and have as few turns as possible (avoiding the staircase effect). Connections can also intersect but they can never overlap.
I used AStar algorithm to find the shortest and the nicest path between two logic gates. The heuristics for pathfinding is Manhattan distance while the cost between the two nodes is a dimension of a single square on the canvas.
The whole issue arises between two conditions. "Min turns" and "no overlap". I solved "min turns" issue by punishing the algorithm with double the normal cost when it tries to make a turn. That causes the algorithm to postpone all turns to the latest possible moment which causes my next picture.
My condition of no overlapping is forbidding the second input from connecting to the second free input of the AND gate (note: simulator is made for Android and the number of inputs is variable, that's why inputs are close to each other). A situation like this is bound to happen sooner or later but I would like to make it as late as possible.
I have tried to:
introdue "int turnNumber" to count how many turns have been made so far and punish paths that make too many turns. (algorithm takes too long to complete, sometimes very very long)
calculate Manhattan distance from the start to the end. Divide that number by two and then remove the "double cost" punishment from nodes whose heuristics are near that middle. (for some situations algorithm fell into infinite loop)
Are there any ideas on how to redistribute turns in the middle so as many as possible connections can be made between logic gates while still satisfying the "min turn" condition?
In case you'd like to see the code: https://gist.github.com/linaran/c8c493bb54cfca764aeb
Note: The canvas that I'm working with isn't bounded.
EDIT: method for calculating cost and heuristics are -- "calculateCost" and "manhattan"

1. You wrote that you already tried swap start/end position
but my guts tell me if you compute path from In to Out
then the turn is near Output which is in most cases OK because most Gates has single output.
2. Anyway I would change your turn cost policy a bit:
let P0,P1 be the path endpoints
let Pm=(P0+P1)/2 be the mid point
so you want the turn be as close to the mid point as it can be
so change turn cost tc to be dependent to the distance from Pm
tc(x,y)=const0+const1*|(x,y)-Pm|
that should do the trick (but I didn't test this so handle with prejudice)
it could create some weird patterns so try euclidean and manhatan distances
and chose the one with better results
3. Another approach is
fill the map from both start and end points at once
And stop when they meet
you need to distinguish between costs from start and end point
so either use negative for star and positive values for end point origin
or allocate ranges for the two (range should be larger then map size xs*ys in cells/pixels)
or add some flag value to the cost inside map cell
4. you can mix 1. and 2. together
so compute Pm
find nearest free point to Pm and let it be P2
and solve path P0->P2 and P1->P2
so the turns will be near P2 which is near Pm which is desired
[notes]
the 3th approach is the most robust one and should lead to desired results

Related

Traveling Salesman - 2-Opt improvement

So I've been looking for an explanation of a 2-opt improvement for the traveling salesman problem, and I get the jist of it, but I don't understand one thing.
I understand that IF two edges of a generated path cross each other, I can just switch two points and they will no longer cross. HOWEVER - I do not understand how I can determine whether or not two edges cross.
To make my question clear, this is what I've done so far: (I did it in java)
I have an object called Point that represents a city, with an x and y coordinate.
I have a PointSet which has a set of Points contained in a List.
I have a method for PointSet called computeByNN() which arranges the PointSet in a fairly short manner through a Nearest Neighbor algorithm.
So now I have a sorted PointSet (not optimal, but still short) and I want to do 2-opt on it. However, I don't know where to start. Should I check each and every line segment to see if they cross, and if they do, switch two points? I feel like that defeats the purpose of heuristics and it becomes a sort of brute force solution. Is there an efficient way to find if two segments of the tour cross?
I applogize if my question is not clear. I'll try to edit it to make it clearer if anyone needs me to.
If you like you can create a look-up table to detect crossed edges. For n = 1000, order 10^12 entries is obviously too extravagant. However you probably are most worried about the shorter edges? Suppose you aimed to include edges to about √n of the nearest neighbors for each node. Then you are only in the realm of megabytes of space and in any case O(n^2) preprocessing. From there it's a heuristic, so good luck!
Also will mention this can be done on the fly.

How to improve the perfomance of my A* path finder?

So basically I coded an A* pathfinder that can find paths through obstacles and move diagnolly. I basically implemented the pseudocode from Link into real code and also used a binary heap method to add and delete items from the openlist.
Using binary heap led to significant performance boost , about 500 times faster than the insert sorting algorithm I used before.
the problem is that it still takes around on average 1.5 million nanoseconds which is around .0015 of a second.
So the question is, my plan is to make a tower defense game where the pathfinding for each mob needs to update everytime I add a tower to the map. If I were to have around a maximum of 50ish mobs on the map, that means it will take around .0015 * 50 = .075 seconds to update all paths for the entire mob. The game basically ticks( all the ingame stuff updates) every 1/60 seconds which is .016 of a second, so the problem is that it takes longer to update the paths than it takes to tick, which will lead to massive lag. So how should I go about this? DO I need to find a better algorithm for sorting the openlist or somehow divide the pathfinding tasks so that each tick only does X number of pathfinding tasks as opposed to all of them.
Rather than searching from each enemy to the checkpoint, search outwards from the checkpoint to every enemy at once. This way, rather than doing 50 searches, you only need to do one.
More specifically, just do a breadth-first search (or djikstra's, if your graph is weighted) from the player outwards, until every enemy has been reached.
You could alter this strategy to work with A* by changing your heuristic EstimatedDistanceToEnd (aka h(x)) to be the minimum estimate to any enemy, but with a lot of enemies this may end up being slower than the simpler option. The heuristic must be consistent for this to work.
Additionally, make sure you are using the correct tie-breaking criteria.
Also, and most importantly, remember that you don't need to run your pathfinder every single frame for most games - often you can get away with only once or twice a second, or even less, depending on the game.
If that is still too slow, you could look into using D* lite to reuse information between subsequent searches. But, I would bet money that running a single breadth-first search will be more than fast enough.
(copied from my answer to a similar question on gamedev)
Have you considered the Floyd-Warshall algorithm?
Essentially, A* is for path-finding from a single source to one or more destinations. However, in tower defense (depending on your rules of course), it is about multiple sources navigating around a map.
So for this, Floyd's algorithm seems more optimal. However, you could have your A* algorithm find paths for unit groups instead of individual units, which should optimize your calculation times.
Presumably, you can back-search from the exit towards all the creeps, so you need to explore your maze only once.

Guide on how to solve Rush Hour Puzzle in Java obtaining lowest number of moves using A* . Need help on how to start and steps to follow

Firstly, I have read every thread that I could find on stackoverflow or other internet searching. I did learn about different aspects, but it isn't exactly what I need.
I need to solve a Rush Hour puzzle of size no larger than 8 X 8 tiles.
As I have stated in title I want to use A*, as a heuristic for it I was going to use :
number of cars blocking the red car's ( the one that needs to be taken out ) path should decrease or stay the same.
I have read the BFS solution for Rush hour.
I don't know how to start or better said, what steps to follow.
In case anyone needs any explanation, here is the link to the task :
http://www.cs.princeton.edu/courses/archive/fall04/cos402/assignments/rushhour/index.html
So far from what have I read ( especially from polygenelubricants's answer ) I need to generate a graph of stages including initial one and "succes" one and determine the minimum path from initial to final using A* algorithm ?
Should I create a backtracking function to generate all the possible ( valid ) moves ?
As I have previously stated, I need help on outlining the steps I need to take rather than having issues with the implementation.
Edit : Do I need to generate all the possible moves so I convert them into graph nodes, isn't that time consuming ? I need to solve a 8X8 puzzle in less than 10 seconds
A* is an algorithm for searching graphs. Graphs consist of nodes and edges. So we need to represent your problem as a graph.
We can call each possible state of the puzzle a node. Two nodes have an edge between them if they can be reached from each other using exactly one move.
Now we need a start node and an end node. Which puzzle-states would represent our start- and end-nodes?
Finally, A* requires one more thing: an admissable distance heuristic - a guess at how many moves the puzzle will take to complete. The only restriction for this guess is that it must be less than the actual number of moves, so actually what we're looking for is a minimum-bound. Setting the heuristic to 0 would satisfy this, but if we can come up with a better minimum-bound, the algorithm will run faster. Can you come up with a minimum-bound on the number of moves the puzzle will take to complete?

How to find the best path in graph with weighted nodes and vertices

Let's say I have this graph
always a full graph
one start node - also the finish node
weighted nodes and vertices
I want to find a path short as possible but with the best score (sum of points of nodes) - in other words a path that can't be longer then some defined constant but give me the best amount of points. And I want to start and stop in the same node and don't want to go over already visited nodes.
Are there any algorithms which could help me with this problem or do you have any ideas how to solve it?
Oh, and it's not a homework, I just want to create a special path finder.
EDIT
So far I've been able to construct a working algorithm which can find some path in a few seconds. But I don't get the amount of points I'd like to - I get only about 85% of the desired score. And if I change the algoritm's parameters then time will be in hours and more...
I don't think this is solvable in better than brute force time. You could calculate all paths up to a certain constraint length. However, for an arbitrarily large graph that would be extremely slow. If you're looking for a solid guess, I'd start with a greedy algorithm that picks the step with the highest Points per Length value, until the limit is reached. You can then add things such as reversing in the case of premature filling (say, if you've gone 5, but your limit is 6, and your current node has no paths of length one connected) to find out how that works.
I'm not sure if this would actually work, but these are my initial thoughts:
Perhaps try with the maximum spanning tree (Prim's or Kruskal's). Since you don't want to repeat vertices, your path must end up being the cycle graph. Walk the spanning tree (maybe some sort of greedy algorithm?) and once you hit a leaf, go back to the start vertex (since the original graph was the complete graph). This would only work (maybe) if there were no negative edge weights.
Just some thoughts for now - it's late at night, I'll take a closer look in the morning. :)

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.

Categories