ArcGIS Desktopを使用してポリゴン内にポリゴンをパッキングしますか?


25

ブールラスターがあります。

ラスターの灰色の領域で、特定のサイズのポリゴンを連続した範囲内に収めたいと思います。

基本的に、不規則なポリゴンがあります。可能な限り、不規則なポリゴンの範囲内で既知のポリゴンを「適合」させたいと思います。

多角形の方向は重要ではなく、正方形でもかまいません。グラフィカルにフィットするようにしたいのですが、ポリゴンに数字を付けるだけで(フィットする#)、同様に機能します。

ArcGIS Desktop 10を使用しています。


8
これは非常に難しい問題です。たとえば、できるだけ多くの円を正方形に収めるには多くの作業が必要です。図のように元のポリゴンが複雑な場合、いくつかの強力な最適化手順が必要です。この問題に対して私が見つけた最良の方法はシミュレーテッドアニーリングですが、ArcGISでは利用できず、スクリプトを作成するには非常に巧妙なスクリプトが必要になります(ArcGISは遅すぎます)。可能な限り多くの回数ではなく、より小さなポリゴンを十分な回数だけフィッティングするなど、要件を少し緩和できますか?
whuber

1
@whuber投稿を編集してくれてありがとう。ええ、十分な回数が機能します。または、与えられた角度方向でどうでしょう。例 私はその方向に持っている可能性があるので、私は彼らに90度回転させていた上記の画像では、私はあなたが1もっと...合うことができる、何回ものポリゴンに合わせている
サド

1
はい、でも落とし穴がたくさんあります。いくつかは初歩的です。たとえば、ESRIが作成および公開したテキスト「Getting to know ArcView GIS」(バージョン3の場合)には、サッカーフィールドを表す長方形をポリゴン内にインタラクティブに配置する演習が含まれていました。問題は、作者がデータの投影に失敗し、地理座標の使用におけるエラーが結果に影響を与えるほど大きいため、演習の答えが間違っていたことです。答えはGISで良さそうに見えましたが、その分野を構築しようとした人がいたとしても、十分なスペースがないことがわかりました:-)。
whuber

6
@whuber彼らは「球場」の数字で十分だと思ったようです。
カーククイケンドール

2
不規則な多角形内の不規則な多角形の一般的なケースでは、これは計算上困難な問題です:最適なソリューションを見つけることはすべての場合において妥当な目標ではなく、技術的な観点からはNP完全である可能性があります:どのケースが事前に決定できないか。問題を大幅に制約する場合、一部の反復ランダムフィッティングアルゴリズムにより、かなり高い数値が得られる可能性があります。これが課題であれば、彼らは正しい答えを探しているのではなく、創造的なアプローチを探しているという感じです。
MappingTomorrow

回答:


22

この問題に取り組むには多くの方法があります。 データのラスター形式は、ラスターベースのアプローチを示唆しています。これらのアプローチを検討する際、2進整数線形プログラムとしての問題の定式化は有望に見えます。これは、多くのGISサイト選択分析の精神に非常に合致しており、それらに容易に適応できるためです。

この定式化では、塗りつぶしポリゴンのすべての可能な位置と方向を列挙します。これを「タイル」と呼びます。各タイルに関連付けられているのは、その「良さ」の尺度です。目的は、全体の良さが可能な限り大きい非重複タイルのコレクションを見つけることです。ここでは、各タイルの長所をカバーする領域とすることができます。(よりデータが豊富で洗練された決定環境では、各タイルに含まれるセルのプロパティ、おそらく可視性に関連するプロパティ、他のものへの近接性などの組み合わせとして、良さを計算している可能性があります。)

この問題に対する制約は、ソリューション内の2つのタイルが重ならないことです。

これは、多角形のセル(「領域」)1、2、...、Mを列挙することにより、効率的に計算できるように、もう少し抽象的にフレーム化できます。タイルの配置は、0と1のインジケーターベクトルでエンコードすることができ、1をタイルで覆われたセルと他の場所の0に対応させます。このエンコーディングでは、タイルのコレクションに必要なすべての情報は、それらのインジケーターベクトル(通常はコンポーネントごと)を合計することで見つけることができます:合計は、少なくとも1つのタイルがセルをカバーし、合計が大きくなるゼロ以外の値になります2つ以上のタイルが重なる場所はどこでもありません。(合計は、重複の量を効果的にカウントします。)

もう1つの小さな抽象化:考えられるタイル配置のセット自体を列挙できます(1、2、...、Nなど)。タイル配置のセット自体の選択は、配置するタイルを指定するインジケーターベクトルに対応します。

ここにアイデアを修正するための小さなイラストがあります。計算の実行に使用されるMathematicaコードが付随しているため、プログラミングの難しさ(またはその欠如)が明らかになります。

まず、タイル化する領域を示します。

region =  {{0, 0, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}};

図1:地域

セルを左から右へ、上から順に番号付けすると、領域のインジケーターベクトルには16個のエントリがあります。

Flatten[region]

{0、0、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1}

90度の倍数のすべての回転とともに、次のタイルを使用してみましょう。

tileSet = {{{1, 1}, {1, 0}}};

図2:タイル

回転(および反射)を生成するコード:

apply[s_List, alpha] := Reverse /@ s;
apply[s_List, beta] := Transpose[s];
apply[s_List, g_List] := Fold[apply, s, g];
group = FoldList[Append, {}, Riffle[ConstantArray[alpha, 4], beta]];
tiles = Union[Flatten[Outer[apply[#1, #2] &, tileSet, group, 1], 1]];

(このやや不透明な計算は、 /math//a/159159のます。これは、タイルの可能なすべての回転と反射を生成し、重複する結果を削除することを示しています。)

ここに示すようにタイルを配置するとします。

図3:タイルの配置

セル3、6、および7は、この配置でカバーされています。それは指標ベクトルによって指定されます

{0、0、1、0、0、1、1、0、0、0、0、0、0、0、0、0、0}

このタイルを1列右にシフトすると、そのインジケーターベクトルは代わりに

{0、0、0、1、0、0、1、1、0、0、0、0、0、0、0、0、0}

両方にタイルを配置しようとする組み合わせこれらのの位置に同時に、これらのインジケータの合計によって決まります。

{0、0、1、1、0、1、2、1、0、0、0、0、0、0、0、0、0}

7番目の位置の2は、1つのセルでこれらのオーバーラップを示しています(下から2行目、左から3列目)。重複したくないので、、有効なソリューションのベクトルの合計に1を超えるエントリが含まれないようにする必要があります。

この問題では、タイルの方向と位置の29の組み合わせが可能です。(これは徹底的な検索を含む簡単なコーディングで発見されました。)29の可能性すべてを、ベクトルとしてインジケーターを描画することで表現できます。(行の代わりに列を使用するのが一般的です。)結果の配列の画像を次に示します。これは16行(長方形の各セルに1行)と29列になります。

makeAllTiles[tile_, {n_Integer, m_Integer}] := 
  With[{ m0 = Length[tile], n0 = Length[First[tile]]},
   Flatten[
    Table[ArrayPad[tile, {{i, m - m0 - i}, {j, n - n0 - j}}],  {i, 0, m - m0}, {j, 0, n - n0}], 1]];
allTiles = Flatten[ParallelMap[makeAllTiles[#, ImageDimensions[regionImage]] & , tiles], 1];
allTiles = Parallelize[
   Select[allTiles, (regionVector . Flatten[#]) >= (Plus @@ (Flatten[#])) &]];
options = Transpose[Flatten /@ allTiles];

図4:オプション配列

(前の2つのインジケーターベクトルは、左の最初の2列として表示されます。)鋭い目をした読者は、並列処理のいくつかの機会に気付いたかもしれません。これらの計算には数秒かかることがあります。

前述のすべては、マトリックス表記を使用してコンパクトに言い換えることができます。

  • Fは、MN列のこのオプションの配列です。

  • Xは、長さNの一連のタイル配置のインジケータです。

  • bは1のNベクトルです。

  • Rは地域の指標です。それはMの -ベクトル。

FXXでカバーされるセルのインジケーターであり、Rの積はこれらの値を合計するため、考えられるソリューションXに関連付けられた合計「良さ」はRFXに等しくなります。(ソリューションが地域内の特定の領域を優先または回避することを希望する場合、Rに重みを付けることができます。) これは最大化されます。RF)と書くことができるからです。Xは、それがある線形の関数X:これは重要です。(以下のコードでは、変数にRFが含まれています。)c

制約があること

  1. Xのすべての要素は非負でなければなりません。

  2. Xのすべての要素は1(bの対応するエントリ)未満でなければなりません。

  3. Xのすべての要素は整数でなければなりません。

制約(1)と(2)はこれを線形プログラムにしますが、3番目の要件はこれを整数線形プログラムに変えます。

まさにこの形式で表現された整数線形プログラムを解くための多くのパッケージが存在しますMおよびNの値を数十または数十万にまで処理できます。実際のアプリケーションでは、おそらくこれで十分です。


最初の例として、Mathematica 8のLinearProgrammingコマンドを使用して前の例の解を計算しました。(これがします最小限に抑える。線形目的関数を最小化が容易に目的関数を否定することで最大化になっている。)それは0.011秒で(タイルとその位置のリストとして)ソリューションを返しました:

b = ConstantArray[-1, Length[options]];
c = -Flatten[region].options;
lu = ConstantArray[{0, 1}, Length[First[options]]];
x = LinearProgramming[c, -options, b, lu, Integers, Tolerance -> 0.05];
If[! ListQ[x] || Max[options.x] > 1, x = {}];
solution = allTiles[[Select[x Range[Length[x]], # > 0 &]]];

図5:ソリューション

灰色のセルは領域にまったくありません。白血球はこの溶液で覆われていませんでした。

これと同じくらい良い他の多くのタイルを(手で)解決できますが、より良いタイルを見つけることはできません。これは、このアプローチの潜在的な制限です。複数のソリューションがある場合でも、1つの最適なソリューションを提供します。(いくつかの回避策があります:Xの列を並べ替える場合と、問題は変わりませんが、ソフトウェアは結果として異なるソリューションを選択することがよくあります。ただし、この動作は予測できません。)

2番目の図として、より現実的にするために、問題の地域を考えてみましょう。画像をインポートしてリサンプリングすることで、69 x 81のグリッドで表現しました。

図6:地域

領域は、このグリッドの2156個のセルで構成されています。

物事を面白くし、線形計画法の一般性を説明するために、この領域を可能な限り2種類の長方形でカバーしてみましょう。

図7:タイル

1つは17 x 9(153セル)で、もう1つは15 x 11(165セル)です。2番目のほうが大きいので、2番目のほうを使用することをお勧めしますが、最初のほうがより細く、狭い場所に収まります。どれどれ!

このプログラムには、N = 5589のタイル配置が含まれます。かなり大きい!6.3秒の計算の後、Mathematicaはこの10タイルのソリューションを思い付きました。

図8:ソリューション

いくつかのたるみがあるため(たとえば、左下のタイルを最大で4列左にシフトできます)、明らかにこれとは少し異なる他のソリューションがいくつかあります。


1
このソリューションの以前のバージョン(それほど良くはありません)は、Mathematicaサイトのmathematica.stackexchange.com/a/6888にあります。わずかなタイルで領域を完全にカバーする問題を解決するために、公式の小さなバリエーションを使用できることも注目に値するかもしれません(もちろん、いくつかの重複を許可します):これは、「穴あきパッチング」を解決します問題。
whuber

1
スペースを確保するため、この回答では潜在的に役立つ改善点については説明していません。たとえば、可能なすべてのタイル位置を(インジケーターベクトルとして)見つけた後、それらをすべて加算して、どのセルが実際にいくつかのタイルで覆われるかを見つけることができます。このようなセルのセットは、2番目の例では2つの独立した接続コンポーネントに分割されます。これは、2つのコンポーネントで問題を個別に解決できることを意味し、サイズ(および計算時間)を大幅に削減します。このような初期の単純化は、現実の問題に取り組むために重要になる傾向があります。
whuber

多大な努力と答え。クリスの答えも役に立ちました。助けてくれてありがとう!動作し、再び正しい方向に動いた。
サッド

うわー!私は同様の問題に興味があり、この投稿は新しい視点を与えてくれました。ありがとうございました。Rが大きい場合(140x140≈20000など)、計算コストを削減する方法はありますか?この問題に関連する論文を知っていますか?私の検索キーワードが正しい方法で私を導きません(今まで)。
nimcap

@nimcapこれは重要なクラスの問題であるため、多くの研究が続けられています。検索するキーワードは、「混合整数線形プログラム」で始まり、検索結果に基づいてそこから分岐します。
whuber

5

多角形のパッキングのための遺伝的アルゴリズムについてへのリンクは最小間隔で制約エリア内に最大数のポイントを配置するアルゴリズムを探すでの同様の質問への私の答えで提供されていますか?、役に立つかもしれません。メソッドは、長方形だけでなく、任意のコンテナ形状で機能するように一般化できるようです。


この論文にはいくつかの素晴らしいアイデアがありますが(+1)、そのアルゴリズムはすべて、基本的な方法で、長方形領域内のポリゴンのパッキングに焦点を当てています。これは、多角形が正方形の辺に平行に指定されたコーナーに向かってスライドする一連の手順を表す離散データ構造(一連の多角形とその向き)を持つパッキングを表すためです。このような単純な離散エンコーディングは、より複雑な領域では効果が低いようです。おそらく、グリッド内の領域の最初の単純化が役立つでしょう。
whuber

2

あなたが言及した高度に制約されたサブセット(ポットホール内の正方形/三角形のタイル)について、上記の明示的な最適化を仮定すると、この疑似コードは、高解像度で問題をブルートフォースする可能性を単に通して、おおよその答えに到達するはずです。長方形のタイルや非常に不規則なコンテナーなど、個々のタイルの回転がゲインを見ることができる状況では、正しく機能しません。これは100万回の反復であり、必要に応じてさらに試行できます。

長さLの辺を持つ正方形を仮定します

少なくともコンテナの範囲の寸法に加えて、各方向に少なくとも1Lの正方形の市松模様を作成します。

N = 0

DX = 0

DY = 0

DR = 0

チェッカーボードの位置を元の重心にリセット

(R = 1:100)

(Y = 1:100)

(X = 1:100)

M =コンテナ内の正方形の数を完全に数える

If(M> N)

DR = R

DY = Y

DX = X

N = M

チェッカーボードをL / 100だけ東に移動する

チェッカーボードの東をリセット

チェッカーボードをL / 100だけ北に移動する

チェッカーボードの北をリセット

チェッカーボードをその重心を中心にCW 3.6度回転させます

DY = DY * L

DX = DX * L

チェッカーボードを元の位置と回転にリセット

印刷DR& "、"&DX& "、および"&DY& "は最終的な変換/回転マトリックスです

DRによるチェッカーボードの回転

DX、DYによるチェッカーボードの翻訳

完全にコンテナ内にある正方形を選択します

正方形をエクスポート


1つの長いエッジの中央に沿ってセルが欠落している2 x 5の領域でこの手順を試してみると、2 x 2の正方形を1つしか配置できないことがわかります。ただし、このような2つの正方形は簡単に収まります。問題は、それらが通常の「チェッカーボード」パターンの一部ではないことです。この難しさは、この問題をかなり難しくしているものの1つです。
whuber

1
うん。コンテナの形状が不規則で、それぞれが数個のセルのオーダーで複数の不連続な規則的なパターンをサポートできる場合、これは最適とはほど遠い結果になります。そのようなものを可能性スペースに追加すると、処理時間が非常に急速に増加し、ターゲットとする特定のケースに対してある程度の計画が必要になります。
MappingTomorrow
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.