Find two farthest cells in a grid with obstacles - grid

Having no defined starting cell, how to find the two farthest cells in a grid with obstacles (walls and such) in the most efficient way?
Doesn't need to be a perfect result, can be an approximation, given it's good enough.
If you know how, I love you.

Do an 8-way bucket fill algorithm to find deadends.
To minimize the amount of deadends append first the cardinals to the queue and then the primary intercardinals (diagonals). Also keep track of the last deadend and if you find a new deadend too close to the last you delete the last and keep the new found one. In large maps you can also calculate the Manhattan distance from the deadend to the center of the map and if it's too short you just don't add the deadend.
Now just A* every point to every other point.
Since you test each path twice (p1 to p2 then p2 to p1) once you test p1 to p2 you can also register p2 to p1 off the bat with the same distance to halve the amount of times you need to do an A* search. The times you need to do an A* search then can be calculated by number of deadends * (number of deadends - 1) / 2.

Related

Shortest distance to cover all the (N+1) points. All the N points lie on x- axis. Remaining one point lies anywhere in the coordinate plane

Given (N+1) points. All the N points lie on x- axis. Remaining one point (HEAD point) lies anywhere in the coordinate plane.
Given a START point on x- axis.
Find the shortest distance to cover all the points starting from START point.We can traverse a point multiple times.
Example N+1=4
points on x axis
(0,1),(0,2),(0,3)
HEAD Point
(1,1) //only head point can lie anywhere //Rest all on x axis
START Point
(0,1)
I am looking for a method as of how to approach this problem.
Whether we should visit HEAD point first or HEAD point in between.
I tried to find a way using Graph Theory to simplify this problem and reduce the paths that need to be considered. If there is an elegant way to represent this problem using graphs to identify a solution, I was not able to find it. This approach becomes very inefficient as the n increases - the time and memory is O(2^n).
Looking at this as a tree graph, the root node would be the START point, then each of its child nodes would be the points it is connected to.
Since the START point and the rest of the points aside from the HEAD all lay on the x-axis, all non-HEAD points only need to be connected to adjacent points on the x-axis. This is because the distance of the path between any two points is the sum of the distances between any adjacent points along the path between those two points (the subset of nodes representing points on the x-axis does not need to form a complete graph). This reduces the brute force approach some.
Here's a simple example:
The upper left shows the original problem: points on the x-axis along with the START and HEAD points.
In the upper right, this has been transformed into a graph with each node representing a point from the original problem. The edges represent the paths that can be taken between points. This assumes that the START point only represents the first point in the path. Unlike the other nodes, it is only included in the path once. If that is not the case and the path can return to the START point, this would approximately double the possible paths, but the same approach can be followed.
In the bottom left, the START point, a, is the root of a tree graph, and each node connected to the START point is a child node. This process is repeated for each child node until either:
A path that is obviously not optimal is identified, in which case that node can just be excluded from the graph. See the nodes in red boxes; going back and forth between the same nodes is unnecessary.
All points are included when traversing the tree from the root to that node, producing a potential solution.
Note that when creating the tree graph, each time a node is repeated, its "potential" child nodes are the same as the first time the node was included. By "potential", I mean cases above still need to be checked, because the result might include a nonsensical path, in which case that node would not be included. It is also possible a potential solution results from the path after its child nodes are included.
The last step is to add up the distances for each of the potential solutions to determine which path is shortest.
This requires a careful examination of the different cases.
Assume for now START (S) is on the far left, and HEAD (H) is somewhere in the middle the path maybe something like
H
/ \
S ---- * ----*----* * --- * ----*
Or it might be shorter to from H to and from the one of the other node
H
//
S ---- * --- * -- *----------*---*
If S is not at one end you might have something like
H
/ \
* ---- * ----*----* * --- * ----*
--------S
Or even going direct from S to H on the first step
H
/ |
* ---- * ----*----* |
S
A full analysis of cases would be quite extensive.
Actually solving the problem, might depend on the number of nodes you have. If the number is small < 10, then compete enumeration might be possible. Just work out every possible path, eliminate the ones which are illegal, and choose the smallest. The number of paths is I think in the order of n!, so its computable for small n.
For large n you can break the problem into small segments. I think its enough just to consider a small patch with nodes either side of H and a small patch with nodes either side of S.
This is not really a solution, but a possible way to think about tackling the problem.
(To be pedantic stackoverflow.com is not the right site for this question in the stack exchange network. Computational Science : algorithms might be a better place.
This is a fun problem. First, lets try to find a brute force solution, as Poosh did.
Observations about the Shortest Path
No repeated points
You are in an Euclidean geometry, thus the triangle inequality holds: For all points a,b,c, the distance d(a,b) + d(b,c) <= d(a,c). Thus, whenever you have an optimal path that contains a point that occurs more than once, you can remove one of them, which means it is not an optimal path, which leads to a contradiction and proves that your optimal path contains each point exactly once.
Permutations
Our problem is thus to find the permutation, lets call it M_i, of the numbers 1...n for points P1...Pn (where P0 is the fixed start point and Pn the head point, P1...Pn-1 are ordered by increasing x value) that minimizes the sum of |(P_M_i)-(P_M_(i-1))| for i from 1 to n, || being the vector length sqrt(v_x²+v_y²).
The number of permutations of a set of size n is n!. In this case we have n+1 points, so a brute force approach testing all permutations would have complexity (n+1)!, which is higher than even 2^n and definitely not practical, so we need further observations to improve this.
Next Steps
My next step would now be to see if there are any other sequences that can be proven to be not optimal, leading to a reduction in the number of candidates to be tested.
Paths of non-head points
Lets look at all paths (sequences of indices of points that don't contain a head point and that are parts of the optimal path. If we don't change the start and end point of a path, then any other transpositions have no effect on the outside environment and we can perform purely local optimizations. We can prove that those sequences must have monotonic (increasing or decreasing) x coordinate values and thus monotonic indices (as they are ordered by ascending x coordinate between indices 0 and n-1):
We are in a purely one dimensional subspace and the total distance of the path is thus equal to the sum of the absolute values of the differences in x coordinates between one such point and the next. It is clear that this sum is minimized by ordering by x coordinate in either ascending or descending order and thus ordering the indices in the same way. Note that this is true for maximal such paths as well as for all continuous "subpaths" of them.
Wrapping it up
The only choices we have left are:
where do we place the head node in the optimal path?
which way do we order the two paths to the left and right?
This means we have n values for the index of the head node (1...n, 0 is fixed as the start node) and 2x2 values for sort order. So we have 4n choices which we can all calculate and pick the shortest one. One of the sort orders probably determines the other but I leave that to you.
Anyways, the complexity of this algorithm is O(4n) = O(n). Because reading in the input of the problems is in O(n) and writing the output is as well, I believe that is an algorithm of optimal complexity. However, if we could reformulate the problem somewhat, so that we could read and write the input and output in some compressed form, as in only the parameters that we actually need to solve the problem, then it is possible that we could do better.
P.S.: I'm not a mathematician so I probably used wrong words for some concepts and missed the usual notation for the variables and functions. I would be glad for some expert to check this for any obvious errors.

Polygon overlap, specific case

I've implemented a function to check the overlapping of two polygons, p1 and p2, to verify if p1 overlaps p2 the function takes every edge of p1 and test if one point of it is inside p2 and not on an edge of p2 (they can share an edge).
The function works just fine, the problem is that it's called a thousand times and it makes my program really slow since it have to iterate through each edge point by point and I'm only checking 4 cases of polygon overlapping, they are:
If a triangle overlaps a triangle.
If a triangle overlaps a rectangle.
If a triangle overlaps a parallelogram.
If a rectangle overlaps a parallelogram.
Is there any simpler and faster way to check if these cases of overlapping occur?
I'm thinking all you are really looking for is where line segment intersections. This can be done in O((N+k) log N), where N is the number of line segments (roughly the number of vertices) and k is the number of intersections. Using the Bentley-Ottmann algorithm. This would probably be best done using ALL of the polygons, instead of simply considering only two at a time.
The trouble is keeping track of which line segments belong to which polygon. There is also the matter that considering all line segments may be worst than simply considering only two polygons, in which case you stop as soon as you get one valid intersection (some intersections may not meet your requirements to be count as an overlap). This method is probably faster, although it may require that you try different combinations of polygons. In which case, it's probably better to simply consider all line segments.
You can speed up the intersection test by first check if the edge intersects the boundin box of the polygon. Look at Line2D.interSects(Rectangle2D rect).
If you have ten thousands of polygons, then you further can speed up, by storing the polygons in a spatial index (Region Quadtree). This then will limit the search to a view polygons instead of bruite force searching all. But this proably make only sense if you often have to search, not only once at program start up.

Finding shortest paths to all desired points in a graph

I was asked the following question in an interview
You are given a 4 X 4 grid. Some locations on the grid contain
treasure. Your task is the visit all the locations that contain the
treasure and collect it. You are allowed to move on the four adjacent
cells (up, down, left, right). Each movement and the action of
"treasure collection" is of a single unit cost. You need to traverse
the entire grid, and collect all the treasure on the grid, minimizing
the cost taken.
If I can recall properly, here is a sample graph that was given:
U..X
..X.
X..X
..X.
Where, U is my current position and X marks the position of the treasure.
The solution that I presented was to use breadth first search traversing the graph and "collecting the treasure" while doing so. However, the interviewer insisted that there was a better way to minimize the cost. I hope you could help me in figuring it out.
You should have recognized that this is a Traveling Salesman Problem in a small disguise. Using breadth-first, you can determine the shortest way between the different vertices you have to visit which gives you a derived graph containing just those ways as weighted edges between the vertices. From then on, it's a classic TSP.
BFS alone is not going to solve it for you, because you cannot move in all directions at the same time. It is not a single-source shortest path problem, because once you collect the treasure, you start your path to the next one from your current spot, not from the original spot.
The time that it takes to collect all treasure depends on the order in which you visit the boxes with X. Since there are only five of them, you can try all 120 orderings, compute the cost, and pick the best one.
Note that if the order is fixed, the solution is trivial: you add up manhattan distances between the cells in order, and pick the smallest result.

Closest Approach question for math/physics heads

I'm using a Segment to Segment closest approach method which will output the closest distance between two segments of length. Each segment corresponds to a sphere object's origin and destination. The speed is simply from one point, to the other.
Closest Approach can succeed even when there won't be a real collision. So, I'm currently using a 10-step method and calculating the distance between 2 spheres as they move along the two segments. So, basically the length of each segment is the object's traverse in the physics step, and the radius is the objects radius. By stepping, I can tell where they collide, and if they collide (Sort of; for the MOST part.)..
I get the feeling that there could be something better. While I sort of believe that the first closest approach call is required, I think that the method immediately following it is a TAD weak. Can anyone help me out? I can illustrate this if needed.
Thanks alot!
(source: yfrog.com)
(I don't know how to post graphics; bear with me.)
All right, we have two spheres with radii r1 and r2, starting at locations X1 and X2, moving with velocities V1 and V2 (X's and V's are vectors).
The velocity of sphere 1 as seen from sphere 2 is
V = V1-V2
and its direction is
v = V/|V|
The distance sphere 1 must travel (in the frame of sphere 2) to closest approach is
s = Xv
And if X is the initial separation, then the distance of closest approach is
h = |X - Xv|
This is where graphics would help. If h > r1+r2, there will be no collision. Suppose h < r1+r2. At the time of collision, the two sphere centers and the point of closest approach will form a right triangle. The distance from Sphere 1's center to the point of closest approach is
u = sqrt((r1 + r2)^2 - h^2)
So the distance sphere 1 has traveled is
s - u
Now just see if sphere 1 travels that far in the given interval. If so, then you know exactly when and where the spheres were (you must shift back from sphere 2's frame, but that's pretty easy). If not, there's no collision.
Closest approach can be done without simulating time if the position function is invertible and explicit.
Pick a path and object.
Find the point on the path where the two paths are closest. If time has bounds (e.g. paths are line segments), ignore the bounds in this step.
Find the time at which the object is at the point from the previous step.
If time has bounds, limit the picked time by the bounds.
Calculate the position of the other object at the time from the previous step.
Check if the objects overlap.
This won't work for all paths (e.g. some cubic), but should work for linear paths.

Simple Problem - Velocity and Collisions

Okay I'm working on a Space sim and as most space sims I need to work out where the opponents ship will be (the 3d position) when my bullet reaches it. How do I calculate this from the velocity that bullets travel at and the velocity of the opponents ship?
Calculate the relative velocity vector between him and yourself: this could be considered his movement if you were standing still. Calculate his relative distance vector. Now you know that he is already D away and is moving V each time unit. You have V' to calculate, and you know it's length but not it's direction.
Now you are constructing a triangle with these two constraints, his V and your bullet's V'. In two dimensions it'd look like:
Dx+Vx*t = V'x*t
Dy+Vy*t = V'y*t
V'x^2 + V'y^2 = C^2
Which simplifies to:
(Dx/t+Vx)^2 + (Dy/t+Vx)^2 = C^2
And you can use the quadratic formula to solve that. You can apply this technique in three dimensions similarly. There are other ways to solve this, but this is just simple algebra instead of vector calculus.
Collision Detection by Kurt Miller
http://www.gamespp.com/algorithms/collisionDetection.html
Add the negative velocity of the ship to the bullet, so that only the bullet moves. Then calculate the intersection of the ship's shape and the line along which the bullet travels (*pos --> pos + vel * dt*).
The question probably shouldn't be "where the ship will be when the bullet hits it," but IF the bullet hits it. Assuming linear trajectory and constant velocity, calculate the intersection of the two vectors, one representing the projectile path and another representing that of the ship. You can then determine the time that each object (ship and bullet) reach that point by dividing the distance from the original position to the intersection position by the velocity of each. If the times match, you have a collision and the location at which it occurs.
If you need more precise collision detection, you can use something like a simple BSP tree which will give you not only a fast way to determine collisions, but what surface the collision occurred on and, if handled correctly, the exact 3d location of the collision. However, it can be challenging to maintain such a tree in a dynamic environment.

Resources