Đóng gói đa giác trong đa giác bằng ArcGIS Desktop?


25

Tôi có một raster Boolean.

Trong các vùng màu xám của raster, tôi muốn đặt một đa giác kích thước nhất định trong một phạm vi liền kề.

Về cơ bản, tôi có một đa giác không đều, và tôi muốn "khớp" một đa giác đã biết trong phạm vi của đa giác không đều càng nhiều lần càng tốt.

Hướng của đa giác không quan trọng, và nó có thể là một hình vuông. Tôi muốn nó phù hợp với đồ họa, nhưng nếu nó chỉ gắn một số vào đa giác (# phù hợp) cũng sẽ hoạt động.

Tôi đang sử dụng ArcGIS Desktop 10.


8
Đây là một vấn đề rất khó khăn. Chẳng hạn, phải mất rất nhiều công việc để ghép càng nhiều vòng tròn vào một hình vuông càng tốt. Khi đa giác ban đầu phức tạp - như trong hình minh họa - bạn cần một số quy trình tối ưu hóa mạnh mẽ. Phương pháp tốt nhất mà tôi đã tìm thấy cho vấn đề này là mô phỏng ủ, nhưng nó sẽ không có sẵn trong ArcGIS và nó sẽ mất kịch bản cực kỳ xảo quyệt để kịch bản nó (ArcGIS quá chậm). Bạn có thể thư giãn có lẽ yêu cầu của bạn một chút, chẳng hạn như lắp đa giác nhỏ hơn đủ số lần, chứ không phải như nhiều lần càng tốt?
whuber

1
@whuber Cảm ơn bạn đã chỉnh sửa bài viết của tôi. Vâng, đủ số lần sẽ làm việc. Hoặc, làm thế nào về một định hướng góc nhất định. ví dụ trong hình trên, tôi đã điều chỉnh đa giác nhiều lần như tôi có thể có theo hướng đó, tôi đã xoay chúng 90 độ bạn có thể phù hợp hơn một lần nữa ...
Thad

1
Vâng, nhưng nó cũng đầy những cạm bẫy. Một số là tiểu học. Ví dụ, văn bản do ESRI ủy quyền và được xuất bản, "Tìm hiểu về ArcView GIS" (cho phiên bản 3) bao gồm một bài tập trong đó một hình chữ nhật đại diện cho một sân bóng đá được đặt tương tác trong một đa giác. Vấn đề là, câu trả lời của bài tập đã sai vì tác giả không thể chiếu dữ liệu và các lỗi trong việc sử dụng tọa độ địa lý đủ lớn để ảnh hưởng đến kết quả. Câu trả lời có vẻ tốt trong GIS, nhưng nếu bất cứ ai đã cố gắng xây dựng lĩnh vực đó, họ sẽ thấy rằng không đủ chỗ cho nó :-).
whuber

6
@whuber Tôi đoán họ nghĩ rằng một con số "công viên bóng" là đủ.
Kirk Kuykendall

2
Trong trường hợp chung của đa giác không đều trong đa giác không đều, đây là một vấn đề khó tính toán: Tìm một giải pháp tối ưu không phải là mục tiêu chính đáng trong mọi trường hợp và có khả năng NP-hoàn thành từ góc độ kỹ thuật: Những trường hợp nào không thể xác định trước. Nếu bạn hạn chế vấn đề một cách đáng kể, một số thuật toán phù hợp ngẫu nhiên lặp lại có khả năng cung cấp cho bạn số lượng cao hợp lý . Tôi cảm thấy nếu đây là một bài tập là họ không tìm câu trả lời đúng , họ đang tìm cách tiếp cận sáng tạo.
MappingTomorrow

Câu trả lời:


22

Có nhiều cách để tiếp cận vấn đề này. Định dạng raster của dữ liệu cho thấy cách tiếp cận dựa trên raster; khi xem xét các cách tiếp cận đó, một công thức của vấn đề như một chương trình tuyến tính số nguyên nhị phân có vẻ đầy triển vọng, bởi vì nó rất giống với nhiều phân tích lựa chọn trang web của GIS và có thể dễ dàng thích nghi với chúng.

Trong công thức này, chúng tôi liệt kê tất cả các vị trí và hướng có thể có của đa giác điền, mà tôi sẽ gọi là "gạch". Liên kết với mỗi gạch là một thước đo "lòng tốt" của nó. Mục tiêu là tìm ra một bộ sưu tập gạch không chồng chéo mà tổng độ tốt của nó càng lớn càng tốt. Ở đây, chúng ta có thể lấy sự tốt đẹp của mỗi viên gạch để trở thành khu vực mà nó bao phủ. .

Các ràng buộc về vấn đề này chỉ đơn giản là không có hai ô trong một giải pháp có thể trùng nhau.

Điều này có thể được đóng khung một chút trừu tượng hơn, theo một cách có lợi cho tính toán hiệu quả, bằng cách liệt kê các tế bào trong đa giác được điền (các "khu vực") 1, 2, ..., M . Bất kỳ vị trí xếp gạch nào cũng có thể được mã hóa bằng một vectơ chỉ thị các số 0 và số 0, để cho các vị trí tương ứng với các ô được bao phủ bởi các ô và số không ở nơi khác. Trong bảng mã này, tất cả thông tin cần thiết về một tập hợp các ô có thể được tìm thấy bằng cách tính tổng các vectơ chỉ báo của chúng (thành phần theo thành phần, như thường lệ): tổng sẽ không chính xác trong đó ít nhất một ô bao phủ một ô và tổng sẽ lớn hơn hơn một nơi hai hoặc nhiều gạch chồng lên nhau. (Tổng số có hiệu quả đếm số lượng chồng lấp.)

Một trừu tượng ít hơn: tập hợp vị trí ngói có thể tự nó có thể được liệt kê, nói 1, 2, ..., N . Việc lựa chọn bất kỳ tập hợp các vị trí ô nào cũng tương ứng với một vectơ chỉ báo nơi các vị trí chỉ định các ô được đặt.

Đây là một minh họa nhỏ để sửa chữa các ý tưởng . Nó được đi kèm với Mathematica mã được sử dụng để thực hiện các phép tính, vì vậy mà những khó khăn lập trình (hoặc thiếu đó) có thể hiển nhiên.

Đầu tiên, chúng tôi mô tả một khu vực được lát gạch:

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

Hình 1: khu vực

Nếu chúng ta đánh số các ô của nó từ trái sang phải, bắt đầu từ trên cùng, vectơ chỉ báo cho vùng có 16 mục:

Flatten[region]

{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}

Hãy sử dụng ô sau đây, cùng với tất cả các phép quay theo bội số 90 độ:

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

Hình 2: gạch

Mã để tạo các phép quay (và phản xạ):

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]];

(Tính toán hơi đục này được giải thích trong bài trả lời tại /math//a/159159 , trong đó cho thấy nó chỉ đơn giản là tạo ra tất cả các phép quay tốt và phản xạ của một gạch và sau đó loại bỏ bất kỳ kết quả trùng lặp.)

Giả sử chúng ta đã đặt gạch như hiển thị ở đây:

Hình 3: vị trí gạch

Các ô 3, 6 và 7 được bao phủ trong vị trí này. Điều đó được chỉ định bởi vectơ chỉ báo

{0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}

Nếu chúng ta dịch chuyển một cột này sang bên phải, vectơ chỉ báo đó sẽ thay thế

{0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0}

Sự kết hợp của việc cố gắng đặt gạch tại cả hai vị trí này đồng thời được xác định bởi tổng của các chỉ số này,

{0, 0, 1, 1, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0}

Số 2 ở vị trí thứ bảy cho thấy các phần trùng nhau này trong một ô (hàng thứ hai trở xuống, cột thứ ba từ bên trái). Vì chúng tôi không muốn trùng lặp, chúng tôi sẽ yêu cầu tổng các vectơ trong bất kỳ giải pháp hợp lệ nào phải không có mục nào vượt quá 1.

Nó chỉ ra rằng đối với vấn đề này, 29 kết hợp định hướng và vị trí có thể cho gạch. (Điều này đã được tìm thấy với một chút mã hóa đơn giản liên quan đến tìm kiếm toàn diện.) Chúng ta có thể mô tả tất cả 29 khả năng bằng cách vẽ các chỉ số của chúng dưới dạng vectơ cột . (Sử dụng các cột thay vì các hàng là thông thường.) Đây là hình ảnh của mảng kết quả, sẽ có 16 hàng (một cho mỗi ô có thể có trong hình chữ nhật) và 29 cột:

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];

Hình 4: mảng tùy chọn

(Hai vectơ chỉ báo trước xuất hiện dưới dạng hai cột đầu tiên bên trái.) Trình đọc mắt sắc nét có thể nhận thấy một số cơ hội để xử lý song song: các tính toán này có thể mất vài giây.

Tất cả những điều đã nói ở trên có thể được trình bày lại một cách gọn gàng bằng cách sử dụng ký hiệu ma trận:

  • F là mảng tùy chọn này, với M hàng và N cột.

  • X là chỉ số của một tập hợp vị trí gạch, chiều dài N .

  • b là một N -vector của những người.

  • R là chỉ số cho khu vực; nó là một M -vector.

Tổng "độ tốt" liên quan đến bất kỳ giải pháp X có thể nào , bằng RFX , vì FX là chỉ số của các ô được bao phủ bởi X và sản phẩm có R tính tổng các giá trị này. (Chúng tôi có thể cân R nếu chúng tôi muốn các giải pháp ủng hộ hoặc tránh các khu vực nhất định trong khu vực.) Điều này sẽ được tối đa hóa. Bởi vì chúng ta có thể viết nó dưới dạng ( RF ). X , nó là một hàm tuyến tính của X : điều này rất quan trọng. (Trong đoạn mã dưới đây, biến cchứa RF .)

Những hạn chế là

  1. Tất cả các yếu tố của X phải không âm;

  2. Tất cả các phần tử của X phải nhỏ hơn 1 (là mục tương ứng trong b );

  3. Tất cả các yếu tố của X phải là tích phân.

Các ràng buộc (1) và (2) biến điều này thành một chương trình tuyến tính , trong khi yêu cầu thứ ba biến nó thành một chương trình tuyến tính nguyên .

Tồn tại nhiều gói để giải các chương trình tuyến tính nguyên được thể hiện dưới dạng chính xác này. Chúng có khả năng xử lý các giá trị của MN thành hàng chục hoặc thậm chí hàng trăm ngàn. Điều đó có lẽ đủ tốt cho một số ứng dụng trong thế giới thực.


Như minh họa đầu tiên của chúng tôi, tôi đã tính toán một giải pháp cho ví dụ trước bằng cách sử dụng lệnh của Mathicala 8 LinearProgramming. (Điều này sẽ giảm thiểu chức năng mục tiêu tuyến tính. Tối thiểu hóa dễ dàng chuyển sang tối đa hóa bằng cách phủ định chức năng mục tiêu.) Nó trả về một giải pháp (dưới dạng danh sách các ô và vị trí của chúng) trong 0,011 giây:

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 &]]];

Hình 5: giải pháp

Các tế bào màu xám không ở trong khu vực; các tế bào trắng không được bao phủ bởi giải pháp này.

Bạn có thể làm việc (bằng tay) nhiều cách khác cũng tốt như cái này - nhưng bạn không thể tìm thấy cái nào tốt hơn. Đó là một hạn chế tiềm năng của phương pháp này: nó mang đến cho bạn một giải pháp tốt nhất, ngay cả khi có nhiều hơn một. (Có một số cách giải quyết: nếu chúng tôi sắp xếp lại các cột của X , vấn đề vẫn không thay đổi, nhưng phần mềm thường chọn một giải pháp khác do kết quả. Tuy nhiên, hành vi này là không thể đoán trước.)

Như một minh họa thứ hai , để thực tế hơn, hãy xem xét khu vực trong câu hỏi. Bằng cách nhập hình ảnh và lấy mẫu lại, tôi biểu thị nó bằng lưới 69 x 81:

Hình 6: Vùng

Vùng bao gồm 2156 ô của lưới này.

Để làm cho mọi thứ thú vị và để minh họa tính tổng quát của thiết lập lập trình tuyến tính, chúng ta hãy cố gắng bao phủ càng nhiều vùng này càng tốt với hai loại hình chữ nhật:

Hình 7: gạch

Một là 17 x 9 (153 ô) và hai là 15 x 11 (165 ô). Chúng tôi có thể thích sử dụng cái thứ hai, vì nó lớn hơn, nhưng cái thứ nhất thì gầy hơn và có thể vừa với những nơi chật hơn. Hãy xem nào!

Chương trình hiện có N = 5589 vị trí xếp có thể. Nó khá lớn! Sau 6,3 giây tính toán, Mathicala đã đưa ra giải pháp mười ô này:

Hình 8: giải pháp

Do một số độ chùng ( .eg, chúng ta có thể dịch chuyển ô bên trái phía dưới lên đến bốn cột sang bên trái), rõ ràng có một số giải pháp khác khác một chút so với giải pháp này.


1
Một phiên bản trước đó của giải pháp này (nhưng không hoàn toàn tốt) xuất hiện trên trang Mathicala tại mathicala.stackexchange.com/a/6888 . Cũng có thể đáng lưu ý rằng một biến thể nhỏ của công thức có thể được sử dụng để giải quyết vấn đề bao phủ hoàn toàn khu vực với càng ít gạch càng tốt (dĩ nhiên là cho phép một số chồng chéo): điều này sẽ giải quyết "vá ổ gà" vấn đề.
whuber

1
Về lợi ích của không gian, câu trả lời này không mô tả một số cải tiến có thể hữu ích. Chẳng hạn, sau khi tìm thấy tất cả các vị trí ô có thể (dưới dạng vectơ chỉ báo), bạn có thể thêm tất cả chúng để tìm ô nào thực sự có thể được bao phủ bởi một số ô. Tập hợp các ô như vậy chia thành hai thành phần được kết nối riêng biệt trong ví dụ thứ hai. Điều này có nghĩa là vấn đề có thể được giải quyết một cách độc lập trong hai thành phần, làm giảm đáng kể kích thước của nó (và do đó thời gian tính toán). Đơn giản hóa ban đầu như vậy có xu hướng quan trọng để giải quyết các vấn đề trong thế giới thực.
whuber

Nỗ lực và trả lời tuyệt vời. Câu trả lời của Chris cũng hữu ích. Cảm ơn tất cả mọi người đã giúp đỡ! Hoạt động, và khiến tôi đi đúng hướng một lần nữa.
Thad

Ồ Tôi đã quan tâm đến một vấn đề tương tự và bài đăng này đã cho tôi quan điểm mới. Cảm ơn bạn. Điều gì xảy ra nếu R lớn hơn (ví dụ 140x14020000), có cách nào để giảm chi phí tính toán không? Bạn có biết bất kỳ giấy tờ liên quan đến vấn đề này? Từ khóa tìm kiếm của tôi không dẫn tôi đi đúng hướng (cho đến bây giờ).
nimcap

@nimcap Đây là một lớp vấn đề quan trọng, rất nhiều nghiên cứu được thực hiện. Từ khóa để tìm kiếm sẽ bắt đầu với "chương trình tuyến tính số nguyên hỗn hợp" và phân nhánh từ đó dựa trên những gì bạn tìm thấy.
whuber

5

Liên kết đến Thuật toán di truyền để đóng gói đa giác , được cung cấp trong câu trả lời của tôi cho một câu hỏi tương tự tại thuật toán Tìm kiếm để đặt số điểm tối đa trong vùng giới hạn ở khoảng cách tối thiểu? , có thể hữu ích. Có vẻ như phương pháp này có thể được khái quát hóa để làm việc với các hình dạng thùng chứa tùy ý (và không chỉ hình chữ nhật).


Bài báo đó có một số ý tưởng hay (+1), nhưng tất cả các thuật toán của nó tập trung, theo một cách cơ bản, về việc đóng gói các đa giác trong các khu vực hình chữ nhật . Điều này là do nó đại diện cho các gói có cấu trúc dữ liệu rời rạc (một chuỗi các đa giác cùng với định hướng của chúng) đại diện cho một tập hợp các thủ tục trong đó các đa giác được trượt , song song với các cạnh của hình vuông, về phía một góc được chỉ định. Dường như một mã hóa rời rạc đơn giản như vậy sẽ kém hiệu quả hơn đối với các khu vực phức tạp hơn. Có lẽ sự đơn giản hóa ban đầu của các vùng trong lưới sẽ giúp ích.
whuber

2

Đối với tập hợp con bị ràng buộc cao mà bạn đã đề cập (lát vuông / tam giác trong ổ gà), giả sử các tối ưu hóa rõ ràng ở trên, mã giả này sẽ đi đến một câu trả lời gần đúng bằng cách đơn giản đưa bạn qua các khả năng với độ phân giải cao, vũ phu buộc vấn đề. Nó sẽ không hoạt động chính xác trong các tình huống trong đó xoay vòng gạch riêng lẻ có thể thấy lợi ích, như gạch hình chữ nhật hoặc thùng chứa không đều. Đây là 1 triệu lần lặp, bạn có thể thử thêm nếu cần thiết.

Giả sử hình vuông có cạnh dài L

Tạo một mô hình bàn cờ của hình vuông, ít nhất là kích thước của phạm vi của container, cộng với ít nhất 1L cho mỗi hướng.

N = 0

DX = 0

NÓ = 0

DR = 0

Đặt lại vị trí bàn cờ về trọng tâm ban đầu

Với (R = 1: 100)

Với (Y = 1: 100)

Với (X = 1: 100)

M = Đếm số lượng hình vuông hoàn toàn trong container

Nếu (M> N)

DR = R

NÓ = Y

DX = X

N = M

Di chuyển bàn cờ về phía đông bằng L / 100

Đặt lại bàn cờ đông

Di chuyển bàn cờ về phía bắc bằng L / 100

Đặt lại bàn cờ phía bắc

Xoay bàn cờ bằng 3,6 độ CW quanh tâm của nó

NÓI = NĂNG L

DX = DX * L

Đặt lại bàn cờ về vị trí ban đầu và xoay

In DR & "," & DX & "và" & DY & "là ma trận dịch / xoay cuối cùng"

Xoay bàn cờ bằng DR

Dịch bàn cờ bằng DX, DY

Chọn hình vuông hoàn toàn trong container

Xuất hình vuông


Nếu bạn thử quy trình này trên vùng 2 x 5 với một ô bị thiếu dọc theo giữa một cạnh dài, bạn sẽ thấy bạn chỉ có thể đặt một hình vuông 2 x 2 vào đó. Tuy nhiên, hai hình vuông như vậy dễ dàng phù hợp. Vấn đề là chúng không phải là một phần của mẫu "bàn cờ" thông thường. Khó khăn này là một trong những điều làm cho vấn đề này khá khó khăn.
whuber

1
Vâng Nếu bạn có một hình dạng thùng chứa không đều đủ để nó có thể hỗ trợ nhiều mẫu thông thường rời rạc theo thứ tự của một vài ô, thì điều này kết thúc rất xa so với tối ưu. Thêm những thứ như thế vào không gian khả năng sẽ tăng thời gian xử lý rất nhanh và đòi hỏi một mức độ lập kế hoạch nhất định cho trường hợp cụ thể mà bạn đang nhắm mục tiêu.
MappingTomorrow
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.