Thuật toán cho chữa lành vết thương nhiều hình chữ nhật thành một số lượng hình chữ nhật nhỏ hơn?


13

nhập mô tả hình ảnh ở đây

Giả sử tôi có một lưới các hình chữ nhật có hình dạng và màu sắc khác nhau và tôi muốn giảm (hợp lý gần với tối ưu là tốt, tối ưu là không cần thiết) số lượng hình chữ nhật để thể hiện cùng một bố cục màu.

Hình ảnh trên là một trường hợp rất đơn giản và khoảng trắng giữa các hình chữ nhật chỉ dành cho trực quan hóa - chúng thực sự sẽ được đóng gói chặt chẽ.

Cách tiếp cận hoặc tên thuật toán (hạnh phúc với google) có thể giúp tôi làm điều này là gì?


3
Bạn có thể cho chúng tôi biết một chút về những hình chữ nhật này đến từ đâu không? Họ có xu hướng (đại khái) căn chỉnh với bất kỳ lưới bên dưới, hoặc chia sẻ một số khối xây dựng chung, hoặc một số hình chữ nhật "nguyên tử" nhỏ nhất? Họ có thể được luân chuyển? Điều này có vẻ như là loại vấn đề có thể rất khó khăn trong trường hợp chung nhất, nhưng có thể dễ dàng hơn nhiều nếu chúng ta có thể khai thác một số hạn chế hoặc điểm chung trong kịch bản cụ thể của bạn.
DMGregory

Có một lưới các ô vuông bên dưới (như một bàn cờ) và mỗi hình chữ nhật đang chia sẻ ranh giới với các ô vuông bên dưới. tức là bạn có thể sử dụng một số nguyên để mô tả đỉnh / đáy / trái / phải của mỗi hình chữ nhật. Do đó, chúng không thể được xoay theo các góc không chia hết cho 90 độ. Ngoài ra, lưới NxM được điền đầy đủ các hình chữ nhật - không có vị trí lưới không được che chắn.
xaxxon

Tôi chỉ cố gắng tránh trường hợp giống như ví dụ ở trên (từ phối cảnh tô màu), nhưng nó được tạo thành từ một tấn hình chữ nhật 1x1 và tôi đang xử lý từng cái trong số chúng khi tôi có thể xử lý không gian trong nhiều Cuộc gọi ít hơn.
xaxxon

Tôi đoán một số loại "chỉ bắt đầu ở đâu đó và tiếp tục thử các hình chữ nhật lớn hơn và lớn hơn theo một chiều (nói theo chiều dọc) cho đến khi bạn chạm một đường viền màu, sau đó phát triển chiều khác (theo chiều ngang) cho đến khi bạn chạm vào một đường viền. Sau đó, có thể chỉ thử hình vuông (tăng theo đường chéo). Nhưng không chắc việc chỉ cần chọn khả năng lớn nhất trong 3 khả năng trên là cách tiếp cận phù hợp.
xaxxon

Có thể chấp nhận chia một hình chữ nhật hiện có, nếu cuối cùng nó có ít hình chữ nhật hơn không? Hoặc thuật toán chỉ nên hợp nhất bao giờ? Ngoài ra, tổng số là tiêu chí duy nhất, hay bạn thích hình dạng vuông hơn các mảnh gầy dài / hình chữ nhật lớn hơn hình nhỏ hơn?
DMGregory

Câu trả lời:


15

Đầu tiên, chúng tôi có thể chuyển đổi hình chữ nhật nguồn của bạn thành các ô trong lưới bên dưới của bạn, để làm cho đầu vào đồng đều hơn. (Hiệu quả khắc phục sự cố)

Điều này sẽ cho phép chúng tôi tìm thấy các tối ưu hóa có thể không rõ ràng khi làm việc trực tiếp với các hình chữ nhật nguồn - đặc biệt khi nó liên quan đến việc chia nhiều hình chữ nhật nguồn để kết hợp lại chúng theo cách khác nhau.

Ví dụ chuyển đổi hình chữ nhật thành các ô lưới và trở lại

Tiếp theo, chúng ta có thể tìm thấy các khu vực được kết nối có cùng màu, sử dụng thuật toán tìm kiếm theo chiều sâu hoặc tìm kiếm ngập lụt. Chúng ta có thể xem xét từng khu vực được kết nối (một polyomino ) một cách cô lập - không có gì chúng ta làm với một khu vực khác cần phải ảnh hưởng đến khu vực này.

Thực tế, chúng tôi muốn tìm cách phân tích polyomino này thành hình chữ nhật (tiếc là hầu hết các tài liệu tôi có thể tìm thấy là về vấn đề ngược lại: mổ xẻ hình chữ nhật thành đa hình! Điều này khiến cho việc tìm kiếm khách hàng tiềm năng trở nên khó khăn ...)

Một phương pháp đơn giản là kết hợp các đường ngang của các hình vuông liền kề thành các hình chữ nhật dài. Sau đó, chúng ta có thể so sánh với hàng ở trên và kết hợp nếu lần chạy và kết thúc của chúng ta khớp với nhau - khi chúng ta kết thúc mỗi lần chạy / hàng hoặc khi chúng ta xem xét từng ô để thêm vào lần chạy hiện tại.

Phân tách một polyomino thành các đường chạy ngang, sau đó hợp nhất theo chiều dọc

Tôi không biết làm thế nào gần phương pháp này đạt đến tối ưu. Có vẻ như nó có thể gặp một chút rắc rối khi một hàng mà nó chưa xem xét cho thấy sự phân chia khác với các hàng mà nó đã thấy cho đến nay:

Ví dụ về trường hợp với giải pháp 3 hình chữ nhật, trong đó phương pháp trên tìm thấy 4

Phát hiện khi chạy / hình chữ nhật được bao phủ chính xác bằng cách chạy bên trên & bên dưới, sau đó tách nó và hợp nhất chúng sẽ giải quyết trường hợp cụ thể này, nhưng tôi chưa khám phá vấn đề chung như thế nào.

Tôi cũng đã xem xét các phương pháp mà chúng ta đi theo chu vi của polyomino và cắt ngang bất cứ khi nào chúng ta gặp một góc lõm, nhưng cách tiếp cận này có vẻ dễ bị lỗi hơn đối với tôi. Để có kết quả tối ưu dường như yêu cầu các ưu tiên cắt giảm tham gia hai góc lõm và hình dạng chứa các hốc cần xử lý đặc biệt, vì vậy phương pháp quét hàng dường như có lợi thế đơn giản.

Một phương pháp nữa tôi đang tìm kiếm là thực hiện lần chạy đầu tiên được tìm thấy ở hàng trên cùng và kéo dài nó xuống hết mức có thể. Sau đó, chạy lần đầu tiên ở hàng trên cùng của những gì còn lại ... Điều này được tăng gấp ba lần trên các hình chữ T ngược, vì vậy nó cũng không tối ưu.

Tôi cảm thấy có lẽ có một cách để sử dụng lập trình động để tìm ra sự phân chia tối ưu, nhưng tôi chưa tìm thấy nó.


Cảm ơn câu trả lời tuyệt vời! giải pháp đó có vẻ đủ nhanh để tôi có thể chạy nó theo một vài hướng khác nhau và chọn hướng nào có vẻ tốt nhất --horizontal left-> right, vertical right-> left, và dọc theo mỗi chiều.
xaxxon

2
Vấn đề là chúng ta có thể xây dựng các hình dạng sẽ đánh lừa thuật toán từ mọi hướng quét. Những thứ đó có thể không xuất hiện trong sử dụng thực sự, nhưng nó vẫn làm tôi khó chịu. Tôi nghĩ rằng có một cách khắc phục đơn giản ... Một cái gì đó giống như ghi chú trong mỗi lần chạy, cho dù có các góc lõm phía trên nó giữa chừng. Sau đó, nếu lần chạy tiếp theo kết thúc tại một điểm chính xác như vậy, chúng ta quay lại thông qua các lần chạy phía trên để tách chúng theo chiều dọc. Tôi đã không sắp xếp các chi tiết đầy đủ mặc dù.
DMGregory

1
Ngoài ra, tôi không chắc tại sao bước lấp lũ là cần thiết. Khi đi từ một positino lưới đến một hình chữ nhật dài, bạn có thể chỉ cần đi bộ toàn bộ hàng hoặc cột của lưới (bất cứ cách nào bạn đi) để tạo các hình chữ nhật 1xN đó. Không cần phải biết polyomino, phải không?
xaxxon

Bạn nói đúng, việc lấp lũ không phải là một bước cần thiết. Tôi đã đưa nó vào để biện minh cho việc tập trung vào chỉ một vùng màu tại các bước tiếp theo, nhưng bạn có thể dễ dàng áp dụng phương pháp quét hàng cho nhiều vùng màu xen kẽ. Phương pháp dựa trên chu vi cần phải làm việc trên chu vi của một hình dạng tại một thời điểm.
DMGregory
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.