Reputation: 512
I have a given S point (red on the graph) and n other points (black on the graph). I want to find a point P, in a distance of 1 from S, which is the furthest from all the black points (in this case - the sum of distances between P and each point should is the highest).
As P is 1 away from S, we can tell that y = √(1 - x^2)
.
The analitical way I would personally use would be to:
Q - P = √((Qx - Sx - x)^2 + (Qy - Sy - √(1 - x^2))^2)
(repeat of all n points and sum up),What would be the most efficient way to do this in Java and what libraries could be used? I heard about libraries allowing to do this analyticaly, but it sounds complicated and slow so I was searching for any numerical ideas, but couldn't find any.
Upvotes: 2
Views: 1186
Reputation: 3736
EDIT: The algorithm below doesn't work as explained in the comments. I'll keep it here as a reference.
This might a bit naive, but how about:
Corner-case: if all black points are point-symmetrical around the origin (for example, one point at -2,-2 and one point at 2,2; then the solution above would have no answer because A (the average point) would equal S (origin 0,0). You can do an additional check for A being equal to S and then throw an exception.
Upvotes: 0
Reputation: 798
First of all, it seems that O(N^2) is not so bad in the worst case for this problem. Because each call to cost function costs O(N). Consider this situation: N black points, which lie on another circle (R > 1, center in S) and split this new circle into N equal arcs. In this symmetric case, we have N maximums. Just to check them it takes O(N^2) — compute cost function in each point. So I think any algorithm which examines all local extremums will have at least O(N^2) in the worst case.
Here my solution sketch for general case:
If {Q_j} are black points, let`s define {O_j} so that each O_j is the closest point to Q_j which lies on the red circle around S. Points {O_j} split the circle into n arcs. We can calculate each O_j coords easily.
It seems that cost function which we are trying to optimize has only one local extremum within each arc (this part need more accurate proof), so we could find these extremums by ternary search -- linearithmic complexity. We need to check O_j for local extremums as well -- linear complexity.
Totally, we have to check O(NlogN) points, each check costs O(N). At least this method is more convenient than checking every point on circle with small epsilon.
Upvotes: 0
Reputation: 11
Follow the path of the circle in SMALL incrementials. Calculate the sum of distances for each point along the circle. Find the position where the sum of distances are the maximum. Done. java.lang.Math is enough for this. No need of extra libraries. Look up trigonometry.
SP segment's angle is phi. You go from 0 to 2*pi (remember it uses radians). Increment phi with a small number in your loop.
Something like:
At the end of the loop You will have the phi angle's value where the sum of distances was the biggest. Then you recalculate the coordinates of P from phi, and the distance of SP.
This might be a bruteforce approach, but calculating derivatives for this seems overkill, and too complicated.
Upvotes: 1