I'm working through this programming challenge and I'm having some difficulties understanding how the chess board is composed. From what I manage to understand is:
We receive a board chess of size 4*4 which give us 16.
We receive our input test for our attacker and we need to check with the formula abs(x-xi) + abs(y-yi) <= ri. The result of the operation needs to be less or equal to ri, if this conditional is correct that square of the chess board can be attacked by the attacker.
What I planned to do is starting a chess board where the first square is (0,0) and the last square is (3,3). I need to iterate from that first position, then do the operations to find if that square is less than Ri, if its less than mark that entrance with a counter and continue.
I did it by hand to check if the output of the first case was correct, I got a 5 reachable squares but the output got a 10. I redraw my chess board starting from (1,1) to (4,4) did the math by hand and also got a 5. The first test is (1,1,1) the attacker is in position (1,1) with a range of 1.
If I use the board starting in (0,0) the squares that can be attacked are: 2,5,6,7 and 10. If I use the board starting in (1,1) the squares are: 1,2,5,9 and 10.
First, I would stick with their notation and do things 1-based. Second, people do attack the square they are on. So in the first case, the (1,1) attacker attacks (1,1), (1,2), and (2,1), the (3,1) attacks (3,1), (3,2), and (4,1) [also (2,1), but we already counted that] and (3,3) attacks itself, (2,3), (3,4) and (4,3). [also (3,2), which we already counted] That is 10 squares attacked as claimed.
The next case specifies a new board which is 1 by 10 with 1 attacker. That attacker sits on (1,1) and attacks (1,1) and (1,2) so 2 squares. Then your algorithm should work (the way you describe, you would need to nest a second loop of iterations over attackers, but I would rather read an attacker at a time in a loop and then iterate over the squares).
Related
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.
I'm writing a tower defense game, and I'm implementing the A* path finding algorithm from tutorials and what not, but I've encountered a situation I can't code out of as of yet! Consider the graphic below. The cyan nodes represent the shortest path found so far, the violet nodes represent inspected nodes, and the dark gray nodes represent a wall.
From what I know of the A* algorithm, to calculate a path for the situation below, it...
Starts at "start" and checks if the upper node is available. It is. It calculates its G and H scores. It does the same to the right, lower, and left nodes.
Finds that the right node has the lowest F score (F = G + H). It then repeats the same method as step #1 to find the next node, marking the "start" node as the parent.
Continues this pattern and lands on the node in the center of the "C trap," as this node has the lowest F score so far.
Discovers that the upper, right, lower, and left nodes are all closed. A* then marks this node as closed and starts over, understanding to leave this node alone.
What happens immediately after #4? Would A* re-examine the G and H scores along the same path, skipping that newly-closed node? Also, when drawing this scenario with this SWF, it indicates that more nodes are discovered to make up for the trap, as suggested here. Why?
What you seem to be missing is that A* is not like a single unit moving along the grid, and backtracking when it hits a wall; it's more like an observer looking at various nodes around the graph, always considering next the node "most likely" to be in the shortest path.
So, step 4 above never happens. A* doesn't mark a node as closed when it determines it can't be part of the best-path - it simply puts every single node it vists in the closed list, as soon as it visits it. And it doesn't ever "start over" - it's always looking at the next "most likely" node, where "most likely" means the front of the priority queue ordered by f(x).
So, in your example above, A* will jump to one of the blue-nodes next, since they are all in the open list, and all have the same f(x) value. Though it could technically consider any one of them next, if you use the correct tie-breaking criteria, it will take one of the two that are closest to the end.
I want to have an estimation of the location of a user using the surrounding cell towers. For each tower, I have a location and a signal strength. Now I use a simple means of the coordinates but it is not very accurate (the user is not necessarily between the two towers).
I guess the solution is to draw a circle around each tower (the less the signal strength is, the larger it will be) and them compute the intersection between the circles. I usually don't have more than 3 cell towers.
Any idea how ? I found the Delaunay triangulation method but I don't think it applies here.
Thank you
You need to convert each signal strength to an estimate of distance and then use each distance (as the radius of a circle) in order to triangulate. You'll need at least three transmitters to resolve ambiguity, and accuracy will not be great, since signal strength is only very approximately related to distance and is affected by numerous external factors in the real world. Note that in ideal conditions, signal strength follows an inverse square law with distance.
I just want to make sure this would work. Could you find the greatest path using Dijkstra's algorithm? Would you have to initialize the distance to something like -1 first and then change the relax subroutine to check if it's greater?
This is for a problem that will not have any negative weights.
This is actually the problem:
Suppose you are given a diagram of a telephone network, which is a graph
G whose vertices represent switches centers, and whose edges represent communication
lines between two centers. The edges are marked by their bandwidth of its lowest
bandwidth edge. Give an algorithm that, given a diagram and two switches centers a
and b, will output the maximum bandwidth of a path between a and b.
Would this work?
EDIT:
I did find this:
Hint: The basic subroutine will be very similar to the subroutine Relax in Dijkstra.
Assume that we have an edge (u, v). If min{d[u],w(u, v)} > d[v] then we should update
d[v] to min{d[u],w(u, v)} (because the path from a to u and then to v has bandwidth
min{d[u],w(u, v)}, which is more than the one we have currently).
Not exactly sure what that's suppose to mean though since all distance are infinity on initialization. So, i don't know how this would work. any clues?
I'm not sure Djikstra's is the way to go. Negative weights do bad, bad things to Djikstra's.
I'm thinking that you could sort by edge weight, and start removing the lowest weight edge (the worst bottleneck), and seeing if the graph is still connected (or at least your start and end points). The point at which the graph is broken is when you know you took out the bottleneck, and you can look at that edge's value to get the bandwidth. (If I'm not mistaken, each iteration takes O(E) time, and you will need O(E) iterations to find the bottleneck edge, so this is an O(E2) algorithm.
Edit: you have to realize that the greatest path isn't necessarily the highest bandwidth: you're looking to maximize the value of min({edges in path}), not sum({edges in path}).
You can solve this easily by modifying Dijkstra's to calculate maximum bandwidth to all other vertices.
You do not need to initialize the start vertex to -1.
Algorithm: Maximum Bandwidth(G,a)
Input: A simple undirected weighted graph G with non -ve edge weights, and a distinguished vertex a of G
Output: A label D[u], for each vertex u of G, such that D[u] is the maximum bandwidth available from a to u.
Initialize empty queue Q;
Start = a;
for each vertex u of G do,
D[u] = 0;
for all vertices z adjacent to Start do{ ---- 1
If D[Start] => D[z] && w(start, z) > D[z] {
Q.enqueue(z);
D[z] = min(D[start], D[z]);
}
}
If Q!=null {
Start = Q.dequeue;
Jump to 1
}
else
finish();
This may not be the most efficient way to calculate the bandwidth, but its what I could think of for now.
calculating flow may be more applicable, however flow allows for multiple paths to be used.
Just invert the edge weights. That is, if the edge weight is d, consider it instead as d^-1. Then do Dijkstra's as normal. Initialize all distances to infinity as normal.
You can use Dijkstra's algorithm to find a single longest path but since you only have two switch centers I don't see why you need to visit each node as in Dijkstra's. There is most likes a more optimal way of going this, such as a branch and bound algorithm.
Can you adjust some of the logic in algorithm AllPairsShortestPaths(Floyd-Warshall)?
http://www.algorithmist.com/index.php/Floyd-Warshall%27s_Algorithm
Initialize unconnected edges to negative infinity and instead of taking the min of the distances take the max?
Background
There is a square map with some obstacles on it. Obstacles are represented by polygons. I implemented following path finding algorithm:
1) Choose precision (it'll be denoted by k)
2) Divide map into k x k squares.
3) Make graph from those squares according to the following rules:
- Every node represents one square
- Two nodes are connected if and only if they are adjacent and none of them cosist any obstacle.
4) Find shortest path using A* algorithm (or Dijkstra or some other...)
This algorithm works quite well if map is not dynamic. It means that obstacles can't be moved.
Questions
1) Is that efficient approach?
2) What to do if obstacles can be moved?
3) How to treat other agents? Lets consider situation where there 100agents in the room. There are two exists. All agents are in one group, and that group near one of the exits. If all agents go to the nearest exit then it'll cause a bottleneck. Some of them should go to the other exit to minimize time needed to exit. How to get such result?
Use the A* path as a general guideline around static obstacles and perform local Obstacle Avoidance for dynamic (smaller) obstacles. Reynolds also has an algorithm for the bottleneck-problem. He calls it Queueing.