7

長方形の山があり、そのうちのいくつかは交差し、いくつかは孤立しているとします。例)

    +-------------------- + +-------- +
    | | | | | | | |
    | | | | | | | |
    | | あ | | | シー |
    | | +---------------- + | | |
    | | | | | | | | +---------+-------- +
    | | | | | | | | | | | |
    +--------|----- + B | | | D |
              | | | | | | | |
              | | | | +------------------ +
              +---------------- +

    +-------------------- + +-------- +
    | | | | | | | |
    | | え | | | X |
    +--------------------+ | | |
    | | | | +-------- +
    | | | | +------------ +
    | | | | | | | |
    | | ふ | | | | |
    | | | | | | よ |
    | | | | | | | |
    +---------------------+ +------------ +

Rect A、B は互いに交差し、C、D は 1 つの同じ点を持ち、E、F は 2 つの同じ点を持ち、X、Y は孤立しています。

2 つの質問があります。

  1. これらの長方形を、A、B、C、D、E、F、X、Y を正確にカバーする長方形に分割する方法も、次のような最小数になります。
    +--------+----- + +-------- +
    | | | | | | | | | |
    | | | | | | | | | |
    | | | | | | | | | |
    | | | | +--------- + | | |
    | | | | | | | | +---------+-------- +
    | | | | | | | | | | | |
    +---------+ | | | | | | |
              | | | | | | | | | |
              | | | | | | +---------------------+
              +--------+----------+

    +-------------------- + +-------- +
    | | | | | | | |
    | | | | | | | |
    | | | | | | | |
    | | | | +---------+
    | | | | +------------ +
    | | | | | | | |
    | | | | | | | |
    | | | | | | | |
    | | | | | | | |
    +--------------------+ +-------------+

  1. 交差する長方形を大きな長方形で覆う方法は? このような:
    + ---------------------------+ +-------------------+
    | | | | | | | |
    | | | | | | | |
    | | | | | | | |
    | | | | | | | |
    | | | | | | | |
    | | | | | | | |
    | | | | | | | |
    | | | | | | | |
    | | | | +---------------------+
    + ---------------------------+


    +---------------------+ +---------+
    | | | | | | | |
    | | | | | | | |
    | | | | | | | |
    | | | | +---------+
    | | | | +------------ +
    | | | | | | | |
    | | | | | | | |
    | | | | | | | |
    | | | | | | | |
    +--------------------+ +-------------+

Q1については、まったくわかりません.... Q2については、C++でいくつかのコードを書きましたが、効率が悪いです。もっと良い方法/アルゴリズムがあると思います。

 bool intersectRect(const Rect& rect1, const Rect& rect2) {
    /* if rect1 and rect2 intersect return true
       else return false
    */
}
Rect mergeIntersectRects(const set<Rect>& rects) {
    // suppose rects are all intersected. This function only return a smallest Rect that cover all rects.
}
set<Rect> mergeRectToRects(const set<Rect>& rectset, const Rect& rect) {
    set<Rect> _intersect_rects;
    set<Rect> _unintersect_rects;
    for(set<Rect>::const_iterator it = rectset.begin();
        it != rectset.end();
        ++it) {
        if(intersectRect(*it, rect))
            _intersect_rects.insert(*it);
        else 
            _unintersect_rects.insert(*it);
    }
    if(!_intersect_rects.empty()) {
        _intersect_rects.insert(rect);
        return mergeRectToRects(_unintersect_rects,
                                mergeIntersectRects(_intersect_rects));
    }
    else {
        _unintersect_rects.insert(rect);
        return _unintersect_rects;
    }
}
4

4 に答える 4

3

まず、あなたの長方形はすべて軸が揃っていると仮定しています。

Q1 の場合、1 つのオプションは、長方形の内部にあるスイープ ラインに沿ったライン セグメントのリストを維持しながら平面をスイープすることです。スイープ中に各長方形の頂点を検出すると、現在の内部セグメントが変更されているかどうかを確認できます。変更されている場合は、必要に応じて長方形を開始または終了します。

たとえば、スイープ ラインが左から右に移動するとします。

                                                                     現時点の
                                                                     インテリア
      | |                                                                  
    +-|------------- + +-------- + *
    | | | | | | | | | | | |
    | | | | | | | | | | | |
    | | | | あ | | | シー | | |
    | | | | +---------------- + | | | | |
    | | | | | | | | | | +---------+-------- + |
    | | | | | | | | | | | | | | | |
    +-|------|----- + B | | | D | *
      | | | | | | | | | |
      | | | | | | +------------------ +
      | | +---------------- +
      | |
    +-|---------------- + +-------- + *
    | | | | | | | | | | | |
    | | | | え | | | X | | |
    | | |-----------------+ | | | | |
    | | | | | | +-------- + |
    | | | | | | +------------ + |
    | | | | | | | | | | | |
    | | | | ふ | | | | | | |
    | | | | | | | | よ | | |
    | | | | | | | | | | | |
    +-|-----------------+ +------------ + *
      | |

スイープ ラインが上図の位置にある場合、2 つの内部セグメントがあります。つまり、A の内側と (EUF) の内側です。スイープ ラインが B の左端に到達すると、左側にある A の部分の長方形を出力します。次に、セグメント リストの A の内部を (AUB) の内部に置き換えます。

                                                                     現時点の
                                                                     インテリア
                | |                                                        
    +---------+-|--- + +-------- + *
    | | | | | | | | | | | | | |
    | | | | | | | | | | | | | |
    | | | | | | | | | | シー | | |
    | | | | | -------------- + | | | | |
    | | | | | | | | | | +---------+-------- + |
    | | | | | | | | | | | | | | | |
    +---------+ |--- + B | | | D | | |
              | | | | | | | | | | | |
              | | | | | | +------------------ + |
              +-|------ + *
                | |
    +---------|------ + +-------- + *
    | | | | | | | | | | | |
    | | | | | | | | X | | |
    | | |------+ | | | | |
    | | | | | | +-------- + |
    | | | | | | +------------ + |
    | | | | | | | | | | | |
    | | | | | | | | | | | |
    | | | | | | | | よ | | |
    | | | | | | | | | | | |
    +----------|-------+ +------------ + *
                | |

Q2 の場合、セグメントが最初にリストに追加された x 座標 (「A の左側」など) と最小および最大の y 座標を追跡することにより、同じスイープ中に答えを計算できます。存続期間中 (たとえば、B の下部から A の上部まで) にまたがります。セグメントが最終的にリストから削除されると (例: 「B の右側」)、これら 4 つの座標を使用して長方形を出力します。

前処理ステップで四角形の頂点を辞書式に並べ替えると、O(n * log n) になります。既知の内部範囲でバイナリ検索を実行できるため、それらの処理は O(log n) になります。合計実行時間は O(n * log n) である必要があります。

于 2012-07-26T12:34:45.607 に答える
1

Q1: これを直線多角形の分割といいます。ロブのコメントからの回答には非常に良い説明があります。回答に記載されている紙役に立ちました。

Q2: 交差しない領域の 2 つのカバーが交差することを望まないと思います。3 つの長方形のカバーと同様に、L を生成する 2 つの長方形と、L の長方形の交差部分をカバーしますが、L の長方形はカバーしません。

そのような場合は、カバーを段階的に作成することができます。これがそのための簡単なアルゴリズムです。

covers = {A}
for each rectangle R
  while there is a cover that intersects R, say C
    remove C from covers and set R = cover of R and C
  add R to covers

このコードは、標準形式では効率的ではありません。構造に優れた構造でcovers、効率的に行うことができます。

于 2012-07-26T15:05:35.990 に答える
0

アルゴリズムは次のとおりです: http://goo.gl/aWDJo

凸包アルゴリズムの検索について読むことができます: http://ralph.cs.cf.ac.uk/papers/Geometry/boxing.pdf

于 2012-07-26T14:10:34.667 に答える
0

@Damon によって提案された方法を使用しますが、四分木やグリッドなどの空間インデックス構造を使用して、隣接する四角形の検索を高速化します。分割する交差する四角形を検索するために最初に入力四角形のセットを構築し、次にマージする隣接する四角形を検索するために最初のステップで取得した分割四角形のセットを構築します。これにより、素朴なアプローチに比べてかなりスピードアップするはずです。

于 2012-07-26T11:58:04.490 に答える