I have a set of points denoted by (x y) coordinates in a space with a specified width and height, let's call this set s. Given any point p (p is not necessarily in s), I want to find the point q in s, such that the distance between p and q is minimized (i.e., find the closest point to p, that is in s).
Intuitively I feel as though I need to parse the entirety of s, and find the smallest distance by simply evaluating them all. For my application, this is unfortunately super slow.
I am wondering if there are any better ways to do this search? The only better way I can think is to organize the set s into a quadtree, find the leaf node that houses p, and check this leaf node's neighbour nodes for potential candidates for q. But that will be a lot of implementation :P
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.
In my research I confront a variant of the vertex cover problem as follows:
Given a graph G, a vertex v and a number k, to decide whether G has a vertex cover of size k
that contain v.
I have search all over literature and could not find a similar problem. I am interested in the complexity of this problem ( I have proved that it complete for $P^NP[long]$ ).
The question is have you ever seen such variant of vertex cover problem? How do you call this problem ?
Given a graph G and a integer K, to decide whether G has a vertex cover of size K is the decision problem of minimal vertex cover problem. And it is NP-complete.
If fact, the problem you described is no difference with that one. That is because if you have contained vertex v, you can remove v and all edges having v as an end-point. What you should do next is to decide whether you can cover the left sub-graph with k-1 vertices.
Given A: a point, B: A point known to exist on a plane P, C: the normal of plane P. Can I determine if A lies on P by the result of a dot product between (A - B) and C being zero? (or within a certain level of precision, I'll probably use 0.0001f)
I might just be missing some obvious mathematical flaw but this seems to be much simpler and faster than transforming the point to a triangle's coordinate space a.la the answer to Check if a point is inside a plane segment
So secondly I guess; if this is a valid check, would it be computationally faster than using matrix transformations if all I want is to see if the point is on the plane? (and not whether it lies within a polygon on said plane, I'll probably keep using matrix transforms for that)
You are correct that B lies on the plane through A and with normal P if and only if dotProduct(A-B,P) = 0.
To estimate speed for this sort of thing, you can pretty much just count the multiplications. This formula just has three multiplications, so its going to be faster than pretty much anything to do with matrices.
The above answers are closer to the proof, but not sufficient. It should be intuitive that using just two vectors is insufficient because for one, point P can be above the plane and a vertical line drawn from it to the plane would still generate a zero dot product with any single vector lying on the plane, just as it would for a point P on the plane. The necessary and sufficient condition is that if two vectors can be found on the plane then the actual plane is represented unambiguously by the cross product of the two vectors i.e.
w=uxv. By definition, w is the area vector, which is always perpendicular to the plane.
Then, for the point P in question, constructing a third vector s from either u or v should be tested against w by the dot product, s.t.
w.s=|w||s|cos(90)=0 implies that the point P lies on the plane described by w, which is in turn described by vectors u and v.
I want to write an algorithm using a dynamic programming technique, which does the following:
Find number of monotonic paths along the edges of a grid with n × n square cells, which do not pass above the diagonal. A monotonic path is one which starts in the lower left corner, finishes in the upper right corner, and consists entirely of edges pointing rightwards or upwards.
I had some ideas, but can't figure out how to do it right.
First, find a base for your recursion by solving a degenerate case (a 0 x 0 grid). Then look for a recurrence step by imagining that part of the problem, say, K x M is already solved, and see if you can expand upon that solution by adding one row or one column to it, making the solution K+1 x M or K x M+1. This should be simple: for each point you add, see if a grid point is below the diagonal, and then add up the number of paths leading to that point from the bottom and from the left. One of these points would be in the K x M, the other would be in the additional row or column that you are building.
With the degenerate case and a recursive step in hand, build your solution by first solving a 0 x N problem, then 1 x N, then 2 x N and so on, until you have your N x N solution.
Here is a possible recursion that considers only square grids.
There are two kinds of monotone paths over the n×n grid that do not cross the diagonal: those that touch the diagonal at some intermediate point (i,i) with 0 < i < n, and those that don't.
A path over the n×n grid that first touches the diagonal at (i,i) can be split in two: one path over the i×i grid that does not touch the diagonal, and another over the (n-i)×(n-i) grid and thay may touch the diagonal. This suggests that you can count those with a recursion that considers all possible i.
A path that does not touch the diagonal will start with "right", and end with "up". Between these two moves is a monotone path over a (n-1)×(n-1) grid that does not cross the diagonal but may touch it.
What we are computing here is the nth Catalan number. There is a formula for it if you want to verify your recursive computation.
Let number of path reaching coordinate (i,j) be P(i,j). Therefore (assuming bottom left corner is (0,0)):
P(i,j) = P(i-1,j) + P(i,j-1)
You can further put conditions of coordinate not going below the diagonal. That is: i ranges from 0..n, j ranges from 0..n, but i<=j always.
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?