1

グリッド内のランダムなポイントのコレクションが与えられた場合、それらがすべて他のポイントの固定範囲内にあることを効率的にチェックするにはどうすればよいでしょうか。つまり、グリッド内の任意のポイントに移動できる任意のポイントを 1 つ選択します。

さらに明確にするために: 1000 x 1000 のグリッドに 100 個のポイントがランダムに配置されている場合、あるポイントが隣のポイントから 100 単位以内にあり、あるポイントから別のポイントまで歩いてすべてのポイントにアクセスできることをどのように証明できますか?

私はいくつかのコードを書いていて、興味深い問題を思いつきました: 非常にまれに (これまでに一度だけ)、残りのポイントからの最大範囲を超えるポイントの島が作成されます。この問題を解決する必要がありますが、ブルート フォースでは解決できないようです。

これは Java で書かれていますが、私は疑似コードまたは C++ のどちらかが得意です。

4

7 に答える 7

2

@ joel.neelyの構築アプローチが好きですが、より均一な密度を確保したい場合は、これが機能する可能性が高くなります(ただし、全体的に均一な密度ではなく、より多くのクラスターが生成される可能性があります)。

  1. 有効なグリッド内の一様分布からx、yを選択して、初期点P_0をランダムに配置します
  2. i = 1:N-1の場合
    1. ランダムj=0からi-1まで均一に分布しP_jているものを選択し、以前に配置された点を特定します
    2. 以下のサブステップ4で 有効なものが選択されるまで、以下を繰り返すことにより、 P_idistance(P_i、 )<100であるランダムな点を選択します。P_jP_i
      1. それぞれ-100から+100まで均一に分布する(dx、dy)を選択します
      2. dx ^ 2 + dy ^ 2> 100 ^ 2の場合、距離が大きすぎる(21.5%の確率で失敗する)場合は、前の手順に戻ります。
      3. 候補coords(P_i)= coords(P_j)+(dx、dy)を計算します。
      4. P_i全体的に有効なグリッド内にある場合に有効です。
于 2008-12-30T14:03:06.540 に答える
1

新規および改善 ;-)

もう少し考えさせられたコメントをくれたGuillaumeとJasonSに感謝します。これにより、統計が大幅に改善された2番目の提案が作成されました。

ギヨームは、私が投稿した以前の戦略では均一な密度が失われると述べました。もちろん、彼は正しいです。なぜなら、それは本質的に元のポイントを周回する傾向がある「酔っぱらいの散歩」だからです。ただし、ポイントを均一にランダムに配置すると、「パス」要件に失敗する可能性が高くなります(すべてのポイントは、100を超えるステップのないパスで接続できます)。その状態のテストには費用がかかります。1つが通過するまで純粋にランダムな解を生成することはさらにそうです。

Jason Sはバリエーションを提供しましたが、多数のシミュレーションにわたる統計的検定により、彼のバリエーションは、最初の提案と同じようにクラスター化されたパターンを生成すると結論付けました(座標値の平均と標準偏差の調査に基づく)。

以下の改訂されたアルゴリズムは、統計が純粋に(均一な)ランダム配置の統計と非常に似ているが、パス要件を満たすように構築によって保証されているポイントセットを生成します。残念ながら、口頭で説明するよりも視覚化する方が少し簡単です。事実上、ポイントは漠然と一貫した方向(NE、SE、SW、NW)にランダムによろめき、「壁に跳ね返る」ときにのみ方向を変える必要があります。

大まかな概要は次のとおりです。

  1. ランダムに始点を選び、水平移動を右に、垂直移動を下に設定します。

  2. 残りのポイント数(たとえば、元の仕様では99)について繰り返します。

    2.1。距離が50から100の間のdxとdyをランダムに選択します。(私の試行実装では、ユークリッド距離(二乗和の平方根)を想定しましたが、「タキシカブ」距離(絶対値の合計)はさらに簡単です。コード化する。)

    2.2。水平方向と垂直方向の移動に基づいて、dxとdyを前のポイントに適用します(右/下->加算、左/上->減算)。

    2.3。いずれかの座標が範囲外(0未満または少なくとも1000)になった場合は、違反した境界の周囲の座標を反映し、その移動を反対方向に置き換えます。これは、4つのケース(2つの座標x 2つの境界)を意味します。

    2.3.1. if x < 0, then x = -x and reverse LEFT/RIGHT horizontal travel.
    2.3.2. if 1000 <= x, then x = 1999 - x and reverse LEFT/RIGHT horizontal travel.
    2.3.3. if y < 0, then y = -y and reverse UP/DOWN vertical travel.
    2.3.4. if 1000 <= y, then y = 1999 - y and reverse UP/DOWN vertical travel.
    

ステップ2.3での反射は、新しいポイントを前のポイントから100単位以内に残すことが保証されているため、パス要件が維持されることに注意してください。ただし、水平方向と垂直方向の移動の制約により、ポイントの生成は空間全体でランダムに「スイープ」され、元の純粋な「酔っぱらいの歩行」アルゴリズムよりも全体的な分散が大きくなります。

于 2009-01-02T13:56:29.660 に答える
1

既存の点のセットを評価する限り、これは一種のユークリッド最小全域木問題のように見えます。ウィキペディアのページには、これはドロネー三角形分割のサブグラフであると記載されています。したがって、ドロネー三角形分割(前のリファレンスまたはグーグルの「計算幾何学」を参照)を計算してから、最小全域木を計算し、すべてのエッジの長さが100未満であることを確認するだけで十分だと思います。

参考文献を読むと、これはO(N log N)であるように見えます。おそらくもっと速い方法がありますが、これで十分です。

より単純な(ただしおそらく効率が低い)アルゴリズムは、次のようになります。

  1. 与えられた:ポイントはインデックス0からN-1までの配列にあります。
  2. ポイントをx座標順に並べ替えます。これは、効率的な並べ替えのためにO(N log N)です。
  3. i=0を初期化します。
  4. インクリメントi。i == Nの場合、成功して停止します。(すべてのポイントは、半径Rの別のポイントから到達できます)
  5. j=iを初期化します。
  6. デクリメントj。
  7. j<0またはの場合P[i].x - P[j].x > R失敗して停止します。(ギャップがあり、半径Rですべてのポイントに到達することはできません)
  8. それ以外の場合、P[i].xとP[j].xが互いにR内にある場合はここに到達します。ポイントP[j]がP[i]に十分に近いかどうかを確認します(P[i].x-P[j].x)^2 + (P[i].y-P[j].y)^2 <。R^2`の場合、ポイントP [i]は半径R内の前のポイントの1つから到達可能であり、手順4に戻ります。
  9. 試してください:ステップ6に戻ります。

編集:これはO(N log N)であるはずの何かに変更される可能性がありますが、よくわかりません:

  1. 与えられた:ポイントはインデックス0からN-1までの配列にあります。
  2. ポイントをx座標順に並べ替えます。これは、効率的な並べ替えのためにO(N log N)です。
  3. YLISTをセット{P[0]}に初期化して、y座標順にポイントのソートされたセットYLISTを維持します。x座標を左から右にスイープし、ポイントを1つずつYLISTに追加し、新しく追加されたポイントから離れすぎているx座標を持つポイントを削除します。
  4. i = 0、j=0を初期化します。
  5. この時点でループ不変条件は常に真です。k<=iであるすべての点P[k]は、半径Rで互いに到達できるネットワークを形成します。YLIST内のすべての点は、P[i]の間にあるx座標を持ちます。 xRおよびP[i].x
  6. インクリメントi。i == Nの場合、成功して停止します。
  7. P [i] .xP [j] .x <= Rの場合、手順10に進みます(i == jの場合、これは自動的に真になります)
  8. 半径Rの点P[i]から点P[j]に到達できません。YLISTからP[j]を削除します(これはO(log N)です)。
  9. jをインクリメントし、ステップ6に進みます。
  10. この時点で、j<iP[i].xRとP[i].xの間のx座標を持つすべての点P[j]はセットYLISTにあります。
  11. P [i]をYLIST(これはO(log N))に追加し、YLIST [k] ==P[i]であるYLIST内のインデックスkを覚えておいてください。
  12. ポイントYLIST[k-1]およびYLIST[k+ 1](存在する場合、P [i]はYLIST内の唯一の要素であるか、極端な端にある可能性があります)は、YLIST内でP[i]に最も近いポイントです。 。
  13. ポイントYLIST[k-1]が存在し、P [i]の半径R内にある場合、P [i]は、前のポイントの少なくとも1つから半径Rで到達可能です。手順5に進みます。
  14. ポイントYLIST[k+ 1]が存在し、P [i]の半径R内にある場合、P [i]は、前のポイントの少なくとも1つから半径Rで到達可能です。手順5に進みます。
  15. P [i]は、前のどのポイントからも到達できません。失敗して停止します。
于 2008-12-30T14:37:15.847 に答える
1

私があなたの問題を正しく理解している場合、サイトのセットが与えられた場合、各サイトの最近傍 (L1 距離、つまりグリッド距離) が値 K 未満の距離にあるかどうかをテストする必要があります。

これは、一連のポイントの Delaunay 三角形分割を計算することにより、ユークリッド距離について簡単に取得できます。サイトの最近傍は、Delaunay 三角形分割におけるその近傍の 1 つです。興味深いことに、L1 距離はユークリッド距離よりも大きくなっています (係数 sqrt(2) 内)。

あなたの状態をテストする方法は次のとおりです。

  1. サイトの Delaunay 三角形分割を計算する
  2. 各サイト s に対して、三角形分割の s から幅優先探索を開始して、s から K 未満のユークリッド距離にあるすべての頂点を検出します (ドロネー三角形分割には、s から K 未満の距離にある頂点のセットが与えられたサイトは三角測量で接続されています)
  3. 各サイト s について、s から K 未満の距離にあるこれらの頂点の中で、それらのいずれかが s から K 未満の L1 距離にあるかどうかを確認します。そうでない場合、プロパティは満たされていません。

このアルゴリズムは、いくつかの方法で改善できます。

  1. もちろん、ステップ 2 の幅優先探索は、K 未満の L1 距離にあるサイトが見つかるとすぐに停止する必要があります。
  2. s の有効な近隣の検索中に、サイト s' が s から K 未満の L1 距離にあることがわかった場合、s' の有効な近隣を探す必要はありません。s は明らかにそれらの 1 つです。
  3. 完全な幅優先探索は必要ありません: s に付随するすべての三角形を調べた後、三角形分割の s の近傍のいずれも有効な近傍 (つまり、K 未満の L1 距離にあるサイト) でない場合、(v 1、 ...,v n ) 隣人。水平軸および垂直軸と交差するエッジは最大で 4 つ (v i、 v i+1 ) あります。検索は、これら 4 つ (またはそれ以下) のエッジを通じてのみ続行する必要があります。[これはL1球の形状から従う]
于 2009-01-03T23:38:40.327 に答える
1

簡単な考え: グリッドを 50x50 のパッチに分割し、最初のポイントを配置すると、それらがどのパッチに属しているかも記録されます。ここで、新しいポイントが他のポイントから 100 ピクセル以内にあるかどうかを確認したい場合は、パッチとその周囲の 8 ピクセルをチェックして、ポイント数が一致するかどうかを確認するだけです。

たとえば、100 個のランダム ポイントがあり、各パッチに含まれるポイントの数が含まれていることがわかっている場合、単純に合計して、実際に 100 であるかどうかを確認できます。これは、すべてのポイントに到達可能であることを意味します。

他にも方法はあると思います、難しいです。

編集: 50x50 パッチの左上点から右下点までの距離は sqrt(50^2 + 50^2) = 70 ポイントなので、おそらく小さいパッチ サイズを選択する必要があります。多分 35 か 36 で十分でしょう (50^2 = sqrt(x^2 + x^2) => x=35.355...)。

于 2008-12-30T13:12:30.387 に答える
1

ポイント セットの凸包を見つけてから、回転キャリパーメソッドを使用します。凸包の最も離れた 2 つのポイントは、セット内の最も離れた 2 つのポイントです。他のすべてのポイントは凸包に含まれているため、2 つの極値ポイントよりも近いことが保証されます。

于 2008-12-30T13:41:22.450 に答える
0

構造によって望ましい状態を強制します。乱数を描画するだけですべてのポイントを配置する代わりに、次のように座標を制限します。

  1. 初期点をランダムに配置します。

  2. 残りのポイント数 (例: 99) について繰り返します。

    2.1. 前の点からある範囲 (たとえば 90) 内の x 座標をランダムに選択します。

    2.2. 前の点から 100 単位以内になる y 座標の有効な範囲を計算します。

    2.3. その範囲内の y 座標をランダムに選択します。

  3. 原点を完全に隠したい場合は、ポイントを座標ペアで並べ替えます。

これは、純粋なランダム性に比べて多くのオーバーヘッドを必要としませんが、各ポイントが少なくとも 1 つの他のポイントの 100 単位以内にあることを保証します (実際には、最初と最後の点を除いて、各ポイントは他の2 つのポイントの 100 単位以内になります)。

上記のバリエーションとして、ステップ 2 で、既に生成されたポイントをランダムに選択、前のポイントの代わりに参照として使用します。

于 2008-12-30T13:44:49.307 に答える