「労働者が自分の仕事をうまくやりたいなら、まず自分の道具を研ぎ澄まさなければなりません。」 - 孔子、「論語。陸霊公」
表紙 > プログラミング > 分割統治を使用して最も近い点のペアを見つける

分割統治を使用して最も近い点のペアを見つける

2024 年 7 月 30 日に公開
ブラウズ:259

このセクションでは、分割統治法を使用して最も近い点のペアを見つけるための効率的なアルゴリズムを紹介します。一連の点が与えられた場合、最近接ペア問題は、互いに最も近い 2 つの点を見つけることです。以下の図に示すように、最近接ペア アニメーションでは最も近い 2 点を結ぶ線が描画されます。

Image description

ケーススタディ: 最も近いペアの検索では、最も近い点のペアを見つけるための総当たりアルゴリズムを紹介しました。アルゴリズムは、すべての点のペア間の距離を計算し、最小距離を持つ点を見つけます。明らかに、アルゴリズムには O(n^2) 時間がかかります。より効率的なアルゴリズムを設計できますか?

この問題を解決するには、分割統治と呼ばれるアプローチを使用します。このアプローチでは、問題をサブ問題に分割し、サブ問題を解決し、サブ問題の解を組み合わせて問題全体の解を取得します。動的プログラミングのアプローチとは異なり、分割統治アプローチの部分問題は重複しません。部分問題は元の問題に似ていますが、サイズが小さいため、再帰を適用して問題を解決できます。実際、再帰的問題に対するすべての解決策は分割統治アプローチに従っています。

以下の手順では、分割統治アプローチを使用して最近接ペア問題を解決する方法を説明します。

  • ステップ 1: 点を x 座標の昇順に並べ替えます。同じ X 座標を持つ点については、Y 座標に基づいて並べ替えます。これにより、ソートされたポイントのリスト S が生成されます。
  • ステップ 2: ソートされたリストの中点を使用して、S を同じサイズの 2 つのサブセット S1 と S2 に分割します。中間点を S1 に置きます。 S1 と S2 で最も近いペアを再帰的に見つけます。 d1 と d2 が、それぞれ 2 つのサブセット内の最も近いペアの距離を表すものとします。
  • ステップ 3: S1 の点と S2 の点の間で最も近いペアを見つけ、それらの距離を d3 として示します。最も近いペアは、距離が min(d1, d2, d3).
  • のペアです。

選択ソートには O(n^2) 時間がかかります。ステップ 1 は O(n log n) 時間で実行できます。ステップ 3 は O(n) 時間で実行できます。 d = min(d1, d2) とします。最も近いペアの距離が d より大きくならないことはすでにわかっています。 S1 の点と S2 の点が S で最も近いペアを形成するには、次の図に示すように、左側の点が stripL 内にあり、右側の点が stripR 内にある必要があります ( a).

stripL 内の点 p については、以下の (b) に示すように、d X 2d 長方形内の右側の点のみを考慮する必要があります。長方形の外側の任意の右点は、p と最も近いペアを形成できません。 S2 の最近接ペアの距離は d 以上であるため、最大で 6 つ存在する可能性があります 長方形内の点。したがって、
stripL の各点について、stripR 内の最大 6 つの点を考慮する必要があります。

stripL の各点 p について、stripR の対応する d X 2d 長方形領域内の点をどのように見つけますか? stripL および stripR 内の点が y 座標の昇順に並べ替えられている場合、これを効率的に行うことができます。 pointsOrderedOnY を、y 座標の昇順に並べ替えた点のリストとします。 pointsOrderedOnYはアルゴリズムで事前に取得できます。 stripLstripR は、以下のコードに示すように、ステップ 3 の pointsOrderedOnY から取得できます。

Image description

pointsOrderedOnY の各ポイント p に対して

if (p が S1 にあり、mid.x – p.x pをstripLに追加;
else if (p が S2 にあり、p.x - Mid.x pをstripR;
に追加

stripL および stripR の点を、次のように {p0, p1, ... , pk} および {q0, q1, ... , qt} とします。上図(c)。 stripL 内の点と stripR 内の点の間で最も近いペアは、以下のコードで説明されているアルゴリズムを使用して見つけることができます。

d = min(d1, d2); r = 0; // r は、stripR 内の点のインデックスです for (stripL の各点 p) { // p.y - d より下のstripR内のポイントをスキップします while (r d = min(d1, d2); r = 0; // r is the index of a point in stripR for (each point p in stripL) { // Skip the points in stripR below p.y - d while (r

stripL 内の点は、p0、p1、...、pk の順に考慮されます。 stripL 内の点 p の場合、p.y – d (行 5 ~ 6) より下にある stripR 内の点をスキップします。ポイントがスキップされると、そのポイントは考慮されなくなります。 while ループ (9 ~ 17 行目) は、(p, q[r1]) が最も近いペアである可能性があるかどうかをチェックします。 stripR 内の 2 点間の距離は d より小さくすることはできないため、そのような q[r1] ペアは最大 6 つあります。したがって、ステップ 3 で最も近いペアを見つけるための複雑さは O(n). です。

上記の手順のステップ 1 は、ポイントを事前に並べ替えるために 1 回だけ実行されることに注意してください。すべての点が事前に並べ替えられていると仮定します。 T(n) がこのアルゴリズムの時間計算量を表すものとします。したがって、

Image description

したがって、最も近い点のペアは O(n log n) 時間で見つかります。

リリースステートメント この記事は次の場所に転載されています: https://dev.to/paulike/finding-the-closest-pair-of-points-using-divide-and-conquer-2deb?1 侵害がある場合は、study_golang@163 までご連絡ください。 .comを削除してください
最新のチュートリアル もっと>

免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。

Copyright© 2022 湘ICP备2022001581号-3