web-dev-qa-db-ja.com

点の平面を2つの等しい半分に分割する

N個の点がある2次元平面が与えられます。片側にn/2点、反対側にn/2点があるように、平面を分割する直線の方程式を生成する必要があります。

32
mousey

私はポイントが明確であると仮定しました、さもなければそのような線さえないかもしれません。

ポイントが異なる場合、そのような線は常に存在し、決定論的 O(nlogn)時間アルゴリズムを使用して見つけることができます。

ポイントがP1、P2、...、P2nであるとします。それらがすべて同じ行にあるわけではないと仮定します。もしそうなら、私たちは簡単に分割線を形成することができます。

まず、すべての座標(xとy)が正になるように点を平行移動します。

ここで、y軸上に点Qがあり、それらの点によって形成される線(つまり、無限の線Pi-Pj)がQを通過しないと仮定します。

これで、Qは点の凸包内にないため、Qを通過する回転線によって点を順序付けることができることが簡単にわかります。ある回転角度では、点の半分が片側にあり、残りの半分が残ります。はこの回転線のもう一方にあります。つまり、点が線Pi-Qの傾きで並べ替えられていると考えると、(中央)番目と(中央+1)の間の傾きを選択できます。 thポイント。この選択は、実際にポイントをソートする必要なしに、任意の線形時間選択アルゴリズムによって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を2点間の最小の非ゼロ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)時間。

26
Aryabhatta
  1. その平面に任意の線を作成します。各ポイントをそのラインに投影します。つまり、各ポイントについて、そのライン上でそのポイントに最も近いポイントを取得します。

  2. いずれかの方向の線に沿ってそれらの点を並べ替え、いずれかの方向の線上に同じ数の点が存在するようにその線上の点を選択します。

  3. その点を通過する最初の線に垂直な線を取得します。この線は、両側に元のポイントの半分があります。

これを行うときに避けるべきいくつかのケースがあります。最も重要なことは、すべてのポイント自体が1本の線上にある場合は、それを通過する垂直線を選択しないでください。実際、ポイントの投影について心配する必要がないように、その線自体を選択してください。この背後にある実際の数学の観点から、 ベクトル射影 は非常に便利です。

10
tlayton

これは 点の平面を2つの等しい半分に分割する の修正であり、点が重なっている場合を考慮に入れています(この場合、答えが存在するかどうかが示されます)。

_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).
_

これは、他の提案されたソリューションとは異なり、O(N)です。

解決策が存在すると仮定すると、証明はありませんが、上記の方法はおそらく終了します。

重複するポイントを検出しない限り、上記のアルゴリズムを数回試してください。重複するポイントが多数検出された場合は、ラフな乗り心地になる可能性がありますが、考えられるすべての角度をチェックすることを含む非常に非効率的なブルートフォースソリューションがあります。

_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.
_

臨界角は、結果を変える可能性のある角度として定義されます(前の答えの解決策を想像し、1つ以上のポイントが1つ以上の他のポイントと位置を入れ替えて、分割線と交差するまで、ポイントのセット全体を回転させます。これらの数は限られており、ポイントの数によって制限されていると思います。したがって、ブルートフォースアプローチの場合、ポイントが重複している場合は、おそらくO(N^2)-O(N^2 log(N))の範囲内の何かを見ているでしょう。

4
ninjagecko

中央値 は、達成しようとしているのと同様の方法で数値のセットを均等に分割し、O(n)時間で計算できます。 選択アルゴリズム (Cormen et alの記述の方が優れているため、代わりにそこを確認することをお勧めします)。したがって、x値の中央値Mを見つけます。バツ (またはあなたのy値My 必要に応じて)、x = Mに設定しますバツ (またはy = My)そしてその線は軸方向に整列され、ポイントを均等に分割します。

問題の性質上、ライン上に1つのポイントしか存在しないことが必要な場合(セットに奇数のポイントがある場合、少なくとも1つのポイントがライン上にある)、それが起こっていることを発見します(または可能性を防ぎたいだけです)、すべての点をランダムな角度θだけ回転させ、回転した点の中央値を計算します。次に、計算した中央線を-θで回転すると、ポイントが均等に分割されます。

問題が再び現れるようにランダムにθを選択する可能性は非常に小さく、点の数は有限ですが、そうであれば、別のθで再試行してください。

1
andand

良い方法は、ポイントを並べ替え/順序付け/順序付けして(たとえば、左から右に)、シーケンスの中間点を通過する(またはその間を通過する)線を選択することだと思います。

1
ChrisW

解決策が不可能な明らかなケースがあります。例えば。ポイントのヒープが3つある場合。場所Aに1ポイント、場所Bに2ポイント、場所Cに5ポイント。

適切な分布が期待できる場合は、tlaytonのアルゴリズムでおそらく良い結果を得ることができます。最初の線の傾斜を選択するには、ポイントセット全体の範囲を決定し、最大の対角線の角度を選択します。

1
relet

私はMoronand andandからアイデアを拾い上げ、決定論的なO(n)アルゴリズムを形成し続けました。

また、点が明確でnが偶数であると仮定しました(分割線上に1つの点がある不均一なnもサポートされるようにアルゴリズムを変更できると考えました)。

アルゴリズムは、ポイントを垂直線で分割しようとします。これは、中央のポイントのx値が同じである場合にのみ失敗します。その場合、アルゴリズムは、同じx値を持つポイントが左側と下部のサイトにいくつある必要があるかを決定し、それに応じてラインを回転させます。

例を挙げて説明しようと思います。平面上に16個の点があると仮定しましょう。最初に、8番目に大きいx値を持つポイントと9番目に大きいx値を持つポイントを取得する必要があります。別の回答で指摘されているように、選択アルゴリズムでは、これはO(n)で可能です。そのポイントのx値が異なる場合は、これで完了です。その2つのポイントの間に垂直線を作成し、ポイントを均等に分割します。

問題なのは、x値が等しいかどうかです。つまり、3セットのポイントがあります。左側のそれ(x <xa)、真ん中(x = xa)と右側のそれ(x> xa)。ここでのアイデアは、左側のポイントを数え、中央からそこに行く必要があるポイントの数を計算して、ポイントの半分がその側にあるようにすることです。左側にポイントの半分がある場合、半分以上が右側にある必要があるため、ここでは右側を無視できます。

したがって、左側に3ポイント(c = 3)、中央に6ポイント、右側に7ポイントがあると仮定します(アルゴリズムは中央または右側からのカウントを認識しないため、認識しません)必要ですが、O(n)で決定することもできます。左側に行くには、真ん中から8-3 = 5ポイント必要です。最初のステップですでに取得したポイントは、x値によってのみ決定され、中央の任意のポイントになる可能性があるため、現在は役に立ちません。

中央から左側にy値が最も低い5つのポイントが必要であり、右側にy値が最も高いポイントが必要です。再び選択アルゴリズムを使用して、5番目に大きいy値を持つポイントと6番目に大きいy値を持つポイントを取得します。両方のポイントのx値はxに等しくなりますa、そうでなければ、垂直線があるため、このステップに到達しません。

これで、その2つのポイントの中間にポイントQを作成できます。これは、結果の線から1ポイントです。左側または右側からのポイントが分割されないように、別のポイントが必要です。その点を取得するには、左側からの角度が最も小さい点が必要です(bh)xの垂直線の間a そして、その点と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の両方が分割線上にある可能性があります。または多分それらの1つだけ。したがって、このアルゴリズムが要件に適合する場合は、入力値に属します。

  1. その2つのポイントを取得しますPa(バツa、ya)およびPb(バツb、yb
    x値に基づく中央値> O(n)
  2. xの場合a != xb ここで停止できます
    その2点間のy軸平行線が結果であるため> O(1)
  3. x値がxに等しいすべてのポイントを取得しますa> O(n)
  4. x値がx未満のポイントをカウントしますa as c > O(n)
  5. 最低点Pを取得しますc 3のポイントのy値に基づきます。> O(n)
  6. 最大のポイントPを取得しますd 3のポイントのy値に基づきます。> O(n)
  7. (n/2-c)番目に大きい点Pを取得しますe 3のポイントのy値に基づきます。> O(n)
  8. また、次に大きいポイントPを取得しますf 3のポイントのy値に基づきます。> O(n)
  9. 新しい点Q(xa、(ye+ yf)/ 2)P間e およびPf> O(1)
  10. すべての点についてP 計算する
    角度a Pの間c、QおよびP そして
    角度b Pの間d、QおよびP> O(n)
  11. ポイントPを取得しますg 最も低い角度でg (とともにg> 0°およびag<180°)> O(n)
  12. ポイントPを取得しますh 最小角度bh (b付きh> 0°およびbh<180°)> O(n)
  13. pがない場合g またはPh (すべてのポイントのx値は同じです)
    新しい点R(xa+ 1、0)xとは異なるx値を持つ以外の場所a
    それ以外の場合g bよりも低いh
    新しい点Rを作成します((xc+ xg)/ 2、(yc+ yg)/ 2)P間c およびPg
    そうしないと
    新しい点Rを作成します((xd+ xh)/ 2、(yd+ yh)/ 2)P間d およびPh> O(1)
  14. qとRによって決定される線は、点を分割します> O(1)
0
rudi-moore

私はこれがどれほど有用であるかわかりません私は同様の問題を見ました...

方向ベクトル(別名、平面の寸法の係数)がすでにある場合。

次に、その平面内の2つの点を見つけることができ、中点の式を使用するだけで、その平面の中点を見つけることができます。

次に、その平面と中点の係数を使用して、平面の一般方程式を使用して、両方の点から等距離にある平面を見つけることができます。

線は、一方の変数をもう一方の変数で表すことで構成されるため、両方の平面間の距離が等しい線が見つかります。

これを行うには、平面からの距離方程式を使用した投影など、さまざまな方法がありますが、それでは計算が非常に複雑になると思います。

0
user342219

Mの答えに追加するには:O(n log n)でQ(それほど遠くない)を生成するメソッド。

まず、Qをy軸上のany点とします。 Q = (0,b)-いくつかの良い選択は(0,0)または(0、(y最大-y)/ 2)。

次に、2つのポイントがあるかどうかを確認します(x1、y1)、 (バツ2、y2)Qと同一線上にあります。任意の点とQの間の線は_y = mx + b_です。 bは一定であるため、勾配mが等しい場合、これは2つの点がQと同一線上にあることを意味します。したがって、勾配mを決定します すべてのポイントについて、重複があるかどうかを確認します:(ハッシュテーブルを使用してO(n)を修正)

すべてのmが異なる場合は、完了です。 Qが見つかり、上記のMのアルゴリズムはO(n)ステップで行を生成します。
2つのポイントがQと同一線上にある場合、Qをtinyの量ε、Qだけ上に移動します新着 =(0、b +ε)、そしてQが新着 他の2つのポイントと同一線上にはありません。

以下で導出されるεの基準は次のとおりです。

ε<mminΔ*バツ

まず、mは次のようになります。

 m = y/バツ -b/x

任意の2つの間の最小差を見つけましょうdistinct m そしてそれをmと呼びますminΔO(n log n)たとえば、並べ替えてからm間の差を比較する そして i + 1 すべてのi)

Bをεでファッジすると、mの新しい方程式は次のようになります。

 m私、新しい = y/バツ -b/x -ε/ x
 = m私、古い -ε/ x

Ε> 0かつxなので > 0の場合、すべてのmが減少し、すべてが最大ε/ xだけ減少します。。したがって、

ε/ x <mminΔ、すなわち。
ε<mminΔ*バツ

真の場合、2 m 以前は不平等だったものは、不平等のままであることが保証されます。


残っているのは、m1、古い = m2、古い、次にm1、新しい =/= m2、新しい。両方のm以来 ε/ xの量だけ減少しました、これはxを表示するのと同じです1 =/= x2。それら等しい場合、次のようになります。

 y1 = m1、古いバツ1 + b = m2、古いバツ2 + b = y2

すべての点が異なるという私たちの仮定と矛盾します。したがって、m1、新しい =/= m2、新しい、および2つの点がQと同一線上にあることはありません。

これが私がこの問題に取り組む方法です(nが偶数で、3つの点が同一線上にないという仮定で):

1)Y値が最小のポイントをピックアップします。それを点Pと呼びましょう。

2)このポイントを新しい原点として、この変換後に他のすべてのポイントが正のY値を持つようにします。

3)1つおきの点(残りn-1点)については、極座標系で考えてください。他の各ポイントは、半径と角度で表すことができます。半径を無視して、角度だけに焦点を合わせることができます。

4)ポイントを均等に分割する線をどのように見つけることができますか? (n-1)の角度の中央値を見つけます。点Pからその中線角度の点までの線は、点を均等に分割します。

このアルゴリズムの時間計算量はO(n)です。

0
nybon