Determine the closest point - python

Math dummy question:
Say I have a "root" coordinate (x0,y0) and a list of other coordinates ((x1,y2),(x2,y2),...(xn,yn))
Is there a computationally better method to find the nearest point to (x0,y0) than to scan through and get all the distances to (x0,y0) using the Pythagorean theorem?
Thank you

Simpler than doing 2 multipltication?
I don't think so.
Just be aware that you do not need to compute the square root to compare which point is closer (because sqrt is a monotonoic incleasing function).
So compute (x0-xi)^2+(y0-yi)^2 for each i in {1,..,n}
and take the one with the smallest value. That's the nearest point.

Related

Points in which polygon

I have several (order of M) points [(x0,y0),...,(xn,yn)]. I also have limited number of hexagons. I want to find each point falls in which hexagon. Using shapely this can be done for 1 point at a time so the loop below does the job. But is there any other way to do it faster?
from shapely.geometry import Point
from shapely.geometry.polygon import Polygon
zones = np.zeros(n)-1
for j,p in enumerate(points):
point = Point(p)
for i in range(len(poly_hex)): #poly_hex = list of hexagonal polygones
polygon = Polygon(poly_hex[i])
if polygon.contains(point):
zones[j] = int(i)
break
Some ideas to speed things up:
Don't convert your hexagons to polygon = Polygon(poly_hex[i]) at each step of the inner loop. Calculate them once before the loop and store them in a list.
As the surface of a hexagon is close to a circle, also make a list of just the centre and the radius of the hexagons. Inside the loop, first test the distance between the point p and the centre of each hexagon, comparing to the radius. Only in case p is less than the radius to the centre, do an explicit test to see whether it is inside the hexagon.
If this still isn't fast enough, and depending on how small, and how far apart the hexagons are relative to your points, you could speed things up further with a quadtree or a grid. But this is less trivial. If most of the points are outside all hexagons, you could first test whether p is inside the convex hull of the hexagons.
Some remarks:
I don't understand your zone[j] = int(i). You convert i to an integer, while it already is an integer. Also, the way you store this, means a point can only be inside maximum one hexagon. Therefore, you can stop the loop as soon as you encountered such a hexagon. (There is also the rare case where a point is just on the edge between two hexagon. This might assign it to the first hexagon encountered. Or, due to rounding errors, even might have it outside both hexagons.)
If you want to save the zones as integers, create it as: zones = np.zeros(n, dtype=int)-1.
If your hexagons form a regular hexagonal grid, you can find the exact hexagon simply from the x and y coordinates without the need for in-polygon testing.

How to find an estimate for the point of inflection of array of numbers? (Python)

Let's say i have an array of numbers. If i sort the array i have a decently smoothed curve. Is there an easy way to get an estimate for the point where the slope of the line increases the most? (I think this is called point of inlection.
Example:
In a digital signal, the derivative correlates to the difference between two adjacent values.
So to get that, if a is a numpy array:
a_prime = a[1:] - a[:-1]
What you're looking for is the point at which the derivative of the derivative is the greatest (which isn't the inflection point):
answer = np.argmax(a_prime[1:] - a_prime[:-1])

Is squared Euclidien distance a admissible heuristic?

I have a grid such as shown in the picture. So far I have implemented below functions as my heuristic functions. So the goal of this game is to collect all the numbers placed on this grid. Starting point A.
Manhattan distance and then take the maximum of it to calculate the heuristic.
distance = abs(A_x-x_i)+abs(A_y-y_i)
if distance > manhMax:
manhMax = distance
Summation of all the Manhattan distances to numbers placed. (This I presume is not admissible since it over estimate the distance to reach the goal-correct me if I am wrong)
My question is, first method expand states more than what I need and the second method is not admissible. I am implementing my own heuristic at the moment.
I came up with the idea, calculating squared Euclidean distance between distance between distances from A to 2 and then to 1 and then to 3 and 0. There is no order as such to collect the numbers. However the problem is just Euclidean distance expand too many states though it is admissible. Could you help me with a suitable distance or method to achieve my task.
Thank you!
I suspect you're having trouble interpreting your approach, because this problem does not have the simple, single-goal paradigm used to define "admissible". Rather, you have a small TSP (Traveling Salesman Problem), in which you can collect the items in any of 4! orders. You didn't describe which distance you used in your approach, but no simplistic computation will do. Adding all 10 distances (for n=5 nodes; 5x4 / 2) is simply over-spending, as you will traverse only 4 of those edges. Similarly, adding the distances from A to each of the items is wrong.
Instead, you need to use the heuristic on each edge of the path, add then generate the heuristic estimate for the four-edge path under consideration. For this treatment, Euclidean distance is admissible -- but its square is not: it seriously overestimates, and is in the wrong units (area, rather than distance). Manhattan distance will likely be better for you.
Note that you have a problem case in this example, as edge 3-0 will be underestimated by a factor of 4 to 5, depending on your heuristic.

Looking for a clustering algorithm, that can cluster by density around a centroid, but with a fixed maximum distance cutoff

I currently have a list with 3D coordinates which I want cluster by density into a unknown number of clusters. In addition to that I want to score the clusters by population and by distance to the centroids.
I would also like to be able to set a maximum possible distance from a certain centroid. Ideally the centroid represent a point of the data-set, but it is not absolutely necessary. I want to do this for a list ranging from approximately 100 to 10000 3D coordinates.
So for example, say i have a point [x,y,z] which could be my centroid:
Points that are closest to x,y,z should contribute the most to its score (i.e. a logistic scoring function like y = (1 + exp(4*(-1.0+x)))** -1 ,where x represents the euclidean distance to point [x,y ,z]
( https://www.wolframalpha.com/input/?i=(1+%2B+exp(4(-1.0%2Bx)))**+-1 )
Since this function never reaches 0, it is needed to set a maximum distance, e.g. 2 distance units to set a limit to the cluster.
I want to do this until no more clusters can be made, I am only interested in the centroid, thus it should preferably be a real datapoint instead of an interpolated one it also has other properties connected to it.
I have already tried DBSCAN from sklearn, which is several orders of magnitude faster than my code, but it does obviously not accomplish what I want to do
Currently I am just calculating the proximity of every point relative to all other points and am scoring every point by the number and distance to its neighbors (with the same scoring function discussed above), then I take the highest scored point and remove all other, lower scored, points that are within a certain cutoff distance. It gets the job done and is accurate, but it is too slow.
I hope I could be somewhat clear with what I want to do.
Use the neighbor search function of sklearn to find points within the maximum distance 2 fast. Only do this once compute the logistic weights only once.
Then do the remainder using ony this precomputed data?

Fastest algorithm to find the max distance within a set of points [duplicate]

This is a question that I was asked on a job interview some time ago. And I still can't figure out sensible answer.
Question is:
you are given set of points (x,y). Find 2 most distant points. Distant from each other.
For example, for points: (0,0), (1,1), (-8, 5) - the most distant are: (1,1) and (-8,5) because the distance between them is larger from both (0,0)-(1,1) and (0,0)-(-8,5).
The obvious approach is to calculate all distances between all points, and find maximum. The problem is that it is O(n^2), which makes it prohibitively expensive for large datasets.
There is approach with first tracking points that are on the boundary, and then calculating distances for them, on the premise that there will be less points on boundary than "inside", but it's still expensive, and will fail in worst case scenario.
Tried to search the web, but didn't find any sensible answer - although this might be simply my lack of search skills.
For this specific problem, with just a list of Euclidean points, one way is to find the convex hull of the set of points. The two distant points can then be found by traversing the hull once with the rotating calipers method.
Here is an O(N log N) implementation:
http://mukeshiiitm.wordpress.com/2008/05/27/find-the-farthest-pair-of-points/
If the list of points is already sorted, you can remove the sort to get the optimal O(N) complexity.
For a more general problem of finding most distant points in a graph:
Algorithm to find two points furthest away from each other
The accepted answer works in O(N^2).
Boundary point algorithms abound (look for convex hull algorithms). From there, it should take O(N) time to find the most-distant opposite points.
From the author's comment: first find any pair of opposite points on the hull, and then walk around it in semi-lock-step fashion. Depending on the angles between edges, you will have to advance either one walker or the other, but it will always take O(N) to circumnavigate the hull.
You are looking for an algorithm to compute the diameter of a set of points, Diam(S). It can be shown that this is the same as the diameter of the convex hull of S, Diam(S) = Diam(CH(S)). So first compute the convex hull of the set.
Now you have to find all the antipodal points on the convex hull and pick the pair with maximum distance. There are O(n) antipodal points on a convex polygon. So this gives a O(n lg n) algorithm for finding the farthest points.
This technique is known as Rotating Calipers. This is what Marcelo Cantos describes in his answer.
If you write the algorithm carefully, you can do without computing angles. For details, check this URL.
A stochastic algorithm to find the most distant pair would be
Choose a random point
Get the point most distant to it
Repeat a few times
Remove all visited points
Choose another random point and repeat a few times.
You are in O(n) as long as you predetermine "a few times", but are not guaranteed to actually find the most distant pair. But depending on your set of points the result should be pretty good. =)
This question is introduced at Introduction to Algorithm. It mentioned 1) Calculate Convex Hull O(NlgN). 2) If there is M vectex on Convex Hull. Then we need O(M) to find the farthest pair.
I find this helpful links. It includes analysis of algorithm details and program.
http://www.seas.gwu.edu/~simhaweb/alg/lectures/module1/module1.html
Wish this will be helpful.
Find the mean of all the points, measure the difference between all points and the mean, take the point the largest distance from the mean and find the point farthest from it. Those points will be the absolute corners of the convex hull and the two most distant points.
I recently did this for a project that needed convex hulls confined to randomly directed infinite planes. It worked great.
See the comments: this solution isn't guaranteed to produce the correct answer.
Just a few thoughts:
You might look at only the points that define the convex hull of your set of points to reduce the number,... but it still looks a bit "not optimal".
Otherwise there might be a recursive quad/oct-tree approach to rapidly bound some distances between sets of points and eliminate large parts of your data.
This seems easy if the points are given in Cartesian coordinates. So easy that I'm pretty sure that I'm overlooking something. Feel free to point out what I'm missing!
Find the points with the max and min values of their x, y, and z coordinates (6 points total). These should be the most "remote" of all the boundary points.
Compute all the distances (30 unique distances)
Find the max distance
The two points that correspond to this max distance are the ones you're looking for.
Here's a good solution, which works in O(n log n). It's called Rotating Caliper’s Method.
https://www.geeksforgeeks.org/maximum-distance-between-two-points-in-coordinate-plane-using-rotating-calipers-method/
Firstly you find the convex hull, which you can make in O(n log n) with the Graham's scan. Only the point from the convex hull can provide you the maximal distance. This algorithm arranges points of the convex hull in the clockwise traversal. This property will be used later.
Secondly, for all the points on the convex hull, you'll need to find the most distant point on this hull (it's called the antipodal point here). You don't have to find all the antipodal points separately (which would give quadratic time). Let's say the points of the convex hall are called p_1, ..., p_n, and their order corresponds to the clockwise traversal. There is a property of convex polygons that when you iterate through points p_j on the hull in the clockwise order and calculate the distances d(p_i, p_j), these distances firstly don't decrease (and maybe increase) and then don't increase (and maybe decrease). So you can find the maximum distance easily in this case. But when you've found the correct antipodal point p_j* for the p_i, you can start this search for p_{i+1} with the candidates points starting from that p_j*. You don't need to check all previously seen points. in total p_i iterates through points p_1, ..., p_n once, and p_j iterates through these points at most twice, because p_j can never catch up p_i as it would give zero distance, and we stop when the distance starts decreasing.
A solution that has runtime complexity O(N) is a combination of the above
answers. In detail:
(1) One can compute the convex hull with runtime complexity O(N) if you
use counting sort as an internal polar angle sort and are willing to
use angles rounded to the nearest integer [0, 359], inclusive.
(2) Note that the number of points on the convex hull is then N_H which is usually less than N.
We can speculate about the size of the hull from information in Cormen et al. Introduction to Algorithms, Exercise 33-5.
For sparse-hulled distributions of a unit-radius disk, a convex polygon with k sides, and a 2-D normal distribution respectively as n^(1/3), log_2(n), sqrt(log_2(n)).
The furthest pair problem is then between comparison of points on the hull.
This is N_H^2, but each leading point's search for distance point can be
truncated when the distances start to decrease if the points are traversed
in the order of the convex hull (those points are ordered CCW from first point).
The runtime complexity for this part is then O(N_H^2).
Because N_H^2 is usually less than N, the total runtime complexity
for furthest pair is O(N) with a caveat of using integer degree angles to reduce the sort in the convex hull to linear.
Given a set of points {(x1,y1), (x2,y2) ... (xn,yn)} find 2 most distant points.
My approach:
1). You need a reference point (xa,ya), and it will be:
xa = ( x1 + x2 +...+ xn )/n
ya = ( y1 + y2 +...+ yn )/n
2). Calculate all distance from point (xa,ya) to (x1,y1), (x2,y2),...(xn,yn)
The first "most distant point" (xb,yb) is the one with the maximum distance.
3). Calculate all distance from point (xb,yb) to (x1,y1), (x2,y2),...(xn,yn)
The other "most distant point" (xc,yc) is the one with the maximum distance.
So you got your most distant points (xb,yb) (xc,yc) in O(n)
For example, for points: (0,0), (1,1), (-8, 5)
1). Reference point (xa,ya) = (-2.333, 2)
2). Calculate distances:
from (-2.333, 2) to (0,0) : 3.073
from (-2.333, 2) to (1,1) : 3.480
from (-2.333, 2) to (-8, 5) : 6.411
So the first most distant point is (-8, 5)
3). Calculate distances:
from (-8, 5) to (0,0) : 9.434
from (-8, 5) to (1,1) : 9.849
from (-8, 5) to (-8, 5) : 0
So the other most distant point is (1, 1)

Categories