Thuật toán nào có thể được sử dụng để đóng gói các hình chữ nhật có kích thước khác nhau thành hình chữ nhật nhỏ nhất có thể theo một cách khá tối ưu?


273

Ive có một loạt các vật thể hình chữ nhật mà tôi cần phải đóng gói vào không gian nhỏ nhất có thể (kích thước của không gian này phải là sức mạnh của hai).

Tôi nhận thức được các thuật toán đóng gói khác nhau sẽ đóng gói các vật phẩm tốt nhất có thể vào một không gian nhất định, tuy nhiên trong trường hợp này tôi cần thuật toán để tìm ra không gian đó cũng lớn như thế nào.

Ví dụ: Ive có các hình chữ nhật sau

  • 128 * 32
  • 128 * 64
  • 64 * 32
  • 64 * 32

Chúng có thể được đóng gói vào một không gian 128 * 128

 _________________
| 128 * 32 |
| ______________ |
| 128 * 64 |
| |
| |
| ______________ |
| 64 * 32 | 64 * 32 |
| ___ | ____ |

Tuy nhiên, nếu có cả 160 * 32 và 64 * 64 thì nó sẽ cần một không gian 256 * 128

 Giới thiệu
| 128 * 32 | 64 * 64 | 64 * 32 |
| ______________ | | ___ |
| 128 * 64 | | 64 * 32 |
| | ___ | ___ |
| | |
| ______________ | ___ |
| 160 * 32 | |
| ______________ | ___________ |

Có những thuật toán nào có khả năng đóng gói một loạt các hình chữ nhật và xác định kích thước cần thiết cho vật chứa (với công suất là 2 và trong một kích thước tối đa nhất định cho mỗi kích thước)?


6
Không phải là giải pháp thứ hai không tối ưu? Không phải là 128 x 224 sao?
Thần chú Vidutis

"kích thước của không gian này phải là sức mạnh của hai" Vì vậy, nó không có gì khác biệt, vì điều này là / tôi không thể cho rằng phi năng lượng của hai được hỗ trợ vô điều kiện bởi phần cứng bên dưới.
Lancer lửa

2
Dù sao nó làm cho các thuật toán đơn giản cuối cùng (cố gắng phù hợp với nó tất cả trong 32x32, nếu nĐể sau đó thử 64x32, 64x64 sau đó, 128x64, vv) :)
cháy Lancer


Tôi đặt một loại giải pháp vũ phu lên đây stackoverflow.com/a/47698424/1641247
Sean

Câu trả lời:


67

Giải pháp vượt qua đầu tiên nhanh chóng và bẩn thỉu luôn là một giải pháp tuyệt vời để bắt đầu, như một sự so sánh nếu không có gì khác.

Vị trí tham lam từ lớn đến nhỏ.

Đặt hình chữ nhật lớn nhất còn lại vào khu vực đóng gói của bạn. Nếu nó không thể phù hợp với bất cứ nơi nào, hãy đặt nó ở một nơi mở rộng khu vực gói càng ít càng tốt. Lặp lại cho đến khi bạn hoàn thành với hình chữ nhật nhỏ nhất.

Nó không hoàn hảo chút nào nhưng nó dễ dàng và là một cơ sở tốt đẹp. Nó vẫn sẽ đóng gói ví dụ ban đầu của bạn một cách hoàn hảo và cũng cung cấp cho bạn một câu trả lời tương đương cho lần thứ hai.


1
Tôi chỉ chơi với một thứ như thế trên một tờ giấy, ngay bây giờ trông khá tối ưu trong hầu hết các trường hợp, ngay cả khi không xoay hình chữ nhật hay bất cứ thứ gì
Fire Lancer

1
Tôi đã thực hiện nó và chạy một loạt dữ liệu thử nghiệm thông qua nó, dường như làm một công việc khá tốt chỉ để lại một ít dữ liệu lãng phí. Bây giờ tôi chỉ cần viết lại việc triển khai của mình để hiệu quả hơn so với tìm kiếm tuyến tính cho từng chỉnh lưu thông qua không gian có sẵn kiểm tra từng pixel là điểm đó bị chặn (đối với tất cả các kiến ​​trúc hiện có) ...
Fire Lancer

4
Một giải pháp tối ưu được đưa ra trong jair.org/media/3735/live-3735-6794-jair.pdf
Jim Balter

2
Tôi đã có một thời gian khó khăn để cố gắng tưởng tượng làm thế nào tối ưu này có thể làm việc. Vì vậy, tôi đã mã hóa nó (với một hình vuông) và kết quả rất tuyệt vời. Đây là một hình ảnh động demo: imgur.com/ISjxuOR
Attila Tanyi

@JimBalter không gian vuông khôn ngoan ... có lẽ ... về tốc độ và khả năng mở rộng? Có thật không?
Arek Bal

86

Xem trang này trên dự án ARC để khảo sát các giải pháp, có sự đánh đổi giữa độ phức tạp / thời gian thực hiện và sự tối ưu, nhưng có một loạt các thuật toán để lựa chọn.

Đây là một trích xuất của các thuật toán:

  1. Thuật toán First-Fit Giảm chiều cao (FFDH)
    FFDH đóng gói vật phẩm tiếp theo R (ở chiều cao không tăng) ở cấp độ đầu tiên mà R phù hợp. Nếu không có cấp nào có thể chứa R, một cấp mới sẽ được tạo.
    Độ phức tạp thời gian của FFDH: O (n · log n).
    Tỷ lệ xấp xỉ: FFDH (I) <= (17/10) · OPT (I) +1; giới hạn tiệm cận của 17/10 là chặt chẽ.

  2. Thuật toán Next-Fit Giảm chiều cao (NFDH)
    NFDH gói mục tiếp theo R (ở chiều cao không tăng) ở mức hiện tại nếu R phù hợp. Mặt khác, mức hiện tại là "đóng" và một mức mới được tạo.
    Độ phức tạp thời gian: O (n · log n).
    Tỷ lệ xấp xỉ: NFDH (I) <= 2 · OPT (I) +1; ràng buộc tiệm cận của 2 là chặt chẽ.

  3. Thuật toán Best-Fit Giảm chiều cao phù hợp (BFDH)
    BFDH gói mục tiếp theo R (ở chiều cao không tăng) ở cấp độ, trong số các mức có thể chứa R, trong đó không gian ngang còn lại là tối thiểu. Nếu không có cấp nào có thể chứa R, một cấp mới sẽ được tạo.

  4. Thuật toán dưới cùng bên trái (BL)
    BL các mục thứ tự đầu tiên theo chiều rộng không tăng. BL đóng gói các mặt hàng tiếp theo gần với đáy vì nó sẽ vừa và sau đó càng gần bên trái càng tốt mà không bị chồng chéo với bất kỳ mặt hàng đóng gói nào. Lưu ý rằng BL không phải là một thuật toán đóng gói theo định hướng cấp.
    Độ phức tạp thời gian: O (n ^ 2).
    Tỷ lệ xấp xỉ: BL (I) <= 3 · OPT (I).

  5. Thuật toán Up-Down (UD) của Baker
    UD sử dụng kết hợp BL và tổng quát hóa NFDH. Chiều rộng của dải và các mục được chuẩn hóa để dải có chiều rộng đơn vị. UD sắp xếp các mục theo chiều rộng không tăng và sau đó chia các mục thành năm nhóm, mỗi nhóm có chiều rộng trong phạm vi (1/2, 1], (1 / 3,1 / 2], (1 / 4,1 / 3 ], (1 / 5,1 / 4], (0,1 / 5]. Dải cũng được chia thành năm khu vực R1, ···, R5. Về cơ bản, một số mục có chiều rộng trong phạm vi (1 / i + 1, 1 / i], với 1 <= i <= 4, được đóng gói vào vùng Ri bởi BL. Vì BL để lại một khoảng trống tăng chiều rộng từ trên xuống dưới ở phía bên phải của dải, UD tận dụng lợi thế này trước tiên đóng gói vật phẩm vào Rj cho j = 1, · ////, 4 (theo thứ tự) từ trên xuống dưới. Nếu không có không gian như vậy, vật phẩm được đóng gói vào Ri bởi BL. Cuối cùng, các vật phẩm có kích thước tối đa 1/5 được đóng gói vào các khoảng trắng trong R1, · ////, R4 bằng thuật toán NFDH (tổng quát).
    Tỷ lệ xấp xỉ: UD (I) <= (5/4) · OPT (I) + (53/8) H, trong đó H là chiều cao tối đa của các mục; giới hạn tiệm cận của 5/4 là chặt chẽ.

  6. Thuật toán Reverse-fit (RF)
    RF cũng bình thường hóa chiều rộng của dải và các vật phẩm để dải có chiều rộng đơn vị. RF đầu tiên xếp tất cả các mục có chiều rộng lớn hơn 1/2. Các mục còn lại được sắp xếp theo chiều cao không tăng và sẽ được đóng gói trên độ cao H0 đạt được bởi những người lớn hơn 1/2. Sau đó RF lặp lại quy trình sau. Nói một cách đơn giản, RF gói các vật phẩm từ trái sang phải với đáy của chúng dọc theo chiều cao H0 cho đến khi không còn chỗ trống. Sau đó đóng gói các mục từ phải sang trái và từ trên xuống dưới (được gọi là cấp độ ngược) cho đến khi tổng chiều rộng tối thiểu là 1/2. Sau đó, cấp độ ngược được thả xuống cho đến khi (ít nhất) một trong số chúng chạm vào một số mục bên dưới. Việc thả xuống bằng cách nào đó được lặp lại.
    Tỷ lệ xấp xỉ: RF (I) <= 2 · OPT (I).

  7. Thuật toán của Steinberg Thuật toán của
    Steinberg, ký hiệu là M trong bài báo, ước tính giới hạn trên của chiều cao H cần thiết để đóng gói tất cả các mục sao cho chứng minh rằng các mục đầu vào có thể được đóng gói thành một hình chữ nhật có chiều rộng W và chiều cao H. xác định bảy thủ tục (với bảy điều kiện), mỗi điều kiện để chia một vấn đề thành hai quy trình nhỏ hơn và giải quyết chúng một cách đệ quy. Nó đã được chỉ ra rằng bất kỳ vấn đề có thể kéo được thỏa mãn một trong bảy điều kiện.
    Tỷ lệ xấp xỉ: M (I) <= 2 · OPT (I).

  8. Thuật toán Split-Fit (SF) SF chia các mục thành hai nhóm, L1 với chiều rộng lớn hơn 1/2 và L2 nhiều nhất là 1/2. Tất cả các mục của L1 được FFDH đóng gói đầu tiên. Sau đó, chúng được sắp xếp sao cho tất cả các mục có chiều rộng hơn 2/3 đều nằm dưới các mục có chiều rộng tối đa bằng 2/3. Điều này tạo ra một hình chữ nhật R của không gian với chiều rộng 1/3. Các mục còn lại trong L2 sau đó được đóng gói thành R và khoảng trống phía trên các mục được đóng gói với L1 bằng FFDH. Các mức được tạo trong R được coi là thấp hơn các mức được tạo bên trên bao bì của L1.
    Tỷ lệ xấp xỉ: SF (I) <= (3/2) · OPT (I) + 2; giới hạn tiệm cận của 3/2 là chặt chẽ.

  9. Thuật toán của Sleator Thuật toán của
    Sleater bao gồm bốn bước:

    1. Tất cả các mục có chiều rộng lớn hơn 1/2 được đóng gói chồng lên nhau ở dưới cùng của dải. Giả sử h0 là chiều cao của bao bì kết quả Tất cả các lần đóng gói tiếp theo sẽ xảy ra trên h0.

    2. Các mặt hàng còn lại được sắp xếp theo chiều cao không tăng. Một mức độ của các mặt hàng được đóng gói (theo thứ tự chiều cao không tăng) từ trái sang phải dọc theo chiều cao h0.

    3. Một đường thẳng đứng sau đó được vẽ ở giữa để cắt dải thành hai nửa bằng nhau (lưu ý dòng này có thể cắt một mặt hàng được đóng gói một phần ở nửa bên phải). Vẽ hai đoạn đường ngang có chiều dài một nửa, một ngang qua nửa bên trái (được gọi là đường cơ sở bên trái) và một đoạn ở nửa bên phải (được gọi là đường cơ sở bên phải) càng thấp càng tốt để hai đường không đi qua bất kỳ mục nào.

    4. Chọn đường cơ sở bên trái hoặc bên phải có chiều cao thấp hơn và đóng gói một mức vật phẩm vào một nửa dải tương ứng cho đến khi mục tiếp theo quá rộng.

    Một đường cơ sở mới được hình thành và Bước (4) được lặp lại ở đường cơ sở thấp hơn cho đến khi tất cả các mặt hàng được đóng gói.
    Độ phức tạp thời gian: O (n · log n).
    Tỷ lệ gần đúng của thuật toán Sleator là 2,5, chặt chẽ.


6
Tất cả những điều này đòi hỏi phải biết chiều rộng của không gian.
Quantum7

1
@ Quantum7 có thể không quá quan trọng vì OP yêu cầu các bên phải là sức mạnh của hai, vì vậy chúng tôi chỉ có thể thử một loạt các kích thước với diện tích đủ.
Ciro Santilli 郝海东 冠状 病

19

Có một cái nhìn về các vấn đề đóng gói . Tôi nghĩ rằng của bạn rơi vào 'đóng gói thùng 2D.' Bạn sẽ có thể học được rất nhiều từ các giải pháp cho vấn đề đó và các vấn đề đóng gói khác.

Xem thêm: Đóng gói dữ liệu hình ảnh hình chữ nhật thành một kết cấu vuông.


Đây là một ví dụ hay khác về thuật toán đóng gói hình chữ nhật tối ưu hóa: codeproject.com/Articles/210979/iêu
Anderson Green

Vấn đề cũng được đề cập trong: en.wikipedia.org/wiki/ Từ Đáng chú ý, điều này hạn chế việc đóng gói bin vào một thùng có kích thước không xác định, tôi tự hỏi liệu nó có còn hoàn thành NP không.
Ciro Santilli 郝海东 冠状 病 事件

17

Có nhiều tài liệu về vấn đề này. Một heuristic tham lam tốt là đặt hình chữ nhật từ khu vực lớn nhất đến nhỏ nhất ở vị trí có sẵn đầu tiên về phía dưới và bên trái của container. Hãy nghĩ về trọng lực kéo tất cả các vật phẩm xuống góc dưới bên trái. Đối với một mô tả của google này "Chazelle dưới cùng đóng gói".

Đối với các giải pháp tối ưu, các kỹ thuật tiên tiến có thể đóng gói hơn 20 hình chữ nhật trong vài giây. Huang có một thuật toán phân tách vấn đề tìm hộp giới hạn nhỏ nhất khỏi vấn đề quyết định xem một tập hợp hình chữ nhật có thể vừa trong một hộp giới hạn có kích thước cụ thể hay không. Bạn đưa cho chương trình của anh ta một tập hợp các hình chữ nhật, và nó cho bạn biết hộp giới hạn bao quanh nhỏ nhất cần có để đóng gói chúng.

Đối với trường hợp của bạn, vòng lặp bên ngoài của bạn sẽ lặp từ hộp giới hạn nhỏ nhất có thể lên trên (với chiều rộng và chiều cao tăng liên tiếp theo lũy thừa của hai). Đối với mỗi hộp giới hạn này, hãy kiểm tra xem bạn có thể tìm thấy bao bì cho hình chữ nhật của mình không. Bạn sẽ nhận được một loạt các câu trả lời "không", cho đến câu trả lời "có" đầu tiên, sẽ được đảm bảo là giải pháp tối ưu.

Đối với vòng lặp bên trong của thuật toán của bạn - câu trả lời "có" hoặc "không" cho một hộp giới hạn có kích thước cụ thể, tôi sẽ tra cứu tham chiếu Huang và chỉ thực hiện thuật toán của mình. Ông bao gồm rất nhiều tối ưu hóa trên đầu thuật toán cơ bản, nhưng bạn chỉ thực sự cần thịt và khoai tây cơ bản. Vì bạn muốn xử lý các phép quay, tại mọi điểm nhánh trong quá trình tìm kiếm của bạn, chỉ cần thử cả hai phép quay và quay lui khi cả hai phép quay không dẫn đến một giải pháp.


9

Tôi khá chắc chắn rằng đây là một vấn đề khó NP , vì vậy, để có giải pháp tối ưu, bạn phải thực hiện thuật toán quay lui thử mọi kết hợp có thể.

Tin tốt là vì cần phải đóng gói các hình chữ nhật 2D trong một không gian 2D hạn chế, bạn có thể sớm cắt tỉa rất nhiều khả năng, vì vậy nó có thể không tệ.


3
Bạn có thể có nghĩa là NP-hoàn thành.
starblue

7
Chà, nếu NP hoàn thành, thì thật dễ để giải quyết, chỉ cần giải một ví dụ tương đương của nhân viên bán hàng du lịch, và bạn đến đó. Nhưng thật đơn giản để chỉ ra rằng như đã đặt ra, không phải vậy, vì các vấn đề hoàn thành NP là vấn đề quyết định (bạn nhận lại câu trả lời có / không) và có thuật toán xác minh thời gian đa thức. Câu hỏi "có sự sắp xếp các hình chữ nhật a, b, c ... chiếm ít diện tích hơn 256 * 128 có thể được hoàn thành NP hay không
Eclipse

2
@Eclipse là chính xác. Từ jair.org/media/3735/live-3735-6794-jair.pdf "Vấn đề tối ưu hóa là NP-hard, trong khi vấn đề quyết định liệu một tập hợp hình chữ nhật có thể được đóng gói trong hộp giới hạn nhất định là NP-đầy đủ không, thông qua việc giảm từ đóng gói bin (Korf, 2003). " Tuy nhiên, lưu ý rằng OP đã yêu cầu "một cách khá tối ưu" và có các giải pháp cho điều đó trong P, cho các định nghĩa đủ rộng về "khá".
Jim Balter

Tôi cũng nghi ngờ độ cứng NP, nhưng chúng tôi cần một tài liệu tham khảo / bằng chứng.
Ciro Santilli 郝海东 冠状 病 事件

2
Necro chủ đề thần thánh, Batman. Đây là một vấn đề về đóng gói và nó đã được chứng minh là NP-hard tốt nhất: en.wikipedia.org/wiki/Packing_probols
Blindy

2

Những gì bạn cần là tại https://github.com/nothings/stb/blob/master/stb_rect_pack.h

mẫu vật:

stbrp_context context;

struct stbrp_rect rects[100];

for (int i=0; i< 100; i++)
{
    rects[i].id = i;
    rects[i].w = 100+i;
    rects[i].h = 100+i;
    rects[i].x = 0;
    rects[i].y = 0;
    rects[i].was_packed = 0;
}

int rectsLength = sizeof(rects)/sizeof(rects[0]);

int nodeCount = 4096*2;
struct stbrp_node nodes[nodeCount];


stbrp_init_target(&context, 4096, 4096, nodes, nodeCount);
stbrp_pack_rects(&context, rects, rectsLength);

for (int i=0; i< 100; i++)
{
    printf("rect %i (%hu,%hu) was_packed=%i\n", rects[i].id, rects[i].x, rects[i].y, rects[i].was_packed);
}

1

Một giải pháp chung là không tầm thường (toán học nói hoàn toàn **** không thể)
Nói chung mọi người sử dụng thuật toán di truyền để thử các kết hợp có thể nhưng bạn có thể làm tốt một cách hợp lý bằng cách đặt hình dạng lớn nhất vào trước và sau đó thử các vị trí khác nhau cho tiếp theo lớn nhất và như vậy.

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.