अलग-अलग आकार के आयतों को काफी इष्टतम तरीके से संभव बनाने के लिए अलग-अलग आकार की आयतों की पैकिंग के लिए किस एल्गोरिदम का उपयोग किया जा सकता है?


273

Ive को आयताकार वस्तुओं का एक गुच्छा मिला, जिसे मुझे संभव सबसे छोटी जगह में पैक करने की आवश्यकता है (इस स्थान के आयाम दो की शक्तियां होनी चाहिए)।

मुझे विभिन्न पैकिंग एल्गोरिदम के बारे में पता है जो किसी दिए गए स्थान पर यथासंभव वस्तुओं को पैक करेंगे, हालांकि इस मामले में मुझे यह काम करने के लिए एल्गोरिथ्म की आवश्यकता है कि अंतरिक्ष कितना बड़ा होना चाहिए।

उदाहरण के लिए, Ive को निम्नलिखित आयतें मिलीं

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

उन्हें एक 128 * 128 अंतरिक्ष में पैक किया जा सकता है

 _________________
| 128 * 32 |
| ________________ |
| 128 * 64 |
| |
| |
| ________________ |
| 64 * 32 | 64 * 32 |
| _______ | ________ |

हालाँकि अगर कोई 160 * 32 और 64 * 64 वाला होता तो उसे 256 * 128 स्थान की आवश्यकता होती

 ________________________________
| 128 * 32 | 64 * 64 | 64 * 32 |
| ________________ | | _______ |
| 128 * 64 | | 64 * 32 |
| | _______ | _______ |
| | |
| ________________ | ___ |
| 160 * 32 | |
| ____________________ | ___________ |

ऐसे कौन से एल्गोरिदम हैं जो आयतों का एक गुच्छा पैक करने में सक्षम हैं और कंटेनर के लिए आवश्यक आकार निर्धारित करते हैं (2 की शक्ति के लिए, और प्रत्येक आयाम के लिए दिए गए अधिकतम आकार के भीतर)?


6
क्या दूसरा समाधान इष्टतम नहीं है? क्या यह 224 से 128 नहीं होना चाहिए?
मन्त्र विदुतियाँ

"इस स्थान के आयामों में दो की शक्तियां होनी चाहिए" तो इससे कोई फर्क नहीं पड़ता है, क्योंकि यह क्या था / इसके लिए मैं यह नहीं मान सकता कि दो की गैर-शक्ति अंतर्निहित हार्डवेयर द्वारा बिना शर्त समर्थित है।
फायर लांसर

2
वैसे भी यह अंत में एल्गोरिथ्म को सरल बना देता है (यह सब 32x32 में फिट करने की कोशिश करें, अगर nto तो 64x32, फिर 64x64, 128x64, आदि का प्रयास करें) :)
फायर लांसर


मैंने एक प्रकार की ब्रूट फोर्स सॉल्यूशन को यहां stackoverflow.com/a/47698424/1641247
सीन

जवाबों:


67

त्वरित और गंदा पहला पास समाधान हमेशा एक महान के साथ शुरू होता है, एक तुलना के रूप में अगर कुछ और नहीं।

बड़े से छोटे के लिए लालची प्लेसमेंट।

शेष बचे हुए आयत को अपने पैक्ड क्षेत्र में रखें। यदि यह कहीं भी फिट नहीं हो सकता है, तो इसे ऐसी जगह पर रखें जो पैक क्षेत्र को जितना संभव हो उतना कम बढ़ाता है। तब तक दोहराएं जब तक आप सबसे छोटी आयत के साथ समाप्त न हो जाएं।

यह बिल्कुल सही नहीं है, लेकिन यह आसान और एक अच्छा आधार रेखा है। यह अभी भी आपके मूल उदाहरण को पूरी तरह से पैक करेगा, और आपको दूसरे के लिए भी एक समान उत्तर देगा।


1
मैं बस कागज के एक बिट पर कुछ के साथ खेल रहा था, अभी ज्यादातर मामलों में काफी इष्टतम दिखता है, यहां तक ​​कि आयतों या किसी भी चीज को घुमाए बिना
फायर लांसर

1
मैंने इसे लागू किया है और इसके माध्यम से परीक्षण डेटा का एक गुच्छा चला रहा है, केवल एक बहुत अच्छा डेटा बर्बाद करने के लिए एक बहुत अच्छा काम करने लगता है। अब मुझे बस अपने कार्यान्वयन को फिर से लिखने की जरूरत है, ताकि प्रत्येक पिक्सेल की जाँच के माध्यम से प्रत्येक रिक्टर के लिए एक रेखीय खोज की तुलना में अधिक कुशल हो। यह बिंदु अवरुद्ध है (सभी मौजूदा आयतों के खिलाफ ...)
फायर लांसर

4
एक इष्टतम समाधान jair.org/media/3735/live-3735-6794-jair.pdf
जिम

2
मेरे पास यह कल्पना करने का कठिन समय था कि यह कितना इष्टतम काम कर सकता है। इसलिए मैंने इसे (एक चौकोर आकार के साथ) कोडित किया है और परिणाम बहुत अच्छे हैं। : यहाँ एक डेमो एनीमेशन है imgur.com/ISjxuOR
अट्टिला Tanyi

@JimBalter वर्ग अंतरिक्ष वार ... शायद ... गति और मापनीयता के संदर्भ में? ज़रुरी नहीं?
बाल बाल

86

समाधान के सर्वेक्षण के लिए एआरसी परियोजना पर इस पृष्ठ को देखें , कार्यान्वयन जटिलता / समय और इष्टतमता के बीच एक व्यापार-बंद है, लेकिन चुनने के लिए एल्गोरिदम की एक विस्तृत श्रृंखला है।

यहाँ एल्गोरिदम का एक उद्धरण है:

  1. पहली-फिट घटती ऊंचाई (एफएफडीएच) एल्गोरिथ्म
    एफएफडीएच अगले आइटम आर (गैर-बढ़ती ऊंचाई में) पैक करता है जहां आर फिट बैठता है। यदि कोई स्तर R को समायोजित नहीं कर सकता है, तो एक नया स्तर बनाया जाता है।
    एफएफडीएच की समय जटिलता: ओ (एन · लॉग एन)।
    लगभग अनुपात: FFDH (I) <= (17/10) · OPT (I) +1; 17/10 की विषमता तंग है।

  2. अगली-फ़िट घटती ऊँचाई (NFDH) एल्गोरिथ्म
    NFDH अगले आइटम R (गैर-बढ़ती ऊंचाई में) आर के फिट होने पर वर्तमान स्तर पर पैक करता है। अन्यथा, वर्तमान स्तर "बंद" है और एक नया स्तर बनाया गया है।
    समय की जटिलता: O (n · log n)।
    लगभग अनुपात: NFDH (I) <= 2 · OPT (I) +1; 2 की विषमता तंग है।

  3. बेस्ट-फिट घटती ऊंचाई (बीएफडीएच) एल्गोरिथ्म
    बीएफडीएच अगले आइटम आर (गैर-बढ़ती ऊंचाई में) को स्तर पर पैक करता है, उनमें से आर को समायोजित कर सकते हैं, जिसके लिए अवशिष्ट क्षैतिज स्थान न्यूनतम है। यदि कोई स्तर R को समायोजित नहीं कर सकता है, तो एक नया स्तर बनाया जाता है।

  4. बॉटम-लेफ्ट (बीएल) एल्गोरिथ्म
    बीएल गैर-बढ़ती चौड़ाई द्वारा पहला ऑर्डर आइटम। बीएल अगले आइटम को नीचे के पास के रूप में पैक करता है क्योंकि यह फिट होगा और फिर बाएं के करीब होगा क्योंकि यह किसी भी पैक किए गए आइटम के साथ ओवरलैपिंग के बिना जा सकता है। ध्यान दें कि बीएल एक स्तर-उन्मुख पैकिंग एल्गोरिथ्म नहीं है।
    समय जटिलता: O (n ^ 2)।
    लगभग अनुपात: बीएल (आई) <= 3 · ऑप्ट (आई)।

  5. बेकर का अप-डाउन (यूडी) एल्गोरिथ्म
    यूडी बीएल के संयोजन और एनएफडीएच के एक सामान्यीकरण का उपयोग करता है। पट्टी की चौड़ाई और वस्तुओं को सामान्यीकृत किया जाता है ताकि पट्टी इकाई की चौड़ाई की हो। यूडी गैर-बढ़ती चौड़ाई में आइटम का आदेश देता है और फिर आइटम को पांच समूहों में विभाजित करता है, प्रत्येक की सीमा में चौड़ाई (1/2, 1], (1 / 3,1 / 2], (1 / 4,1 / 3) ], (१ / ५,१ / ४], (०,१ / ५]। पट्टी को पाँच क्षेत्रों आर १, · शोधक, आर ५ में भी विभाजित किया गया है। मूल रूप से, सीमा में चौड़ाई के कुछ आइटम (१ / आई +) 1, 1 / i], 1 <= i <= 4 के लिए, बीएल द्वारा रीजन के लिए पैक किया जाता है। चूंकि बीएल पट्टी के दाईं ओर ऊपर से नीचे तक चौड़ाई बढ़ाने का एक स्थान छोड़ देता है, यूडी पहले यह लाभ लेता है आइटम को Rj में j = 1 के लिए पैक करना, · · · · ऊपरी क्रम में नीचे से 4 (क्रम में)। यदि ऐसा कोई स्थान नहीं है, तो आइटम को BL द्वारा BL में पैक किया जाता है। अंत में, अधिकतम 1/5 पर आकार के आइटम। R1 (· सामान्यीकृत) NFDH एल्गोरिथ्म द्वारा R1, · abrasives, R4 में रिक्त स्थान के लिए पैक किए गए हैं।
    लगभग अनुपात: यूडी (आई) <= (5/4) · ऑप्ट (आई) + (53/8) एच, जहां एच वस्तुओं की अधिकतम ऊंचाई है; 5/4 की विषम सीमा तंग है।

  6. रिवर्स-फिट (आरएफ) एल्गोरिथ्म
    आरएफ भी पट्टी की चौड़ाई और वस्तुओं को सामान्य करता है ताकि पट्टी इकाई की चौड़ाई की हो। आरएफ पहले 1/2 से अधिक चौड़ाई की सभी वस्तुओं को ढेर करता है। शेष वस्तुओं को गैर-बढ़ती ऊंचाई में क्रमबद्ध किया जाता है और 1/2 से अधिक की ऊंचाई तक पहुंचने वाले H0 से ऊपर पैक किया जाएगा। फिर RF निम्नलिखित प्रक्रिया को दोहराता है। मोटे तौर पर, जब तक कोई और कमरा न हो, तब तक RF अपनी ऊंचाई के साथ बाएँ से दाएँ आइटम को पैक करता है। फिर आइटम को दाईं से बाईं ओर और ऊपर से नीचे (रिवर्स-स्तर कहा जाता है) तक पैक करता है जब तक कि कुल चौड़ाई कम से कम 1/2 न हो। तब रिवर्स-स्तर को नीचे गिरा दिया जाता है जब तक (कम से कम) उनमें से एक नीचे किसी वस्तु को नहीं छूता है। ड्रॉप डाउन किसी तरह दोहराया जाता है।
    लगभग अनुपात: RF (I) <= 2 · OPT (I)।

  7. स्टाइनबर्ग की एल्गोरिथ्म
    स्टीनबर्ग की एल्गोरिथ्म, जिसे कागज में एम के रूप में चिह्नित किया गया है, सभी वस्तुओं को पैक करने के लिए आवश्यक ऊँचाई एच की एक ऊपरी सीमा का अनुमान लगाता है, ताकि यह साबित हो जाए कि इनपुट वस्तुओं को चौड़ाई डब्ल्यू और ऊंचाई एच की एक आयत में पैक किया जा सकता है। सात प्रक्रियाओं (सात स्थितियों के साथ) को परिभाषित करें, प्रत्येक समस्या को दो छोटे में विभाजित करें और उन्हें पुन: हल करें। यह दिखाया गया है कि कोई भी ट्रैक्टेबल समस्या सात स्थितियों में से एक को संतुष्ट करती है।
    अनुमान अनुपात: M (I) <= 2 · OPT (I)।

  8. स्प्लिट-फिट एल्गोरिथ्म (एसएफ) एसएफ दो समूहों में आइटम विभाजित करता है, एल 1 की चौड़ाई 1/2 से अधिक है और एल 2 सबसे अधिक 1/2 है। L1 के सभी आइटम पहले FFDH द्वारा पैक किए जाते हैं। फिर उन्हें व्यवस्थित किया जाता है ताकि 2/3 से अधिक चौड़ाई वाले सभी आइटम अधिकतम 2/3 की चौड़ाई वाले नीचे हों। यह 1/3 की चौड़ाई के साथ अंतरिक्ष का एक आयत R बनाता है। L2 में शेष वस्तुएं R से पैक की जाती हैं और F1DH का उपयोग करते हुए L1 के साथ पैक किए गए रिक्त स्थान से ऊपर होती हैं। R में बनाए गए स्तर को L1 की पैकिंग के ऊपर बनाए गए से नीचे माना जाता है।
    लगभग अनुपात: एसएफ (आई) <= (3/2) · ऑप्ट (आई) + 2; 3/2 की विषम सीमा तंग है।

  9. है Sleator एल्गोरिथ्म
    Sleater एल्गोरिथ्म चार चरणों के होते हैं:

    1. 1/2 से अधिक चौड़ाई के सभी आइटम पट्टी के तल में एक दूसरे के ऊपर पैक किए जाते हैं। मान लीजिए कि h0 परिणामी पैकिंग की ऊंचाई है, बाद की सभी पैकिंग h0 से ऊपर होगी।

    2. शेष वस्तुओं को गैर-बढ़ती ऊंचाई द्वारा आदेश दिया जाता है। ऊँचाई h0 की पंक्ति के साथ बाईं ओर से दाईं ओर आइटम का एक स्तर पैक किया जाता है (गैर-बढ़ती ऊंचाई क्रम में)।

    3. एक ऊर्ध्वाधर रेखा को फिर पट्टी को दो बराबर हिस्सों में काटने के लिए बीच में खींचा जाता है (ध्यान दें कि यह रेखा उस आइटम को काट सकती है जो आंशिक रूप से दाईं ओर पैक की गई है)। लंबाई के दो क्षैतिज रेखाखंडों को आधा, एक को बाएं आधे (जिसे बायाँ आधार रेखा कहा जाता है) और एक को दायें आधे (दाएं आधार रेखा कहा जाता है) के रूप में कम से कम इस तरह खींचें कि दोनों रेखाएँ किसी भी वस्तु को पार न करें।

    4. बाईं या दाईं आधार रेखा चुनें, जो कम ऊँचाई की हो और पट्टी के संगत आधे भाग में वस्तुओं के स्तर को तब तक पैक करें जब तक कि अगला आइटम बहुत चौड़ा न हो जाए।

    एक नई बेसलाइन बनाई जाती है और चरण (4) को निचले बेसलाइन पर दोहराया जाता है जब तक कि सभी आइटम पैक नहीं हो जाते।
    समय जटिलता: ओ (एन · लॉग एन)।
    स्लेटोर के एल्गोरिथ्म का अनुमानित अनुपात 2.5 है जो तंग है।


6
इन सभी को अंतरिक्ष की चौड़ाई जानने की आवश्यकता है।
क्वांटम 7

1
@ क्वांटम 7 संभवतः बहुत महत्वपूर्ण नहीं है क्योंकि ओपी को दो की शक्तियों की आवश्यकता होती है, इसलिए हम पर्याप्त क्षेत्र के साथ आयामों का एक गुच्छा आज़मा सकते हैं।
सिरो सेंटिल्ली 郝海东 冠状 iro i ''

19

पैकिंग की समस्याओं पर एक नजर । मुझे लगता है कि तुम्हारा '2 डी बिन पैकिंग' के अंतर्गत आता है। आपको उस समाधान और अन्य पैकिंग समस्याओं से बहुत कुछ सीखने में सक्षम होना चाहिए।

इसे भी देखें: आयताकार छवि डेटा को एक वर्ग बनावट में पैक करना।


यहाँ एक अनुकूलन आयत-पैकिंग एल्गोरिथ्म का एक और अच्छा उदाहरण है: codeproject.com/Articles/210979/…
एंडरसन ग्रीन

समस्या का भी उल्लेख किया गया: en.wikipedia.org/wiki/… उल्लेखनीय रूप से, यह बिन पैकिंग को अज्ञात आकार के एक बिन में प्रतिबंधित करता है, मुझे आश्चर्य है कि अगर यह अभी भी एनपी-पूर्ण है।
सिरो सेंटिल्ली 郝海东 冠状 iro 法轮功 ''

17

इस समस्या पर व्यापक साहित्य है। एक अच्छा लालची उत्तराधिकारी सबसे बड़े क्षेत्र से सबसे छोटे स्थान तक सबसे पहले उपलब्ध स्थिति में नीचे और कंटेनर के बाईं ओर स्थित है। गुरुत्वाकर्षण के सभी मदों को निचले बाएँ कोने में नीचे खींचने के बारे में सोचें। इस google के वर्णन के लिए "चेज़ेल बॉटम लेफ्ट पैकिंग"।

इष्टतम समाधानों के लिए, अत्याधुनिक तकनीकें कुछ सेकंड में 20 से अधिक आयतों को पैक कर सकती हैं। हुआंग का एक एल्गोरिथ्म है जो छोटी से छोटी एनक्लोजिंग बाउंडिंग बॉक्स को खोजने की समस्या से अलग करता है, यह तय करने की समस्या है कि क्या आयत का एक सेट एक विशिष्ट आकार के बाउंडिंग बॉक्स में फिट हो सकता है या नहीं। आप उनके कार्यक्रम को आयतों का एक सेट देते हैं, और यह आपको बताता है कि उन्हें पैक करने के लिए आवश्यक छोटी से छोटी एनक्लोज़िंग बाउंडिंग बॉक्स है।

आपके मामले के लिए, आपके बाहरी लूप को सबसे छोटे संभव बाउंडिंग बॉक्स से ऊपर की ओर चलना चाहिए (चौड़ाई और ऊंचाई दो की शक्तियों द्वारा क्रमिक रूप से बढ़ रही है)। इन बाउंडिंग बॉक्सों में से प्रत्येक के लिए, यह देखने के लिए परीक्षण करें कि क्या आप अपने आयतों के लिए पैकिंग पा सकते हैं। आपको "नहीं" उत्तरों का एक गुच्छा मिलेगा, जब तक कि पहले "हां" जवाब नहीं दिया जाएगा, जो कि इष्टतम समाधान होने की गारंटी होगी।

अपने एल्गोरिथ्म के आंतरिक लूप के लिए - वह जो विशिष्ट आकार के एक बाउंडिंग बॉक्स में "हां" या "नहीं" का जवाब देता है, मैं हुआंग संदर्भ को देखूंगा और बस उसके एल्गोरिदम को लागू करूंगा। वह बुनियादी एल्गोरिथ्म के शीर्ष पर बहुत सारे अनुकूलन शामिल करता है, लेकिन आपको केवल मूल मांस और आलू की आवश्यकता होती है। चूँकि आप अपनी खोज के दौरान हर शाखा बिंदु पर घुमावों को संभालना चाहते हैं, बस दोनों रोटेशन और बैकट्रैक को आज़माएँ जब दोनों घुमावों के परिणामस्वरूप समाधान नहीं होता है।


9

मुझे पूरा यकीन है कि यह एक एनपी-हार्ड समस्या है , इसलिए, एक इष्टतम समाधान के लिए, आपको एक बैकग्राउंडिंग एल्गोरिदम लागू करना होगा जो हर संभव संयोजन की कोशिश करता है।

अच्छी खबर यह है कि 2 डी आयतों को एक सीमित 2 डी स्थान में पैक करने की आवश्यकता के कारण, आप बहुत सारी संभावनाओं को जल्दी से दूर कर सकते हैं, इसलिए यह बुरा नहीं हो सकता है।


3
आप शायद एनपी-पूरा मतलब है।
स्टारबेल जू

7
ठीक है, अगर यह एनपी पूरा हो गया है, तो इसे हल करना आसान है, बस यात्रा विक्रेता के समतुल्य उदाहरण को हल करें, और वहां आप जाएं। लेकिन यह दिखाने के लिए तुच्छ है कि जैसा कि सामने आया है, यह नहीं है, क्योंकि एनपी-पूर्ण समस्याएं निर्णय समस्याएं हैं (आपको वापस हां / नहीं में कोई उत्तर नहीं मिलता है), और एक बहुपद समय सत्यापन एल्गोरिथ्म है। सवाल "क्या आयतों की व्यवस्था है a, b, c ... जो 256 * 128 से कम क्षेत्रफल को NP- पूर्ण कर सकती है।
ग्रहण

2
@ ग्रहण सही है। से jair.org/media/3735/live-3735-6794-jair.pdf "अनुकूलन समस्या, एनपी कठिन है, जबकि तय आयतों का एक सेट दिए गए बाउंडिंग बॉक्स में पैक किया जा सकता की समस्या एनपी पूरा हो गया है बिन-पैकिंग (कोर्फ, 2003) से कमी के माध्यम से। " हालांकि, ध्यान दें कि ओपी ने "एक काफी इष्टतम तरीका" के लिए कहा, और पी में इसके लिए समाधान हैं "व्यापक रूप से" की पर्याप्त परिभाषाओं के लिए।
जिम बेल्टर

मुझे एनपी-कठोरता पर भी संदेह है, लेकिन हमें एक संदर्भ / प्रमाण की आवश्यकता है।
सिरो सेंटिल्ली 郝海东 冠状 iro 法轮功 ''

2
पवित्र धागा नेक्रो, बैटमैन। यह एक पैकिंग समस्या है, और यह पहले से ही एनपी-हार्ड साबित हो रहा है: en.wikipedia.org/wiki/Packing_problems
Blindy

2

आपको क्या चाहिए https://github.com/nothings/stb/blob/master/stb_rect_pack.h

नमूना:

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

एक सामान्य समाधान गैर-तुच्छ है (पूरी तरह से **** आईएनजी असंभव के लिए गणित बोलते हैं)
आम तौर पर लोग संभावित संयोजनों की कोशिश करने के लिए एक आनुवंशिक एल्गोरिथ्म का उपयोग करते हैं लेकिन आप पहले आकार में सबसे बड़ा आकार डालकर और फिर विभिन्न स्थानों के लिए अलग-अलग स्थानों की कोशिश करके यथोचित प्रदर्शन कर सकते हैं अगले सबसे बड़ा और इतने पर।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.