I have assumed the points are distinct, otherwise there might not even be such a line.
If points are distinct, then such a line always exists and is possible to find using a deterministic O(nlogn) time algorithm.
Say the points are P1, P2, ..., P2n. Assume they are not all on the same line. If they were, then we can easily form the splitting line.
First translate the points so that all the co-ordinates (x and y) are positive.
Now suppose we magically had a point Q on the y-axis such that no line formed by those points (i.e. any infinite line Pi-Pj) passes through Q.
Now since Q does not lie within the convex hull of the points, we can easily see that we can order the points by a rotating line passing through Q. For some angle of rotation, half the points will lie on one side and the other half will lie on the other of this rotating line, or, in other words, if we consider the points being sorted by the slope of the line Pi-Q, we could pick a slope between the (median)th and (median+1)th points. This selection can be done in O(n) time by any linear time selection algorithm without any need for actually sorting the points.
Now to pick the point Q.
Say Q was (0,b).
Suppose Q was collinear with P1 (x1,y1) and P2 (x2,y2).
Then we have that
(y1-b)/x1 = (y2-b)/x2 (note we translated the points so that xi > 0).
Solving for b gives
b = (x1y2 - y1x2)/(x1-x2)
(Note, if x1 = x2, then P1 and P2 cannot be collinear with a point on the Y axis).
Consider |b|.
|b| = |x1y2 - y1x2| / |x1 -x2|
Now let the xmax be the x-coordinate of the rightmost point and ymax the co-ordinate of the topmost.
Also let D be the smallest non-zero x-coordinate difference between two points (this exists, as not all xis are same, as not all points are collinear).
Then we have that |b| <= xmax*ymax/D.
Thus, pick our point Q (0,b) to be such that |b| > b_0 = xmax*ymax/D
D can be found in O(nlogn) time.
The magnitude of b_0 can get quite large and we might have to deal with precision issues.
Of course, a better option is to pick Q randomly! With probability 1, you will find the point you need, thus making the expected running time O(n).
If we could find a way to pick Q in O(n) time (by finding some other criterion), then we can make this algorithm run in O(n) time.
Create an arbitrary line in that plane. Project each point onto that line a.k.a for each point, get the closest point on that line to that point.
Order those points along the line in either direction, and choose a point on that line such that there is an equal number of points on the line in either direction.
Get the line perpendicular to the first line which passes through that point. This line will have half the original points on either side.
There are some cases to avoid when doing this. Most importantly, if all the point are themselves on a single line, don't choose a perpendicular line which passes through it. In fact, choose that line itself so you don't have to worry about projecting the points. In terms of the actual mathematics behind this, vector projections will be very useful.
If number of points is odd, return "impossible".
Pick a random line (two random points)
Project all points onto this line (`O(N)` operation)
(i.e. we pretend this line is our new X'-axis, and write down the
X'-coordinate of each point)
Perform any median-finding algorithm on the X'-coordinates
(`O(N)` or faster-if-desired operation)
(returns 2 medians if no overlapping points)
Return the line perpendicular to original random line that splits the medians
In rare case of overlapping points, repeat a few times (it would take
a pathological case to prevent a solution from existing).
For every "critical slope range", perform the above algorithm
by choosing a line with a slope within the range.
If all critical slope ranges fail, the solution is impossible.
If number of points is odd, return "impossible".
Pick a random line (two random points)
Project all points onto this line (`O(N)` operation)
(i.e. we pretend this line is our new X'-axis, and write down the
X'-coordinate of each point)
Perform any median-finding algorithm on the X'-coordinates
(`O(N)` or faster-if-desired operation)
(returns 2 medians if no overlapping points)
Return the line perpendicular to original random line that splits the medians
In rare case of overlapping points, repeat a few times (it would take
a pathological case to prevent a solution from existing).
This is O(N) unlike other proposed solutions.
Assuming a solution exists, the above method will probably terminate, though I don't have a proof.
Try the above algorithm a few times unless you detect overlapping points. If you detect a high number of overlapping points, you may be in for a rough ride, but there is a terribly inefficient brute-force solution that involves checking all possible angles:
For every "critical slope range", perform the above algorithm
by choosing a line with a slope within the range.
If all critical slope ranges fail, the solution is impossible.
A critical angle is defined as the angle which could possibly change the result (imagine the solution to a previous answer, rotate the entire set of points until one or more points swaps position with one or more other points, crossing the dividing line. There are only finitely many of these, and I think they are bounded by the number of points, so you're probably looking at something in the range O(N^2)-O(N^2 log(N)) if you have overlapping points, for a brute-force approach.
I'd guess that a good way is to sort/sequence/order the points (e.g. from left to right), and then choose a line which passes through (or between) the middle point[s] in the sequence.
There are obvious cases where no solution is possible. E.g. when you have three heaps of points. One point at location A, Two points at location B, and five points at location C.
If you expect some decent distribution, you can probably get a good result with tlayton's algorithm. To select the initial line slant, you could determine the extent of the whole point set, and choose the angle of the largest diagonal.
The median equally divides a set of numbers in the manner similar to what you're trying to accomplish, and it can be computed in O(n) time using a selection algorithm (the writeup in Cormen et al is better, so you may want to look there instead). So, find the median of your x values Mx (or your y values My if you prefer) and set x = Mx (or y = My) and that line will be axially aligned and split your points equally.
If the nature of your problem requires that no more than one point lies on the line (if you have an odd number of points in your set, at least one of them will be on the line) and you discover that's what's happened (or you just want to guard against the possibility), rotate all of your points by some random angle, θ, and compute the median of the rotated points. You then rotate the median line you computed by -θ and it will evenly divide points.
The likelihood of randomly choosing θ such that the problem manifests itself again is very small with a finite number of points, but if it does, try again with a different θ.
4) 如何找到一条将点均匀分割的线?求 (n - 1) 个角度的中值。从点 P 到具有该中位角的点的线将均匀地分割这些点。
该算法的时间复杂度为 O(n)。
Here is how I approach this problem (with the assumption that n is even and NO three points are collinear):
1) Pick up the point with smallest Y value. Let's call it point P.
2) Take this point as the new origin point, so that all other points will have positive Y values after this transformation.
3) For every other point (there are n - 1 points remaining), think it under the polar coordinate system. Each other point can be represented with a radius and angle. You could ignore the radius and just focus on the angle.
4) How can you find a line that split the points evenly? Find the median of (n - 1) angles. The line from point P to the point with that median angle will split the points evenly.
I dont know how useful this is I have seen a similar problem...
If you already have the directional vector (aka the coefficients of the dimensions of your plane).
You can then find two points inside that plane, and by simply using the midpoint formula you can find the midpoint of that plane.
Then using the coefficients of that plane and the midpoint you can find a plane that is from equal distance from both points, using the general equation of a plane.
A line then would constitute in expressing one variable in terms of the other so you would find a line with equal distance between both planes.
There are different methods of doing this such as projection using the distance equation from a plane but I believe that would complicate your math a lot.
与我们所有点都是不同的假设相矛盾。因此,m1, new =/= m2, new,并且没有两点与 Q 共线。
To add to M's answer: a method to generate a Q (that's not so far away) in O(n log n).
To begin with, let Q be any point on the y-axis ie. Q = (0,b) - some good choices might be (0,0) or (0, (ymax-ymin)/2).
Now check if there are two points (x1, y1), (x2, y2) collinear with Q. The line between any point and Q is y = mx + b; since b is constant, this means two points are collinear with Q if their slopes m are equal. So determine the slopes mi for all points and check if there are any duplicates: (amoritized O(n) using a hash-table)
If all the m's are distinct, we're done; we found Q, and M's algorithm above generates the line in O(n) steps. If two points are collinear with Q, we'll move Q up just a tiny amount ε, Qnew = (0, b + ε), and show that Qnew will not be collinear with two other points.
The criterion for ε, derived below, is:
ε < mminΔ*xmin
To begin with, our m's look like this:
mi = yi/xi - b/xi
Let's find the minimum difference between any two distinct mi and call it mminΔ(O(n log n)by, for instance, sorting then comparing differences between mi and i+1 for all i)
If we fudge b up by ε, the new equation for m becomes:
mi,new = yi/xi - b/xi - ε/xi
= mi,old - ε/xi
Since ε > 0 and xi > 0, all m's are reduced, and all are reduced by a maximum of ε/xmin. Thus, if
ε/xmin < mminΔ, ie.
ε < mminΔ*xmin
is true, then two mi which were previously unequal will be guaranteed to remain unequal.
All that's left is to show that if m1,old = m2,old, then m1,new =/= m2,new. Since both mi were reduced by an amount ε/xi, this is equivalent to showing x1 =/= x2. If they were equal, then:
y1 = m1,oldx1 + b = m2,oldx2 + b = y2
Contradicting our assumption that all points are distinct. Thus, m1, new =/= m2, new, and no two points are collinear with Q.
对于所有点 Pi 计算 Pc、Q 和 Pi 和 之间的角度 ai Pd、Q 和 Pi 之间的角度 bi> O(n)
得到具有最小角度 ag 的点 Pg(其中 ag>0° 且 a g<180°) >; O(n)
得到具有最小角度 bh 的点 Ph(其中 bh>0° 且 b h<180°) >; O(n)
如果没有任何 Pg 或 Ph(所有点具有相同的 x 值) 在任意位置创建一个新点 R (xa+1, 0),但 x 值与 xa 否则如果 ag 低于 bh 创建一个新点 R ((xc+xg)/2, (yc+yg )/2) 在 Pc 和 Pg 之间 否则 创建一个新点 R ((xd+xh)/2, (yd+yh )/2) 在 Pd 和 Ph 之间 > O(1)
由 Q 和 R 确定的线将点 > O(1)
I picked up the idea from Moron and andand and continued to form a deterministic O(n) algorithm.
I also assumed that the points are distinct and n is even (thought the algorithm can be changed so that uneven n with one point on the dividing line are also supported).
The algorithm tries to divide the points with a vertical line between them. This only fails if the points in the middle have the same x value. In that case the algorithm determines how many points with the same x value have to be on the left and lower site and and accordingly rotates the line.
I'll try to explain with an example. Let's asume we have 16 points on a plane. First we need to get the point with the 8th greatest x-value and the point with the 9th greatest x-value. With a selection algorithm this is possible in O(n), as pointed out in another answer. If the x-value of that points is different, we are done. We create a vertical line between that two points and that splits the points equal.
Problematically now is if the x-values are equal. So we have 3 sets of points. That on the left side (x < xa), in the middle (x = xa) and that on the right side (x > xa). The idea now is to count the points on the left side and calculate how many points from the middle needs to go there, so that half of the points are on that side. We can ignore the right side here because if we have half of the points on the left side, the over half must be on the right side.
So let's asume we have we have 3 points (c=3) on the left side, 6 in the middle and 7 on the right side (the algorithm doesn't know the count from the middle or right side, because it doesn't need it, but we could also determine it in O(n)). We need 8-3=5 points from the middle to go on the left side. The points we already got in the first step are useless now, because they are only determined by the x-value and can be any of the points in the middle.
We want the 5 points from the middle with the lowest y-value on the left side and the point with the highest y-value on the right side. Again using the selection algorithm, we get the point with the 5th greatest y-value and the point with the 6th greatest y-value. Both points will have the x-value equal to xa, else we wouldn't get to this step, because there would be a vertical line.
Now we can create the point Q in the middle of that two points. Thats one point from the resulting line. Another point is needed, so that no points from the left or right side are divided. To get that point we need the point from the left side, that has the lowest angle (bh) between the the vertical line at xa and the line determined by that point and Q. We also need that point from the right side (with angle ag). The new point R is between the point with the lower angle and a point on the vertical line (if the lower angle is on the left side a point above Q and if the lower angle is on the right side a point below Q).
The line determined by Q and R divides the points in the middle so that there are a even number of points on both sides. It doesn't divide any points on the left or right side, because if it would that point would have a lower angle and would have been choosen to calculate R.
From the view of a mathematican that should work well in O(n). For computer programs it is fairly easy to find a case where precision becomes a problem. An example with 4 points would be A(0, 100000000), B(0, 100000001), C(0, 0), D(0.0000001, 0). In this example Q would be (0, 100000000.5) and R (0.00000005, 0). Which gives B and C on the left side and A and D on the right side. But it is possible that A and B are both on the dividing line, because of rounding errors. Or maybe only one of them. So it belongs to the input values if this algorithm suits to the requirements.
get that two points Pa(xa, ya) and Pb(xb, yb) which are the medians based on the x values > O(n)
if xa != xb you can stop here because a y-axis parallel line between that two points is the result > O(1)
get all points where the x value equals xa> O(n)
count points with x value less than xa as c > O(n)
get the lowest point Pc based on the y values from the points from 3. > O(n)
get the greatest point Pd based on the y values from the points from 3. > O(n)
get the (n/2-c)th greatest point Pe based on the y values from the points from 3. > O(n)
also get the next greatest point Pf based on the y values from the points from 3. > O(n)
create a new point Q (xa, (ye+yf)/2) between Pe and Pf> O(1)
for all points Pi calculate the angle ai between Pc, Q and Pi and the angle bi between Pd, Q and Pi> O(n)
get the point Pg with the lowest angle ag (with ag>0° and ag<180°) > O(n)
get the point Ph with the lowest angle bh (with bh>0° and bh<180°) > O(n)
if there aren't any Pg or Ph (all points have same x value) create a new point R (xa+1, 0) anywhere but with a different x value than xa else if ag is lower than bh create a new point R ((xc+xg)/2, (yc+yg)/2) between Pc and Pg else create a new point R ((xd+xh)/2, (yd+yh)/2) between Pd and Ph> O(1)
the line determined by Q and R divides the points > O(1)
发布评论
评论(10)
我假设这些点是不同的,否则甚至可能不存在这样的线。
如果点是不同的,那么这样的线总是存在,并且可以使用确定性 O(nlogn) 时间算法找到。
假设这些点是 P1、P2、...、P2n。假设它们并不都在同一条线上。如果是的话,那么我们就可以轻松地形成分割线。
首先平移点,使所有坐标(x 和 y)均为正值。
现在假设我们神奇地在 y 轴上有一个点 Q,使得这些点形成的线(即任何无限线 Pi-Pj)都不会穿过 Q。
现在,由于 Q 不在这些点的凸包内,我们可以很容易看出,我们可以通过穿过 Q 的旋转线对点进行排序。对于某个旋转角度,一半的点将位于该旋转线的一侧,另一半将位于该旋转线的另一侧,或者换句话说,如果我们考虑按直线 Pi-Q 的斜率对点进行排序,我们可以选择第(中位数)点和第(中位数+1)点之间的斜率。这种选择可以通过任何线性时间选择算法在 O(n) 时间内完成,而不需要实际对点进行排序。
现在选择点 Q。
假设 Q 是 (0,b)。
假设 Q 与 P1 (x1,y1) 和 P2 (x2,y2) 共线。
然后我们得到
(y1-b)/x1 = (y2-b)/x2(注意我们平移了这些点,使得 xi > 0)。
求解 b 得出
b = (x1y2 - y1x2)/(x1-x2)
(注意,如果 x1 = x2,则 P1 和 P2 不能与 Y 轴上的点共线)。
考虑|b|。
|b| = |x1y2 - y1x2| / |x1 -x2|
现在让 xmax 为最右边点的 x 坐标,ymax 为最上面点的坐标。
还令 D 为两点之间的最小非零 x 坐标差(这是存在的,因为并非所有 xi 都相同,因为并非所有点都共线)。
然后我们就有了 |b| <= xmax*ymax/D。
因此,选择我们的点 Q (0,b) 使得 |b| > b_0 = xmax*ymax/D
D 可以在 O(nlogn) 时间内找到。
b_0 的大小可能变得非常大,我们可能必须处理精度问题。
当然,更好的选择是随机选择Q!以 1 的概率,您将找到所需的点,从而使预期运行时间为 O(n)。
如果我们能找到一种在 O(n) 时间内选取 Q 的方法(通过找到其他一些标准),那么我们就可以使该算法在 O(n) 时间内运行。
I have assumed the points are distinct, otherwise there might not even be such a line.
If points are distinct, then such a line always exists and is possible to find using a deterministic O(nlogn) time algorithm.
Say the points are P1, P2, ..., P2n. Assume they are not all on the same line. If they were, then we can easily form the splitting line.
First translate the points so that all the co-ordinates (x and y) are positive.
Now suppose we magically had a point Q on the y-axis such that no line formed by those points (i.e. any infinite line Pi-Pj) passes through Q.
Now since Q does not lie within the convex hull of the points, we can easily see that we can order the points by a rotating line passing through Q. For some angle of rotation, half the points will lie on one side and the other half will lie on the other of this rotating line, or, in other words, if we consider the points being sorted by the slope of the line Pi-Q, we could pick a slope between the (median)th and (median+1)th points. This selection can be done in O(n) time by any linear time selection algorithm without any need for actually sorting the points.
Now to pick the point Q.
Say Q was (0,b).
Suppose Q was collinear with P1 (x1,y1) and P2 (x2,y2).
Then we have that
(y1-b)/x1 = (y2-b)/x2 (note we translated the points so that xi > 0).
Solving for b gives
b = (x1y2 - y1x2)/(x1-x2)
(Note, if x1 = x2, then P1 and P2 cannot be collinear with a point on the Y axis).
Consider |b|.
|b| = |x1y2 - y1x2| / |x1 -x2|
Now let the xmax be the x-coordinate of the rightmost point and ymax the co-ordinate of the topmost.
Also let D be the smallest non-zero x-coordinate difference between two points (this exists, as not all xis are same, as not all points are collinear).
Then we have that |b| <= xmax*ymax/D.
Thus, pick our point Q (0,b) to be such that |b| > b_0 = xmax*ymax/D
D can be found in O(nlogn) time.
The magnitude of b_0 can get quite large and we might have to deal with precision issues.
Of course, a better option is to pick Q randomly! With probability 1, you will find the point you need, thus making the expected running time O(n).
If we could find a way to pick Q in O(n) time (by finding some other criterion), then we can make this algorithm run in O(n) time.
在该平面上创建一条任意线。将每个点投影到该线上(也称为每个点),获取该线上距离该点最近的点。
沿线的任一方向对这些点进行排序,并选择该线上的一个点,以使该线上的任一方向上的点数量相同。
获取与通过该点的第一条直线垂直的直线。这条线的两侧各有一半的原始点。
执行此操作时需要避免一些情况。最重要的是,如果所有点本身都在一条线上,则不要选择穿过它的垂直线。事实上,选择该线本身,这样您就不必担心投影点。就其背后的实际数学而言,矢量投影将非常有用。
Create an arbitrary line in that plane. Project each point onto that line a.k.a for each point, get the closest point on that line to that point.
Order those points along the line in either direction, and choose a point on that line such that there is an equal number of points on the line in either direction.
Get the line perpendicular to the first line which passes through that point. This line will have half the original points on either side.
There are some cases to avoid when doing this. Most importantly, if all the point are themselves on a single line, don't choose a perpendicular line which passes through it. In fact, choose that line itself so you don't have to worry about projecting the points. In terms of the actual mathematics behind this, vector projections will be very useful.
这是划分点平面的修改分成相等的两半,这允许存在重叠点的情况(在这种情况下,它会说明答案是否存在)。
与其他提出的解决方案不同,这是
O(N)
。假设存在解决方案,上述方法可能会终止,尽管我没有证据。
尝试上述算法几次,除非您检测到重叠点。如果您检测到大量重叠点,您可能会遇到困难,但有一种效率极低的强力解决方案,需要检查所有可能的角度:
临界角度定义为可能会改变结果的角度(想象一下先前答案的解决方案,旋转整个点集,直到一个或多个点与一个或多个其他点交换位置,穿过分界线。这些点的数量是有限的,并且我认为它们受到点数的限制,因此如果有重叠,您可能会看到
O(N^2)-O(N^2 log(N))
范围内的内容点,用于暴力方法。This is a modification of Dividing a plane of points into two equal halves which allows for the case with overlapping points (in which case, it will say whether or not the answer exists).
This is
O(N)
unlike other proposed solutions.Assuming a solution exists, the above method will probably terminate, though I don't have a proof.
Try the above algorithm a few times unless you detect overlapping points. If you detect a high number of overlapping points, you may be in for a rough ride, but there is a terribly inefficient brute-force solution that involves checking all possible angles:
A critical angle is defined as the angle which could possibly change the result (imagine the solution to a previous answer, rotate the entire set of points until one or more points swaps position with one or more other points, crossing the dividing line. There are only finitely many of these, and I think they are bounded by the number of points, so you're probably looking at something in the range
O(N^2)-O(N^2 log(N))
if you have overlapping points, for a brute-force approach.我猜想一个好方法是对点进行排序/排序/排序(例如从左到右),然后选择一条穿过序列中中间点(或中间点之间)的线。
I'd guess that a good way is to sort/sequence/order the points (e.g. from left to right), and then choose a line which passes through (or between) the middle point[s] in the sequence.
有一些明显的情况是无法解决的。例如,当你有三堆点时。 A 位置有 1 个点,B 位置有 2 个点,C 位置有 5 个点。
如果您期望得到一些不错的分布,则使用 tlayton 算法可能会得到很好的结果。要选择初始线倾斜,您可以确定整个点集的范围,并选择最大对角线的角度。
There are obvious cases where no solution is possible. E.g. when you have three heaps of points. One point at location A, Two points at location B, and five points at location C.
If you expect some decent distribution, you can probably get a good result with tlayton's algorithm. To select the initial line slant, you could determine the extent of the whole point set, and choose the angle of the largest diagonal.
中位数以类似于您想要完成的方式平均划分一组数字,并且可以使用 选择算法 在 O(n) 时间内计算出( Cormen 等人更好,所以你可能想看看那里)。因此,找到 x 值 Mx 的中位数(如果您愿意,也可以找到 y 值 My)并设置 x = Mx (或 y = My),该线将轴向对齐并平均分割您的点。
如果你的问题的性质要求线上的点不超过一个(如果你的集合中有奇数个点,那么至少其中一个会在线上)并且你发现这就是发生的事情(或者你只是想防止这种可能性),将所有点旋转某个随机角度 θ,并计算旋转点的中值。然后旋转由 -θ 计算出的中线,它将均匀地划分点。
对于有限数量的点,随机选择 θ 使得问题再次出现的可能性非常小,但如果确实如此,请使用不同的 θ 再次尝试。
The median equally divides a set of numbers in the manner similar to what you're trying to accomplish, and it can be computed in O(n) time using a selection algorithm (the writeup in Cormen et al is better, so you may want to look there instead). So, find the median of your x values Mx (or your y values My if you prefer) and set x = Mx (or y = My) and that line will be axially aligned and split your points equally.
If the nature of your problem requires that no more than one point lies on the line (if you have an odd number of points in your set, at least one of them will be on the line) and you discover that's what's happened (or you just want to guard against the possibility), rotate all of your points by some random angle, θ, and compute the median of the rotated points. You then rotate the median line you computed by -θ and it will evenly divide points.
The likelihood of randomly choosing θ such that the problem manifests itself again is very small with a finite number of points, but if it does, try again with a different θ.
以下是我解决这个问题的方法(假设 n 是偶数并且没有三个点共线):
1) 选取 Y 值最小的点。我们称其为点P。
2) 将此点作为新的原点,这样所有其他点经过此变换后都将具有正的Y 值。
3)对于每一个其他点(还剩下n-1个点),将其视为在极坐标系下。每个其他点都可以用半径和角度表示。您可以忽略半径而只关注角度。
4) 如何找到一条将点均匀分割的线?求 (n - 1) 个角度的中值。从点 P 到具有该中位角的点的线将均匀地分割这些点。
该算法的时间复杂度为 O(n)。
Here is how I approach this problem (with the assumption that n is even and NO three points are collinear):
1) Pick up the point with smallest Y value. Let's call it point P.
2) Take this point as the new origin point, so that all other points will have positive Y values after this transformation.
3) For every other point (there are n - 1 points remaining), think it under the polar coordinate system. Each other point can be represented with a radius and angle. You could ignore the radius and just focus on the angle.
4) How can you find a line that split the points evenly? Find the median of (n - 1) angles. The line from point P to the point with that median angle will split the points evenly.
Time complexity for this algorithm is O(n).
我不知道这有多大用处,我见过类似的问题......
如果您已经有了方向向量(又名平面尺寸的系数)。
然后,您可以找到该平面内的两个点,并且通过简单地使用中点公式,您可以找到该平面的中点。
然后,使用该平面和中点的系数,您可以使用平面的一般方程找到与两个点距离相等的平面。
那么一条线就构成了用另一个变量来表达一个变量
所以你会找到一条两个平面之间距离相等的线。
有不同的方法可以做到这一点,例如使用平面上的距离方程进行投影,但我相信这会让你的数学变得更加复杂。
I dont know how useful this is I have seen a similar problem...
If you already have the directional vector (aka the coefficients of the dimensions of your plane).
You can then find two points inside that plane, and by simply using the midpoint formula you can find the midpoint of that plane.
Then using the coefficients of that plane and the midpoint you can find a plane that is from equal distance from both points, using the general equation of a plane.
A line then would constitute in expressing one variable in terms of the other
so you would find a line with equal distance between both planes.
There are different methods of doing this such as projection using the distance equation from a plane but I believe that would complicate your math a lot.
添加到 M 的答案中:一种在
O(n log n)
中生成 Q(距离不远)的方法。首先,让 Q 为 y 轴上的任意点,即。
Q = (0,b)
- 一些不错的选择可能是 (0,0) 或 (0, (ymax-ymin) /2)。现在检查是否有两个点 (x1, y1), (x2, y2)与 Q 共线。任意点与 Q 之间的直线为 y = mx + b;由于 b 是常数,这意味着如果两个点的斜率
m
相等,则它们与 Q 共线。因此,确定所有点的斜率 mi 并检查是否有重复项:(使用哈希表进行分摊O(n)
)如果所有的 m 都不同,我们就完成了;我们找到了 Q,M 的算法在
O(n)
步内生成了这条直线。如果两点与 Q 共线,我们会将 Q 向上移动微小量 ε,Qnew = (0, b + ε),并证明 Q< sub>new 不会与其他两个点共线。
下面导出的 ε 的标准是:
首先,我们的 m 看起来像这样:
让我们找到任意两个不同 mi 之间的最小差异,并将其称为 m< sub>minΔ (
O(n log n)
例如,排序然后比较 mi 之间的差异对于所有 i,i+1)如果我们将 b 捏造 ε,则 m 的新方程将变为:
因为 ε > 1。 0 且 xi > 0,所有 m 都会减少,并且所有 m 都会减少最多 ε/xmin。因此,如果
为 true,则先前不相等的两个 mi 将保证保持不相等。
剩下的就是证明如果 m1,old = m2,old,则 m1,new =/= m2、新。由于 mi 都减少了 ε/xi,这相当于显示 x1 =/= x2 。如果它们相等,那么:
与我们所有点都是不同的假设相矛盾。因此,m1, new =/= m2, new,并且没有两点与 Q 共线。
To add to M's answer: a method to generate a Q (that's not so far away) in
O(n log n)
.To begin with, let Q be any point on the y-axis ie.
Q = (0,b)
- some good choices might be (0,0) or (0, (ymax-ymin)/2).Now check if there are two points (x1, y1), (x2, y2) collinear with Q. The line between any point and Q is
y = mx + b
; since b is constant, this means two points are collinear with Q if their slopesm
are equal. So determine the slopes mi for all points and check if there are any duplicates: (amoritizedO(n)
using a hash-table)If all the m's are distinct, we're done; we found Q, and M's algorithm above generates the line in
O(n)
steps.If two points are collinear with Q, we'll move Q up just a tiny amount ε, Qnew = (0, b + ε), and show that Qnew will not be collinear with two other points.
The criterion for ε, derived below, is:
To begin with, our m's look like this:
Let's find the minimum difference between any two distinct mi and call it mminΔ (
O(n log n)
by, for instance, sorting then comparing differences between mi and i+1 for all i)If we fudge b up by ε, the new equation for m becomes:
Since ε > 0 and xi > 0, all m's are reduced, and all are reduced by a maximum of ε/xmin. Thus, if
is true, then two mi which were previously unequal will be guaranteed to remain unequal.
All that's left is to show that if m1,old = m2,old, then m1,new =/= m2,new. Since both mi were reduced by an amount ε/xi, this is equivalent to showing x1 =/= x2. If they were equal, then:
Contradicting our assumption that all points are distinct. Thus, m1, new =/= m2, new, and no two points are collinear with Q.
我从白痴和安德那里得到了这个想法
继续形成确定性O(n)算法。
我还假设这些点是不同的并且
n 是偶数(认为算法可以是
改变使得n不均匀有一个点
也支持分割线上)。
该算法尝试用点之间的垂直线来划分点。仅当中间的点具有相同的 x 值时,此操作才会失败。在这种情况下,算法确定左侧和下部位置必须有多少个具有相同 x 值的点,并相应地旋转线。
我将尝试用一个例子来解释。
假设平面上有 16 个点。
首先我们需要得到 x 值第八大的点
以及 x 值第九大的点。
使用选择算法,这在 O(n) 内是可能的,
正如另一个答案中指出的。
如果这些点的 x 值不同,我们就完成了。
我们在这两点之间创建一条垂直线
将分数平分。
现在的问题是 x 值是否相等。所以我们有 3 组点。
在左侧 (x < xa),在中间 (x = xa)
以及右侧 (x > xa)。
现在的想法是计算左侧的点并
计算从中间到那里需要多少个点,
这样一半的点就在那一边。这里我们可以忽略右边
因为如果我们有一半的点在左边,那么超过一半的点一定在右边。
假设左侧有 3 个点 (c=3),
中间6个,右侧7个
(算法不知道从中间或右侧开始计数,
因为它不需要它,但我们也可以在 O(n)) 中确定它。
我们需要从中间得到8-3=5分才能进入左侧。
我们第一步已经得到的积分现在已经没有用了,
因为它们仅由 x 值决定
并且可以是中间的任意点。
我们想要从中间算起 5 个点,其中 y 值最低的点位于左侧,
右侧 y 值最高的点。
再次使用选择算法,我们得到 y 值第五大的点
以及 y 值第六大的点。
两个点的 x 值都等于 xa,
否则我们不会走到这一步
因为会有一条垂直线。
现在我们可以在这两个点的中间创建点 Q。
这是结果线上的一个点。
需要另一个点,以便左侧或右侧的点不会被划分。
为了得到这个点,我们需要左侧的点,
与 xa 处的垂直线之间的角度 (bh) 最小
以及由该点和 Q 确定的线。
我们还需要右侧的那个点(角度为 ag)。
新点 R 位于具有较小角度的点之间
和垂直线上的一个点
(如果下角位于左侧 Q 上方的点
如果下角位于右侧 Q 下方的点)。
由 Q 和 R 确定的线将中间的点分开
这样两边的点数都是偶数。
它不会在左侧或右侧划分任何点,
因为如果是这样的话,那个点会有一个更低的角度并且
会选择计算 R。
从数学家的角度来看,应该在 O(n) 内运行良好。
对于计算机程序来说,找到案例相当容易
精度成为问题的地方。一个有 4 点的例子是
A(0, 100000000)、B(0, 100000001)、C(0, 0)、D(0.0000001, 0)。
在此示例中,Q 为 (0, 100000000.5),R 为 (0.00000005, 0)。
左边是 B 和 C,右边是 A 和 D。
但有可能A和B都在分界线上,
因为舍入误差。或者也许只是其中之一。
因此,如果该算法符合要求,则属于输入值。
这是基于 x 值的中位数
> O(n)
因为这两点之间的 y 轴平行线是结果
> O(1)
> O(n)
> O(n)
在 Pe 和 Pf 之间
> O(1)
Pc、Q 和 Pi 和
之间的角度 ai
Pd、Q 和 Pi 之间的角度 bi
> O(n)
>; O(n)
>; O(n)
在任意位置创建一个新点 R (xa+1, 0),但 x 值与 xa
否则如果 ag 低于 bh
创建一个新点 R ((xc+xg)/2, (yc+yg )/2) 在 Pc 和 Pg 之间
否则
创建一个新点 R ((xd+xh)/2, (yd+yh )/2) 在 Pd 和 Ph 之间
> O(1)
> O(1)
I picked up the idea from Moron and andand and
continued to form a deterministic O(n) algorithm.
I also assumed that the points are distinct and
n is even (thought the algorithm can be
changed so that uneven n with one point
on the dividing line are also supported).
The algorithm tries to divide the points with a vertical line between them. This only fails if the points in the middle have the same x value. In that case the algorithm determines how many points with the same x value have to be on the left and lower site and and accordingly rotates the line.
I'll try to explain with an example.
Let's asume we have 16 points on a plane.
First we need to get the point with the 8th greatest x-value
and the point with the 9th greatest x-value.
With a selection algorithm this is possible in O(n),
as pointed out in another answer.
If the x-value of that points is different, we are done.
We create a vertical line between that two points and
that splits the points equal.
Problematically now is if the x-values are equal. So we have 3 sets of points.
That on the left side (x < xa), in the middle (x = xa)
and that on the right side (x > xa).
The idea now is to count the points on the left side and
calculate how many points from the middle needs to go there,
so that half of the points are on that side. We can ignore the right side here
because if we have half of the points on the left side, the over half must be on the right side.
So let's asume we have we have 3 points (c=3) on the left side,
6 in the middle and 7 on the right side
(the algorithm doesn't know the count from the middle or right side,
because it doesn't need it, but we could also determine it in O(n)).
We need 8-3=5 points from the middle to go on the left side.
The points we already got in the first step are useless now,
because they are only determined by the x-value
and can be any of the points in the middle.
We want the 5 points from the middle with the lowest y-value on the left side and
the point with the highest y-value on the right side.
Again using the selection algorithm, we get the point with the 5th greatest y-value
and the point with the 6th greatest y-value.
Both points will have the x-value equal to xa,
else we wouldn't get to this step,
because there would be a vertical line.
Now we can create the point Q in the middle of that two points.
Thats one point from the resulting line.
Another point is needed, so that no points from the left or right side are divided.
To get that point we need the point from the left side,
that has the lowest angle (bh) between the the vertical line at xa
and the line determined by that point and Q.
We also need that point from the right side (with angle ag).
The new point R is between the point with the lower angle
and a point on the vertical line
(if the lower angle is on the left side a point above Q
and if the lower angle is on the right side a point below Q).
The line determined by Q and R divides the points in the middle
so that there are a even number of points on both sides.
It doesn't divide any points on the left or right side,
because if it would that point would have a lower angle and
would have been choosen to calculate R.
From the view of a mathematican that should work well in O(n).
For computer programs it is fairly easy to find a case
where precision becomes a problem. An example with 4 points would be
A(0, 100000000), B(0, 100000001), C(0, 0), D(0.0000001, 0).
In this example Q would be (0, 100000000.5) and R (0.00000005, 0).
Which gives B and C on the left side and A and D on the right side.
But it is possible that A and B are both on the dividing line,
because of rounding errors. Or maybe only one of them.
So it belongs to the input values if this algorithm suits to the requirements.
which are the medians based on the x values
> O(n)
because a y-axis parallel line between that two points is the result
> O(1)
> O(n)
> O(n)
> O(n)
> O(n)
> O(n)
> O(n)
between Pe and Pf
> O(1)
the angle ai between Pc, Q and Pi and
the angle bi between Pd, Q and Pi
> O(n)
> O(n)
> O(n)
create a new point R (xa+1, 0) anywhere but with a different x value than xa
else if ag is lower than bh
create a new point R ((xc+xg)/2, (yc+yg)/2) between Pc and Pg
else
create a new point R ((xd+xh)/2, (yd+yh)/2) between Pd and Ph
> O(1)
> O(1)