इस समस्या के वैकल्पिक समाधान के रूप में, मेरा एल्गोरिथ्म डेक में कार्ड के समूहों के लिए प्रति कार्ड पर भिन्न भिन्न (गैर पूर्णांक) बिट्स का उपयोग करता है जो इस बात पर आधारित है कि कितने अपूर्ण रैंक शेष हैं। यह एक बहुत ही सुंदर एल्गोरिथ्म है। मैंने हाथ से अपने सांकेतिक एल्गोरिदम की जाँच की और यह अच्छा लग रहा है। एनकोडर आउटपुट कर रहा है जो सही बिटस्ट्रिंग (सरलता के लिए बाइट फॉर्म में) दिखाई देता है।
मेरे एल्गोरिथ्म का अवलोकन यह है कि यह कार्ड के समूहों और मिश्रित आंशिक बिट एन्कोडिंग के संयोजन का उपयोग करता है। उदाहरण के लिए, मिलियन फेरबदल वाले डेक की मेरी साझा परीक्षण फ़ाइल में , पहले वाले में 54 ए 236 जे के पहले 7 कार्ड हैं । जब मैंने 13 रैंक के कार्ड संभव हो तो 7 कार्ड ब्लॉक आकार चुना , क्योंकि 13 7 "शूहॉर्न" (स्नूगली फिट बैठता है) 26 बिट्स में ( 13 7 = 62 , 748 , 517 और 2 26 = 67 , 108 , 108 )3754A236J7131372613762 , 748,517226 ) है। आदर्श रूप से हम चाहते हैं कि उन 2 नंबरों को जितना संभव हो सके (लेकिन 2 नंबरों की शक्ति के साथ थोड़ा अधिक), इसलिए हम बिट पैकिंग प्रक्रिया में बहुत कम अंशों से अधिक बर्बाद नहीं करते हैं। नोट मैं भी groupsize चुन सकते थे 4 जब एन्कोडिंग 13 के बाद से रैंक 13 4 = 28 , 561 और 2 15 = 32 , 768 । यह तंग के रूप में के बाद से एक फिट नहीं है 15 / 4 = 3.75 लेकिन 26 / 7 = 3.71467 , 108,864241313428 , 56121532 , 76815 / 4 = 3.7526 / 7 = 3.714। प्रति कार्ड बिट्स की संख्या तो प्रति कार्ड थोड़ा कम अगर हम का उपयोग है पैकिंग विधि।२६ / 7
तो , हम अपने मास्टर " 23456789 टी जे क्यू के ए " क्रमबद्ध रैंक की सूची में उन रैंक की क्रमिक स्थिति को देखते हैं । उदाहरण के लिए, के पहले वास्तविक कार्ड रैंक 5 के पद देखने स्ट्रिंग में देखने स्थिति है 4 । हम सिर्फ इन इलाज 7 एक आधार के रूप रैंक पदों 13 से 0 (ताकि स्थिति 4 हम पहले मिल गया वास्तव में एक 3 हो जाएगा) आरंभिक क्रमांक। वापस बेस 10 में परिवर्तित (प्रयोजनों की जाँच के लिए), हमें 15 , 565 , 975 मिलते हैं । में 26५४ ए २३६ जे23456789 टीजेक्यू केए547131015 , 565 , 97526बाइनरी के बिट हमें ।00111011011000010010010111
डीकोडर बहुत समान तरीके से काम करता है। यह (उदाहरण के लिए) बिट्स के स्ट्रिंग को लेता है और इसे दशमलव (बेस 10) में 15 , 565 , 975 पर वापस पहुंचाता है , फिर इसे ऑफ़सेट लुकअप स्ट्रिंग में ऑफ़सेट प्राप्त करने के लिए बेस 13 में परिवर्तित करता है , फिर यह रैंक को फिर से संगठित करता है। एक समय में एक और मूल 54 ए 236 जे पहले 7 कार्ड प्राप्त करता है। ध्यान दें कि बिट्स का अवरोधन हमेशा 26 नहीं होगा, लेकिन हमेशा प्रत्येक डेक में 26 पर शुरू होगा। एनकोडर और डिकोडर दोनों के संचालन से पहले ही डेक डेटा के बारे में कुछ महत्वपूर्ण जानकारी होती है। यह इस एल्गोरिथ्म के बारे में असाधारण अच्छी बात है।2615 , 565 , 97513५४ ए २३६ जे7
शेष रैंकों से प्रत्येक # (जैसे अपनी ही groupsize और लागत (प्रति कार्ड बिट्स की #) है। ये प्रायोगिक तौर पर सिर्फ 13 , 12 , 11 ... और 2 की शक्तियों के साथ खेल रहे थे । मैंने पहले ही बताया कि 13 समूहों को देखने के लिए मुझे समूह कैसे मिला , इसलिए जब हम 12 अपूर्ण रैंक पर जाते हैं, तो कैसे करें ? एक ही विधि। 12 की शक्तियों को देखें और रोकें जब उनमें से एक 2 की शक्ति के बहुत करीब आती है, लेकिन बस इसके नीचे थोड़ा सा। 13 , 12 , 11 । । । , 2 , 1 )13 , 12 , 11 ...21312122 = 248 , 832 और 2 18 = 262 , 144 । यह एक बहुत तंग फिट है। इस समूह एन्कोडिंग बिट्स की संख्या है 18 / 5 = 3.6 । में 13 रैंक समूह यह था 26 / 7 = 3.714 इतनी के रूप में आप देख सकते हैं, रिक्त रैंकों की संख्या कम हो जाती है (रैंक भरने कर रहे हैं जैसे 5555 , 3333 ), बिट्स की संख्या कार्ड एन्कोड करने के लिए कम हो जाती है।125२४ , 32३२218262 , 144१ / ५3.613२६ / 73.71455553333
यहाँ मेरी सभी संभावित रैंक के लिए लागतों की पूरी सूची (# बिट्स प्रति कार्ड) देखी जा सकती है:
12 18 / 5 = 3.600 = 3 3 / 5 11 7 / 2 = 3.500 = 3 1 / 2 10 10 / 3 = 3.333 = 3 1 / 3 9 16 / 5 = 3.200 = 3 1 / 5 8 3 / 113 26 / 7 = 3.714 = 3 5 / 7
12 18 / 5 = 3.600 = 3 3 / 5
11 7 / 2 = 3.500 = 3 1 / 2
10 10 / 3 = 3.333 = 3 1 / 3
९ १६ / ५ = ३.२०० = ३ १ / ५
7 17 / 6 = 2.833 = 2 5 / 6 6 13 / 5 = 2.600 = 2 3 / 5 5 7 / 3 = 2.333 = 2 1 / 3 4 2 / 1 = 2.000 = 2 3 5 / 3 = 1.667 = 1 2 / 3 2 1 / 8 3 / 1 = 3.000 = 3
7 17 / 6 = 2.833 = 2 5 / 6
६ १३ / ५ = २.६०० = २ ३ / ५
५ 5 / ३ = २.३३३ = २ १ / ३
4 2 / 1 = 2.000 = 2
3 5 / 3 = 1.667 = 1 2 / 3
1 0 / 1..4 = 0.0 = 0 2 1 / 1 = 1.000 = 1
1 0 / 1..4 = 0.0 = 0
तो जैसा कि आप स्पष्ट रूप से देख सकते हैं, जैसा कि अनफिल्ड रैंक की संख्या घट जाती है (जो कि यह हर डेक करेगा), प्रत्येक कार्ड को एनकोड करने के लिए आवश्यक बिट्स की संख्या भी घट जाती है। आप सोच रहे होंगे कि अगर हम रैंक भरते हैं तो क्या होता है लेकिन हम अभी तक एक ग्रुप में नहीं हैं। उदाहरण के लिए, यदि डेक में पहले कार्ड 5 , 6 , 7 , 7 , 7 , 7 , K थे , तो हमें क्या करना चाहिए? आसान, कश्मीर सामान्य रूप से से एनकोडर छोड़ देगी 13 को रैंक एन्कोडिंग मोड 12 रैंक एन्कोडिंग मोड। हालाँकि, चूंकि हमने अभी तक 13 में 7 कार्ड का पहला ब्लॉक नहीं भरा है75 , 6 , 7 , 7 , 7 , 7 , केक1312713रैंक एन्कोडिंग मोड, हम इसे पूरा करने के लिए को उस ब्लॉक में शामिल करते हैं । इस तरह बहुत कम बर्बादी होती है। ऐसे मामले भी हैं जब हम एक ब्लॉक को भरने की कोशिश कर रहे हैं, भरे हुए रैंकों का # 2 या उससे अधिक तक उछल जाता है । यह भी कोई समस्या नहीं है क्योंकि हम सिर्फ वर्तमान एन्कोडिंग मोड में ब्लॉक को भरते हैं, तो हम नए एन्कोडिंग मोड में उठाते हैं जो 1 , 2 , 3 हो सकता है ... कम या एक ही मोड में रहना (जैसा कि मामला था) डेटाफ़िले में पहले डेक में 13 रैंक एन्कोडिंग मोड में 3 पूर्ण ब्लॉक हैं )। यही कारण है कि आकार 1 और 7 के बीच के रूप में ब्लॉक को उचित बनाना महत्वपूर्ण हैक21 , 2 , 3 ...31317। यदि हमने उदाहरण के लिए इसका आकार बनाया है , तो हमें उस ब्लॉक को एक उच्च बिटरेट पर भरना होगा, यदि हम एनकोडर को एक अधिक कुशल एन्कोडिंग मोड (कम रैंक एन्कोडिंग) में परिवर्तित करते हैं।20
जब मैंने डेटा फ़ाइल में कार्ड के पहले डेक पर इस एल्गोरिथ्म (हाथ से) को चलाया था (जो फिशर-येट्स निष्पक्ष शफ़ल का उपयोग करके बनाया गया था), मुझे एक प्रभावशाली बिट्स मिलाया गया था जो कि सांकेतिक शब्दों में बाइनरी एन्कोडिंग के लगभग समान है लेकिन नहीं सभी संभावित डेक के क्रमिक पदों का ज्ञान, कोई बहुत बड़ी संख्या और कोई बाइनरी खोज नहीं। हालांकि इसके लिए बाइनरी मैनिपुलेशन की आवश्यकता होती है और साथ ही रेडिक्स मैनिपुलेशन ( 13 , 12 , 11 ... की शक्तियां )।16813 , 12 , 11
10777748747रों। यदि डेक एक जोड़ी (जैसे 77), ट्रिपल / सेट (जैसे 777) या एक क्वाड (जैसे 7777) पर समाप्त होता है, तो मुझे अपने एल्गोरिथ्म का उपयोग करके उस डेक के लिए अतिरिक्त बचत मिलती है।
3222613163232
डेटाफ़ाइल में पहले डेक में, कार्ड की एन्कोडिंग इस प्रकार है (बाद में आने के लिए आरेख)। प्रारूप (समूहबद्ध, बिट्स, रैंक एनकोड मोड) है:
7,26,1372613
7,26,13
7,26,13
5,18,12
5,18,12
3,10,10
3, 9, 8
6,17, 7
5,13, 6
3, 5, 3
1, 0, 1
521683.23
181/33.23.254545454722772277...322223333444455556666777788889999TTTTJJJJQQQQKKKKAAAA40
1103,7K8101कार्ड शेष है। यह महत्वपूर्ण है क्योंकि यह एन्कोडिंग प्रक्रिया को अधिक कुशल बनाता है जब डिकोडर इसके बिना अतिरिक्त संदेश पास किए एनकोडर के बिना सही अनुमान लगा सकता है।
313121110
26 26 26 18 18 10 9 17 13 5 0
54A236J 87726Q3 3969AAA QJK7T 9292Q 36K J57 T8TKJ4 48Q8T 55K 4
13 12 xy 98 7 6 543 2 1 0
2166175168बिट्स। ध्यान दें कि हमें डेक के अंत में केवल एक ही 4 मिला था, लेकिन अगर हमें वहां सभी चार 4s मिले, तो यह एक बेहतर मामला है और हमें उस डेक को एनकोड करने के लिए केवल 161 बिट्स की आवश्यकता होगी, एक ऐसा मामला जहां पैकिंग वास्तव में पूरी होती है एक सीधे द्विआधारी का एन्ट्रापी, उस की क्रमिक स्थिति का सांकेतिक शब्दों में बदलना।
मेरे पास अब बिट आवश्यकताओं की गणना करने के लिए लागू किया गया कोड है और यह मुझे औसतन दिखा रहा है, प्रति 155 के निचले हिस्से के साथ 175 बिट्स प्रति डेक और 3 मिलियन डेक टेस्ट फाइल के लिए 183 का उच्च। तो मेरा एल्गोरिथ्म प्रति डेक 9 अतिरिक्त बिट्स का उपयोग करने लगता है। क्रमिक स्थिति विधि के सीधे बाइनरी एनकोड। केवल 5.5% अतिरिक्त संग्रहण स्थान पर बहुत बुरा नहीं है। 176 बिट्स 22 बाइट्स है, जो कि 52 बाइट्स प्रति डेक से काफी बेहतर है। बेस्ट केस डेक (3 मिलियन डेक टेस्ट फाइल में नहीं दिखा) 136 बिट्स और सबसे खराब केस डेक पर पैक (टेस्ट में 8206 बार शो किया गया), 183 बिट्स है। विश्लेषण से पता चलता है कि सबसे खराब स्थिति तब होती है, जब हमें कार्ड के पास (या) 40 तक पहला क्वाड नहीं मिलता है। तब जैसे ही एन्कोड मोड जल्दी से गिरना चाहता है, हम "स्टैक्ड" फिलिंग ब्लॉक (7 कार्ड जितना बड़ा) कर देते हैं। उच्च बिट एन्कोडिंग मोड। कोई सोच सकता है कि कार्ड ४० तक कोई भी क्वैड नहीं मिल रहा है, एक अच्छी तरह से कटा हुआ डेक का उपयोग करना काफी दुर्लभ होगा, लेकिन मेरा कार्यक्रम मुझे बता रहा है कि ३२ मिलियन डेक के टेस्टफाइल में ३२१ बार ऐसा हुआ है कि यह प्रत्येक ९ ३४६ में से १ डेक के बारे में है। यह अधिक बार है कि मुझे उम्मीद होगी। मैं इस मामले की जाँच कर सकता था और इसे कम बिट्स के साथ संभाल सकता था लेकिन यह इतना दुर्लभ है कि यह औसत बिट्स को पर्याप्त प्रभावित नहीं करेगा।
यहाँ भी कुछ और बहुत दिलचस्प है। यदि मैं कच्चे डेक डेटा पर डेक को सॉर्ट करता हूं, तो एक महत्वपूर्ण # बार उपसर्ग की लंबाई केवल लंबाई 6 (जैसे 222244) के बारे में है। हालाँकि पैक किए गए डेटा के साथ, यह लंबाई लगभग 16 तक बढ़ जाती है। इसका मतलब है कि अगर मैं पैक किए गए डेटा को सॉर्ट करता हूं, तो मुझे डिकोडर को 16 बिट उपसर्ग का संकेत देकर एक महत्वपूर्ण बचत प्राप्त करने में सक्षम होना चाहिए और फिर डेक के शेष हिस्से को आउटपुट करना चाहिए। (दोहराव पूर्व उपसर्ग) जिसमें वही उपसर्ग है, फिर अगले उपसर्ग पर जाएं और दोहराएं। मुझे लगता है कि मैं इस तरह भी डेक प्रति 10 बिट्स को बचाने के लिए, मैं प्रति डेक 166 बिट्स को हरा देना चाहिए। दूसरों द्वारा बताई गई गणना तकनीक के साथ, मुझे यकीन नहीं है कि उपसर्ग मेरे एल्गोरिथ्म के रूप में लंबे समय तक होगा। मेरे एल्गोरिथ्म का उपयोग करते हुए पैकिंग और अनपैकिंग गति आश्चर्यजनक रूप से अच्छी है।
संपीड़न के दूसरे स्तर के बारे में जहां मैं अपने एल्गोरिथ्म के आउटपुट बिटस्ट्रिंग्स को सॉर्ट करता हूं, फिर "अंतर" एन्कोडिंग का उपयोग करता हूं: 61,278 अद्वितीय 16 बिट उपसर्गों को एनकोड करने के लिए एक बहुत ही सरल विधि होगी जो आउटपुट डेटा (डेटा और अधिकतम में कम से कम दो बार दिखाती है) 89 बार रिपोर्ट की गई) आउटपुट में 0 के एक अग्रणी बिट के रूप में 2 लेवल डीकंप्रेसर को इंगित करने के लिए कि हम एक उपसर्ग (जैसे 0000111100001111) को एन्कोडिंग कर रहे हैं और फिर उसी उपसर्ग के साथ किसी भी पैक किए गए डेक 1 अग्रणी बिट के साथ अनुसरण करेंगे। पैक्ड डेक के गैर उपसर्ग भाग को इंगित करें। एक ही उपसर्ग के साथ पैक किए गए डेक का औसत # प्रत्येक उपसर्ग के लिए लगभग 49 है, न कि कुछ ऐसे हैं जो अद्वितीय हैं (केवल 1 डेक में उस विशेष उपसर्ग है)। ऐसा प्रतीत होता है कि मैं इस सरल रणनीति का उपयोग करके प्रति डेक लगभग 15 बिट्स बचा सकता हूं (एक बार आम उपसर्गों को संग्रहीत करना)।
पहले एनकोडर के सॉर्ट किए गए बिटस्ट्रिंग आउटपुट के अंतर (उपसर्ग) एन्कोडिंग का उपयोग करके संपीड़न के दूसरे स्तर के बाद, मैं अब प्रति डेक लगभग 160 बिट्स प्राप्त कर रहा हूं। मैं लंबाई 18 उपसर्ग का उपयोग करता हूं और बस इसे बरकरार रखता हूं। चूंकि उन संभावित 18 बिट उपसर्गों में से लगभग सभी (245013 262144 = 93.5% में से) दिखाते हैं, इसलिए उपसर्गों को एनकोड करना और भी बेहतर होगा। शायद मैं 2 बिट्स का उपयोग यह बता सकता हूं कि मेरे पास किस प्रकार का डेटा है। 00 = नियमित लंबाई 18 उपसर्ग संग्रहीत, 01 = "1 अप उपसर्ग" (पिछले जोड़े के अलावा पिछले उपसर्ग के रूप में), 11 = 1 स्तर पैकिंग से औसत एन्कोडिंग (लगभग औसतन 175 बिट्स)। 10 = भविष्य का विस्तार जब मैं कुछ और सोचने के लिए सांकेतिक शब्दों में बदलना होगा जो बिट्स को बचाएगा।
क्या किसी और ने 160 बिट प्रति डेक को हराया? मुझे लगता है कि मैं कुछ प्रयोग करके और ऊपर वर्णित 2 बिट डिस्क्रिप्टर का उपयोग करके मुझे थोड़ा कम प्राप्त कर सकता हूं। शायद यह 158ish पर नीचे होगा। मेरा लक्ष्य इसे 156 बिट्स (या बेहतर) प्राप्त करना है क्योंकि यह 3 बिट प्रति कार्ड या उससे कम होगा। बहुत प्रभावशाली। इसे उस स्तर पर लाने के लिए बहुत सारे प्रयोग किए जा रहे हैं क्योंकि अगर मैं पहले स्तर की एन्कोडिंग को बदल देता हूं तो मुझे फिर से परीक्षा देनी होगी जो कि सर्वश्रेष्ठ द्वितीय स्तर की एन्कोडिंग है और कोशिश करने के लिए कई संयोजन हैं। मेरे द्वारा किए गए कुछ बदलाव अन्य समान यादृच्छिक डेटा के लिए अच्छे हो सकते हैं, लेकिन कुछ इस डेटासेट के लिए पक्षपाती हो सकते हैं। वास्तव में निश्चित नहीं है, लेकिन अगर मुझे आग्रह मिलता है तो मैं एक और 3 मिलियन डेक डेटासेट की कोशिश कर सकता हूं कि यह देखने के लिए कि क्या होता है अगर मुझे इस पर समान परिणाम मिलते हैं।
1050
क्या किसी के पास अपने एल्गोरिथ्म को बेहतर बनाने के बारे में कोई विचार है जैसे कि अन्य मामलों में मुझे क्या करना चाहिए जो औसतन प्रत्येक डेक के लिए भंडारण के बिट्स को कम करेगा? किसी को?
2 और बातें: 1) मुझे कुछ हद तक निराशा हुई है कि अधिक लोगों ने मेरे समाधान को बढ़ावा नहीं दिया, जो कि अंतरिक्ष पर इष्टतम नहीं है, फिर भी लागू करने के लिए सभ्य और काफी आसान है (मुझे मेरा काम ठीक लगा)। 2) मैंने अपने 3 मिलियन डेक डेटाफाइल पर विश्लेषण किया और देखा कि सबसे अधिक बार होने वाला कार्ड जहां पहली रैंक भरता है (जैसे कि 4444) कार्ड 26 पर है। यह लगभग 6.711% समय के लिए होता है (3 डी डेक के 201322 के लिए) )। मैं इस जानकारी का उपयोग करने की उम्मीद कर रहा था, जैसे कि 12 सिंबल एन्कोड मोड में स्टार्ट आउट, क्योंकि हम जानते हैं कि औसतन हम हर रैंक को मिडकॉक तक नहीं देखते हैं, लेकिन यह तरीका किसी भी तरह से कंप्रेस करने में विफल रहा क्योंकि इसमें बचत बचत से अधिक हो गई। मैं अपने एल्गोरिथ्म के लिए कुछ ट्विक्स की तलाश कर रहा हूं जो वास्तव में बिट्स को बचा सकता है।
तो क्या किसी के पास कोई विचार है जो मुझे अपने एल्गोरिथ्म का उपयोग करके प्रति डेक कुछ बिट्स को बचाने के लिए आगे की कोशिश करनी चाहिए? मैं एक पैटर्न की तलाश कर रहा हूं जो अक्सर पर्याप्त होता है ताकि मैं डिकोडर को अतिरिक्त ओवरहेड बताने के बाद भी बिट्स को प्रति डेक कम कर सकूं कि क्या पैटर्न की उम्मीद है। मैं शेष अनदेखी कार्डों की अपेक्षित संभावनाओं के साथ कुछ सोच रहा था और सभी एकल कार्ड शेष लोगों को एक ही बाल्टी में लाद रहा था। यह मुझे एक कम एनकोड मोड में जल्दी छोड़ने की अनुमति देगा और शायद कुछ बिट्स को बचाएगा लेकिन मुझे इसमें संदेह है।
इसके अलावा, FYI करें, मैंने 10 मिलियन यादृच्छिक फेरबदल उत्पन्न किए और उन्हें आसान विश्लेषण के लिए डेटाबेस में संग्रहीत किया। उनमें से केवल 488 एक क्वाड में समाप्त होते हैं (जैसे 5555)। अगर मैं सिर्फ अपने एल्गोरिथ्म का उपयोग करने वालों को पैक करता हूं, तो मुझे 157 बिट्स के साथ औसतन 165.71712 बिट्स और 173 बिट्स का एक उच्च स्तर मिलता है। अन्य एन्कोडिंग विधि का उपयोग करके 166 बिट्स से थोड़ा नीचे। मुझे इस बात पर कुछ आश्चर्य हुआ कि यह मामला कितना निरापद है (औसतन हर 20,492 फेरबदल में से लगभग 1)।