क्या रैंडम सूटलेस प्लेइंग कार्ड डेटा को एप्रोच, मैच, या यहां तक ​​कि एन्ट्रापी एन्कोडिंग स्टोरेज को हरा दिया जा सकता है? यदि हां, तो कैसे?


19

मेरे पास असली डेटा है जो मैं एक नकली कार्ड गेम के लिए उपयोग कर रहा हूं। मुझे केवल कार्डों के रैंक में दिलचस्पी है, न कि सूटों पर। हालाँकि यह एक मानक कार्ड डेक है इसलिए डेक में प्रत्येक रैंक के केवल ही संभव हैं। प्रत्येक हाथ के लिए डेक को अच्छी तरह से हिलाया जाता है, और फिर मैं पूरे डेक को एक फ़ाइल में आउटपुट करता हूं। तो आउटपुट फ़ाइल में केवल संभावित प्रतीक हैं जो । ( = दस रैंक)। तो निश्चित रूप से हम इन का उपयोग कर सकते हैं bitpack प्रतीक बिट्स प्रति है, लेकिन फिर हम बर्बाद कर रहे की संभव एन्कोडिंग। हम बेहतर कर सकते हैं यदि हम एक बार में प्रतीकों को समूहित करें , और फिर उन्हें संकुचित करें, क्योंकि524132,3,4,5,6,7,8,9,T,J,Q,K,AT43164134 = २ और वह बजाय बिट्स में "स्नगली" फिट कर सकता है । सैद्धांतिक बिटपैकिंग सीमा प्रत्येक संभावित कार्ड के लिए यादृच्छिक प्रतीकों के साथ डेटा के लिए लॉग ( ) / लॉग ( ) = । हालाँकि इस डेक में उदाहरण के लिए हमारे पास राजा नहीं हो सकते । हमारे पास प्रत्येक डेक में प्रत्येक रैंक के केवल इसलिए एन्ट्रापी एन्कोडिंग लगभग प्रति प्रतीक से लगभग गिरता है ।28,56115161323.70044135243.2

ठीक है, तो यहाँ मैं क्या सोच रहा हूँ। यह डेटा पूरी तरह से यादृच्छिक नहीं है। हम जानते हैं कि देखते हैं प्रत्येक रैंक के के प्रत्येक ब्लॉक में तो कार्ड (यह एक shuffled डेक कहते हैं), तो हम कई मान्यताओं और अनुकूलन कर सकते हैं। उनमें से एक होने के नाते हमें बहुत अंतिम कार्ड को सांकेतिक शब्दों में बदलना नहीं है, क्योंकि हमें पता चल जाएगा कि यह क्या होना चाहिए। एक और बचत होगी यदि हम एक ही रैंक पर समाप्त होते हैं; उदाहरण के लिए, यदि डेक में अंतिम कार्ड , तो हमें उन्हें एनकोड नहीं करना पड़ेगा क्योंकि डिकोडर उस बिंदु तक कार्ड की गिनती करेगा और देखेगा कि अन्य सभी रैंक भर गए हैं, और मान लेंगे " लापता "कार्ड सभी एस हैं।452377737

तो इस साइट पर मेरा प्रश्न यह है कि इस प्रकार के डेटा पर और भी छोटी आउटपुट फ़ाइल प्राप्त करने के लिए अन्य अनुकूलन क्या संभव हैं, और यदि हम उनका उपयोग करते हैं, तो क्या हम कभी भी प्रति प्रतीक बिट्स की सैद्धांतिक (सरल) बिटकॉइन एंट्री को हरा सकते हैं , या यहां तक ​​कि औसत प्रति प्रतीक लगभग बिट्स की अंतिम एन्ट्रापी सीमा तक पहुंचते हैं ? यदि हां, तो कैसे?3.700443.2

जब मैं एक ज़िप टाइप प्रोग्राम (उदाहरण के लिए WinZip) का उपयोग करता हूं, तो मैं केवल एक संपीड़न के बारे में देखता हूं , जो मुझे बताता है कि यह सिर्फ बिट्स के लिए "आलसी" बिटपैक कर रहा है । यदि मैं अपने स्वयं के बिटपैकिंग का उपयोग करके डेटा को "पूर्व-संपीड़ित" करता हूं, तो यह उस तरह से बेहतर लगता है, क्योंकि तब जब मैं एक ज़िप प्रोग्राम के माध्यम से चलाता हूं, तो मुझे संपीड़न पर थोड़ा सा मिल रहा है । मैं जो सोच रहा हूं, वह सभी संपीड़न खुद क्यों नहीं करते हैं (क्योंकि मुझे जिप प्रोग्राम की तुलना में डेटा का अधिक ज्ञान है)। मैं सोच रहा हूं कि क्या मैं लॉग ( ) / लॉग ( ) = की एन्ट्रापी "सीमा" को हरा सकता2:142:11323.70044। मुझे लगता है कि मैं कुछ "चाल" के साथ उल्लेख कर सकता हूं और कुछ और जो मुझे पता चल सकता है। पाठ्यक्रम की आउटपुट फ़ाइल को "मानव पठनीय" होना जरूरी नहीं है। जब तक एन्कोडिंग दोषरहित है तब तक यह मान्य है।

यहाँ मिलियन मानव पठनीय फेरबदल डेक ( प्रति पंक्ति) की एक कड़ी है । कोई भी इन पंक्तियों के एक छोटे उपसमुच्चय पर "अभ्यास" कर सकता है और फिर इसे पूरी फाइल पर रिप करने देता है। मैं इस डेटा के आधार पर अपनी सर्वश्रेष्ठ (सबसे छोटी) फाइलों को अपडेट करता रहूंगा।31

https://drive.google.com/file/d/0BweDAVsuCEM1amhsNmFITnEwd2s/view

वैसे, यदि आप रुचि रखते हैं कि इस डेटा का उपयोग किस प्रकार के कार्ड गेम के लिए किया जाता है, तो यहां मेरे सक्रिय प्रश्न ( बिंदु बाउंटी के साथ) का लिंक है । मुझे बताया जा रहा है कि इसे (वास्तव में) हल करना एक कठिन समस्या है क्योंकि इसके लिए भारी मात्रा में डेटा स्टोरेज स्पेस की आवश्यकता होगी। कई सिमुलेशन हालांकि अनुमानित संभावनाओं से सहमत हैं। कोई विशुद्ध गणितीय समाधान प्रदान नहीं किया गया है (अभी तक)। यह बहुत मुश्किल है, मुझे लगता है।300

/math/1882705/probability-2-player-card-game-with-multiple-patterns-to-win-who-has-the-advant

मेरे पास एक अच्छा एल्गोरिथ्म है जो मेरे नमूना डेटा में पहले डेक को एनकोड करने के लिए बिट्स दिखा रहा है । फिशर-येट्स फेरबदल एल्गोरिदम का उपयोग करके यह डेटा बेतरतीब ढंग से उत्पन्न किया गया था। यह वास्तविक यादृच्छिक डेटा है, इसलिए मेरा नया बनाया एल्गोरिथ्म बहुत अच्छी तरह से काम कर रहा है, जो मुझे खुश करता है।168

संपीड़न "चुनौती" के बारे में, मैं वर्तमान में लगभग 160 बिट्स प्रति डेक पर हूं। मुझे लगता है कि मैं शायद 158 पर जा सकता हूं। हां मैंने कोशिश की और मुझे प्रति डेक 158.43 बिट्स मिले। मुझे लगता है कि मैं अपने एल्गोरिथ्म की सीमा के करीब पहुंच रहा हूं, इसलिए मैं प्रति डेक 166 बिट्स से नीचे जाने में सफल रहा लेकिन मैं 156 बिट्स प्राप्त करने में विफल रहा जो कि 3 बिट प्रति कार्ड होगा लेकिन यह एक मजेदार अभ्यास था। शायद भविष्य में मैं प्रत्येक डेक को औसतन 2.43 बिट्स या अधिक से कम करने के लिए कुछ सोचूंगा।


8
यदि आप इन फेरबदल वाले डेक को स्वयं उत्पन्न कर रहे हैं (उदाहरण के लिए, कार्ड के भौतिक डेक की स्थिति का वर्णन करने के बजाय), तो आपको डेक को स्टोर करने की आवश्यकता नहीं है - बस उस आरएनजी बीज को स्टोर करें जिसने डेक उत्पन्न किया।
jasonharper

3
आपका विवरण और उन उत्तरों की अवधारणा बहुत समान है, जिन्हें आमतौर पर रेंज एन्कोडिंग ( en.wikipedia.org/wiki/Range_encoding ) के रूप में जाना जाता है । आप प्रत्येक कार्ड के बाद समर्थताओं को अनुकूलित करते हैं, इसलिए यह शेष संभावित कार्ड को दर्शाता है।
एच। आइडेन

टिप्पणियाँ विस्तारित चर्चा के लिए नहीं हैं; इस वार्तालाप को बातचीत में स्थानांतरित कर दिया गया है ।
गिल्स एसओ- बुराई को रोकना '

जवाबों:


3

एक और बात पर विचार करें: यदि आप केवल कई मिलियन डेक के पूर्ण सेट को संपीड़ित करने के बारे में परवाह करते हैं और आप इस बात की परवाह नहीं करते हैं कि वे किस क्रम में हैं, तो आप डेक के सेट के आदेश के बारे में जानकारी को त्यागकर अतिरिक्त एन्कोडिंग लचीलापन प्राप्त कर सकते हैं। । उदाहरण के लिए, यदि आपको सभी डेक को एन्यूमरेट करने और उन्हें प्रोसेस करने के लिए सेट को लोड करने की आवश्यकता है, तो यह मामला होगा, लेकिन इस बात की परवाह नहीं करें कि उन्हें किस क्रम में संसाधित किया गया है।

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

मैं दुर्भाग्य से गणित को नहीं जानता कि यह आपके संपीड़न में कितना मदद करेगा, लेकिन यह विचार विचार करने के लिए उपयोगी हो सकता है।


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

2
@ डेविडजैम: यदि डेक का विशिष्ट क्रम महत्वपूर्ण नहीं है, बस इसमें कोई पक्षपात नहीं है, तो आप विघटन के बाद 3 मिलियन डेक को फिर से फेरबदल कर सकते हैं (अर्थात किसी भी डेक को नहीं बदलते हैं, बस क्रम को बदलें 3 मिलियन डेक की सूची)।
स्टीव जेसप

2
यह सूचना सामग्री को थोड़ा और कम करने का एक तरीका है अगर आदेश देने वाली जानकारी महत्वपूर्ण नहीं है; यदि यह महत्वपूर्ण है, तो यह लागू नहीं है और इसे अनदेखा किया जा सकता है। उस ने कहा, अगर डेक के सेट के आदेश के लिए एकमात्र महत्व यह है कि यह 'यादृच्छिक' है, तो आप केवल डिकम्प्रेसन के बाद ऑर्डर को यादृच्छिक कर सकते हैं, जैसा कि @SteveJessop ने कहा है।
डैन ब्रायंट

@DavidJames यह देखते हुए कि आपके डेक का पहला 173 KKKK से शुरू होता है, और अन्य कई मिलियन को नहीं देखता है, और यह निष्कर्ष निकालता है कि वे सभी KKKK से शुरू करते हैं, एक बहुत ही बेवकूफाना काम है। खासकर यदि वे स्पष्ट रूप से क्रमबद्ध क्रम में हों।
user253751

3
@DavidJames: यह डेटा संपीड़ित है, और विघटनकारी दिनचर्या यदि चाहें तो इसे फिर से यादृच्छिक कर सकती है। "कुछ भोले-भाले व्यक्ति" को कुछ भी नहीं मिलने वाला है, वे यह भी पता लगाने नहीं जा रहे हैं कि इसे कार्ड के डेक के रूप में कैसे समझा जाए। यह डेटा भंडारण प्रारूप (इस मामले में एक हानिपूर्ण प्रारूप) में कोई दोष नहीं है, कि इसका उपयोग करने वाले किसी व्यक्ति को सही डेटा प्राप्त करने के लिए आरटीएफएम की आवश्यकता होती है।
स्टीव जेसोप

34

यहां एक पूर्ण एल्गोरिथ्म है जो सैद्धांतिक सीमा तक पहुंचता है।

प्रस्तावना: पूर्णांक अनुक्रम एन्कोडिंग

एक 13 पूर्णांक अनुक्रम "ऊपरी सीमा के साथ पूर्णांक ऊपरी सीमा के साथ, पूर्णांक ," ऊपरी सीमा के साथ पूर्णांक , ऊपरी सीमा के साथ पूर्णांक , ... साथ पूर्णांक ऊपरी सीमा " हमेशा सही दक्षता के साथ कोडित किया जा सकता है।बी - सी - डी - a1b1c1d1m1

  1. पहले पूर्णांक को लें, इसे गुणा करें, दूसरे को जोड़ें, द्वारा परिणाम को गुणा करें, तीसरे को जोड़ें, परिणाम को गुणा करें, ... परिणाम को गुणा करें , तेरहवां जोड़ें - और वह एक अद्वितीय संख्या उत्पन्न करेगा। और ।c d m 0 a b c d e f g h i j k l m - 1bcdm0abcdefghijklm1
  2. उस नंबर को बाइनरी में लिखें।

रिवर्स आसान भी है। विभाजित करें और शेष तेरहवें पूर्णांक है। परिणाम को विभाजित करें और शेष बारहवां पूर्णांक है। तब तक ले जाएँ जब तक आप विभाजित नहीं हो जाते : शेष दूसरा पूर्णांक है और भागफल पहला पूर्णांक है।एल बीmlb

तो अपने कार्ड को सर्वोत्तम संभव तरीके से कोड करने के लिए, हमें केवल 13-पूर्णांक अनुक्रमों (दी गई ऊपरी सीमाओं के साथ) और आपके फेरबदल कार्ड की व्यवस्था के बीच एक परिपूर्ण पत्राचार करना होगा।

यहां है कि इसे कैसे करना है।

फेरबदल और पूर्णांक अनुक्रमों के बीच पत्राचार

आपके सामने मेज पर 0 कार्ड के अनुक्रम से शुरू करें।

चरण 1

अपने पैक में चार 2 एस लें और उन्हें टेबल पर रखें।

आपके पास क्या विकल्प हैं? एक कार्ड या कार्ड या तो पहले से ही मेज पर अनुक्रम की शुरुआत में रखा जा सकता है, या उस क्रम में कार्ड में से किसी एक के बाद। उस स्थिति में, इसका मतलब है कि कार्ड लगाने के लिए संभावित स्थान हैं।1+0=1

1 स्थान पर 4 कार्ड रखने के तरीकों की कुल संख्या । उन तरीकों में से प्रत्येक को और बीच की संख्या के रूप में एनकोड करें । 1 ऐसी संख्या है।0 1 - 11011

मुझे 5 पूर्णांक के योग के रूप में 0 लिखने के तरीकों पर विचार करने से 1 मिला: यह ।4×3×2×14!

चरण 2

अपने पैक में चार 3 एस लें और उन्हें टेबल पर रखें।

आपके पास क्या विकल्प हैं? एक कार्ड या कार्ड या तो पहले से ही मेज पर अनुक्रम की शुरुआत में रखा जा सकता है, या उस क्रम में कार्ड में से किसी एक के बाद। उस स्थिति में, इसका मतलब है कि कार्ड लगाने के लिए संभावित स्थान हैं।1+4=5

5 जगहों पर 4 कार्ड रखने के तरीकों की कुल संख्या । उन तरीकों में से प्रत्येक को और बीच की संख्या के रूप में । ऐसे 70 नंबर हैं।0 70 - 1700701

मैंने ५ पूर्णांक के योग के रूप में ४ लिखने के तरीकों पर विचार करके the० प्राप्त किया: यह by ५ ।8×7×6×54!

चरण 3

अपने पैक में चार 4s लें और उन्हें टेबल पर रखें।

आपके पास क्या विकल्प हैं? एक कार्ड या कार्ड या तो पहले से ही मेज पर अनुक्रम की शुरुआत में रखा जा सकता है, या उस क्रम में कार्ड में से किसी एक के बाद। उस स्थिति में, इसका मतलब है कि कार्ड लगाने के लिए संभावित स्थान हैं।1+8=9

9 स्थानों में 4 कार्ड रखने के तरीकों की कुल संख्या । उन तरीकों में से प्रत्येक को और बीच की संख्या के रूप में । ऐसी संख्या 495 है।49504951

मुझे 8 लिखने के तरीकों पर विचार करके 495 मिला है 5 पूर्णांक के योग के रूप में: यह ।12×11×10×94!

और इतने पर, जब तक ...

चरण 13

अपने पैक में चार इक्के लें और उन्हें टेबल पर रखें।

आपके पास क्या विकल्प हैं? एक कार्ड या कार्ड या तो पहले से ही मेज पर अनुक्रम की शुरुआत में रखा जा सकता है, या उस क्रम में कार्ड में से किसी एक के बाद। उस स्थिति में, इसका मतलब है कि कार्ड लगाने के लिए संभावित स्थान हैं।1+48=49

49 स्थानों में 4 कार्ड रखने के तरीकों की कुल संख्या । उन तरीकों में से प्रत्येक को और बीच संख्या के रूप में । ऐसी संख्या में 270725 हैं।27072502707251

मुझे ५ 270 पूर्णांक के योग के रूप में ४ 270 लिखने के तरीकों पर विचार करके २ as० as२५ मिला है: यह _५० _ ।52×51×50×494!


यह प्रक्रिया पैदावार के बीच एक 1 से 1 पत्राचार (क) कार्ड जहां सूट और (ख) पूर्णांकों के दृश्यों जहां पहले के बीच है के बारे में परवाह नहीं है की shufflings और , दूसरे के बीच है और , तीसरा और बीच है , और इसी तरह तेरहवें तक, जो और बीच है ।1 - 1 0 70 - 1 0 495 - 1 001107010495102707251

"एनकोडिंग पूर्णांक अनुक्रम" का उल्लेख करते हुए, आप देख सकते हैं कि पूर्णांक का ऐसा क्रम 1-1 पत्राचार में और बीच की संख्या के साथ है । यदि आप प्रत्येक पूर्णांक के "एक भाज्य द्वारा विभाजित उत्पाद" अभिव्यक्ति को देखते हैं ( जैसा कि प्रत्येक चरण के अंत में इटैलिक में वर्णित है ) तो आप देखेंगे कि इसका अर्थ है और बीच की संख्याएँ जो मेरे पिछले उत्तर ने दिखाया सबसे अच्छा संभव था।( 1 × 70 × 495 × × 270725 ) - 1 00(1×70×495××270725)10

52!(4!)131,

तो हमारे पास आपके फेरबदल कार्ड को संपीड़ित करने के लिए एक आदर्श तरीका है।


एल्गोरिथ्म

Precompute सभी 5 पूर्णांकों की राशि के रूप 0 लेखन, 5 पूर्णांकों का योग के रूप में 4 लेखन, 5 पूर्णांकों की राशि के रूप में 8 लेखन के के के तरीके की एक सूची, ... 5 पूर्णांकों की राशि के रूप में 48 लिखने की। सबसे लंबी सूची में 270725 तत्व हैं, इसलिए यह विशेष रूप से बड़ा नहीं है। (Precomputation कड़ाई से आवश्यक नहीं है क्योंकि आप प्रत्येक सूची को आसानी से और जब भी आवश्यकता हो, संश्लेषित कर सकते हैं: Microsoft QuickBasic के साथ प्रयास करना, यहां तक ​​कि 270725-तत्व सूची से गुजरना आंखें देख सकता था की तुलना में तेज था)

पूर्णांक के अनुक्रम में फेरबदल से प्राप्त करने के लिए:

2s कुछ भी योगदान नहीं करते हैं, तो चलो उन्हें अनदेखा करते हैं। 0 और 1-1 के बीच की संख्या लिखिए।

3s: पहले 3 से पहले कितने 2s हैं? दूसरे से पहले कितने? तीसरा? 4 य? 4 के बाद? उत्तर 5 पूर्णांक है जो स्पष्ट रूप से 4 तक जोड़ता है। इसलिए 5 पूर्णांक के अनुक्रम को अपने "लेखन 4 में 5 पूर्णांक" सूची के योग के रूप में देखें, और उस सूची में इसकी स्थिति नोट करें। यह 0 और 70-1 के बीच की एक संख्या होगी। नीचे लिखें।

द 4: पहले 4 से पहले कितने 2 या 3 हैं? दूसरे से पहले कितने? तीसरा? 4 य? 4 के बाद? इसका उत्तर 5 पूर्णांक है जो स्पष्ट रूप से 8 तक जोड़ते हैं। इसलिए 5 पूर्णांक के अनुक्रम को अपने "लेखन 8 में 5 पूर्णांक" सूची के योग के रूप में देखें, और उस सूची में इसकी स्थिति नोट करें। यह 0 और 495-1 के बीच की संख्या होगी। नीचे लिखें।

और इसी तरह, जब तक…

इक्के: पहले इक्का से पहले कितने गैर-इक्के कार्ड हैं? दूसरे से पहले कितने? तीसरा? 4 य? 4 के बाद? उत्तर 5 पूर्णांक है जो स्पष्ट रूप से 48 तक जुड़ता है। इसलिए 5 पूर्णांक के अनुक्रम को अपने "लेखन 48 में 5 पूर्णांक" सूची के योग के रूप में देखें, और उस सूची में इसकी स्थिति नोट करें। यह 0 और 270725-1 के बीच की संख्या होगी। नीचे लिखें।

आपने अब 13 पूर्णांक लिखे हैं। उन्हें (जैसा कि पहले बताया गया है) और बीच एक ही संख्या में एनकोड करें । उस नंबर को बाइनरी में लिखें। यह सिर्फ 166 बिट्स के तहत ले जाएगा।५२ !052!(4!)13

यह सबसे अच्छा संभव संपीड़न है, क्योंकि यह सूचना-सैद्धांतिक सीमा तक पहुंचता है।

अपघटन सीधा है: बड़ी संख्या से 13 पूर्णांकों के अनुक्रम पर जाएं, और फिर पहले से वर्णित कार्ड के अनुक्रम का निर्माण करने के लिए उनका उपयोग करें।


टिप्पणियाँ विस्तारित चर्चा के लिए नहीं हैं; इस वार्तालाप को बातचीत में स्थानांतरित कर दिया गया है ।
DW

यह समाधान मेरे लिए अधूरा है और अधूरा है। यह नहीं दिखाता है कि वास्तव में 166 बिट संख्या कैसे प्राप्त करें और इसे डेक में वापस डिकोड करें। मेरे लिए गर्भधारण करना बिल्कुल भी आसान नहीं है इसलिए मैं नहीं जानता कि इसे कैसे लागू किया जाए। आपका चरणबद्ध फॉर्मूला मूल रूप से सिर्फ को अलग करता है टुकड़ों में सूत्र जो वास्तव में मेरी बहुत मदद नहीं करता है। मुझे लगता है कि अगर आप कार्ड की व्यवस्था करने के 70 संभावित तरीकों के साथ चरण 2 के लिए एक आरेख या चार्ट बनाते हैं तो इससे मदद मिली होगी। आपका समाधान मेरे मस्तिष्क को स्वीकार करने और संसाधित करने के लिए बहुत सार है। मैं वास्तविक उदाहरण और चित्र पसंद करता हूं। १३52!/(4!13)13
डेविड जेम्स

23

प्रत्येक कार्ड को 3 या 4 बिट में अलग से एनकोड करने की कोशिश करने के बजाय, मेरा सुझाव है कि आप पूरे डेक की स्थिति को 166 बिट्स में एनकोड करें। जैसा कि मार्टिन कोचनस्की बताते हैं , सूटों की अनदेखी करने वाले कार्ड की संभव व्यवस्थाएं कम हैं, इसका मतलब है कि पूरे डेक की स्थिति को 166 बिट्स में संग्रहीत किया जा सकता है।2166

आप इस संपीड़न और विघटन को एक कुशल तरीके से, एल्गोरिदमिक रूप से कैसे करते हैं? मैं लेक्सिकोग्राफिक ऑर्डरिंग और बाइनरी सर्च का उपयोग करने का सुझाव देता हूं। यह आपको बड़े लुकअप टेबल या अन्य अवास्तविक मान्यताओं की आवश्यकता के बिना, कुशलतापूर्वक (अंतरिक्ष और समय दोनों में) संपीड़न और विघटन करने की अनुमति देगा।

अधिक विस्तार से: आइए डेक के असम्बद्ध प्रतिनिधित्व पर लेक्सोग्राफिक ऑर्डर का उपयोग करके डेक ऑर्डर करें, अर्थात, एक डेक को 22223333444455556666777788889999TTJJJJQQQKKKKAAAA की तरह एक स्ट्रिंग के रूप में असम्पीडित रूप में दर्शाया गया है; आप उन्हें लेक्सिकोग्राफिक ऑर्डर के अनुसार ऑर्डर कर सकते हैं। अब, मान लीजिए कि आपके पास एक ऐसी प्रक्रिया है जो डेक दी गई है , इससे पहले आने वाले डेक की संख्या (लेक्सिकोग्राफ़िक में) गिना जाता है। तब आप इस प्रक्रिया का उपयोग किसी डेक को संपीड़ित करने के लिए कर सकते हैं: एक डेक दिया गया है , आप संपीड़ित करें 166-बिट संख्या की गिनती डेक की संख्या है जो इसके पहले आती है और फिर उस नंबर को आउटपुट करती है। वह संख्या डेक का संकुचित प्रतिनिधित्व है।डीDD

विघटित करने के लिए, द्विआधारी खोज का उपयोग करें। एक नंबर को देखते हुए , आप सभी डेक के lexicographic क्रम में वें डेक को ढूंढना चाहते हैं । आप बाइनरी खोज की तर्ज पर एक प्रक्रिया का उपयोग करके ऐसा कर सकते हैं: एक डेक , से पहले डेक की संख्या की गणना करें , और तुलना करें । यह आपको बताएगा कि को समायोजित करना हैn D 0 D 0 n D 0nnD0D0nD0पहले या बाद में आने के लिए। मेरा सुझाव है कि आप प्रतीक को सही तरीके से प्राप्त करने का प्रयास करें: यदि आप 22223333444455556666777788889999TTTJJJJQQQKKKAAA की तरह एक स्ट्रिंग को पुनर्प्राप्त करना चाहते हैं, तो स्ट्रिंग में पहले प्रतीक के रूप में उपयोग करने के लिए खोजें (केवल सभी 12 संभावनाओं की कोशिश करें, या द्विआधारी खोज का उपयोग करें) ), तब जब आपने पहले प्रतीक के लिए सही मूल्य पाया है, तो दूसरा प्रतीक खोजने के लिए खोजें, और इसी तरह।

पहले लेक्सिकोग्राफिक रूप से आने वाले डेक की संख्या की गणना करने के लिए सभी को एक कुशल प्रक्रिया के साथ आना है । यह एक सीधा लेकिन थकाऊ जुझारू व्यायाम की तरह दिखता है। विशेष रूप से, मेरा सुझाव है कि आप निम्नलिखित समस्या के लिए एक सबरूटीन का निर्माण करें: एक उपसर्ग (जैसे 222234) दिया गया है, उस उपसर्ग के साथ शुरू होने वाले डेक की संख्या की गणना करें। इस समस्या का उत्तर द्विपद गुणांक और factorials में एक बहुत आसान अभ्यास की तरह दिखता है। फिर, आप सामने आने वाले डेक की संख्या की गणना करने के लिए इस सबरूटीन को कई बार लगा सकते हैं ।डीDD


टिप्पणियाँ विस्तारित चर्चा के लिए नहीं हैं; इस वार्तालाप को बातचीत में स्थानांतरित कर दिया गया है ।
DW

8

सूटों की अनदेखी करने वाले कार्डों की संभावित व्यवस्था की संख्या जिसका लघुगणक आधार २.६.९ or६ या प्रति कार्ड ३.१ ९ १ ९ बिट्स है, जो आपके द्वारा दी गई सीमा से बेहतर है।

52!(4!)13,

किसी भी निश्चित "बिट्स प्रति कार्ड" एन्कोडिंग का कोई मतलब नहीं होगा क्योंकि, जैसा कि आप ध्यान दें, आखिरी कार्ड हमेशा बिट्स में एन्कोड किया जा सकता है और कई मामलों में अंतिम कुछ कार्ड भी हो सकते हैं। इसका मतलब है कि पैक के "पूंछ" की दिशा में काफी हद तक प्रत्येक कार्ड के लिए आवश्यक बिट्स की संख्या आपके विचार से काफी कम होगी।0

अब तक डेटा को संपीड़ित करने का सबसे अच्छा तरीका यह होगा कि आप 59 बिट्स को दूसरे डेटा के साथ खोजें, जिसे आप अपने कार्ड डेटा के साथ वैसे भी पैक करना चाहते हैं (59.6 बिट्स, वास्तव में) और, उन 59 बिट्स को 13-अंकीय संख्या के रूप में लिखकर 24 (=) ), प्रत्येक कार्ड के लिए एक सूट असाइन करें ( 4 के बीच एक अंक चुनता है ! इक्के पर सूट देने के तरीके, राजाओं के लिए एक और ऐसा ही करता है)। फिर आपके पास 52 पूर्ण कार्डों का एक पैकेट है। ५२ ! संभावनाओं को बहुत आसानी से 225.58 बिट्स में एन्कोड किया जा सकता है।4!4!52!

लेकिन उन अतिरिक्त बिट्स को एन्कोडिंग का अवसर लेने के बिना भी करना कुछ हद तक संभव है, और मैं इसके बारे में सोचूंगा क्योंकि मुझे यकीन है कि बाकी सभी लोग हैं। वास्तव में एक दिलचस्प समस्या के लिए धन्यवाद!


1
क्या सिफरटेक्स्ट चोरी के समान दृष्टिकोण का उपयोग यहां किया जा सकता है? जैसा कि, आप उन अतिरिक्त 59 बिट्स में जो डेटा एनकोड करते हैं वह एन्कोडेड प्रतिनिधित्व के अंतिम 59 बिट्स हैं?
जॉन ड्वोरक

@ जैनडी मैं कुछ इस तरह की जांच के बारे में सोच रहा था। लेकिन फिर यह पता चला कि एक एल्गोरिथ्म मौजूद है जो सैद्धांतिक सीमा को प्राप्त करता है और सीधा और 100% विश्वसनीय है, इसलिए आगे देखने का कोई मतलब नहीं था।
मार्टिन कोचनस्की

@MartinKochanski - मैं इसे "अनदेखा करने वाले सूट" के रूप में नहीं कहूंगा क्यूज़ हम अभी भी प्रति रैंक मानक 4 सूट का सम्मान कर रहे हैं। बेहतर शब्दों में कहा जा सकता है "डेक की संभावित अलग व्यवस्था की संख्या है" ...
डेविड जेम्स

3

यह लंबे समय से हल की गई समस्या है।

जब आप 52 कार्ड का एक डेक सौदा करते हैं, तो आपके द्वारा सौदा किए जाने वाले प्रत्येक कार्ड में ज्ञात संभावनाओं के साथ 13 रैंक तक होता है। हर कार्ड से जुड़ी संभावनाएँ बदल जाती हैं। यह एक प्राचीन तकनीक का उपयोग करके अनुकूलित किया गया है जिसे एडेप्टिव अंकगणितीय कोडिंग कहा जाता है, हफ़मैन कोडिंग में सुधार। आमतौर पर इसका उपयोग ज्ञात, अपरिवर्तनीय संभावनाओं के लिए किया जाता है, लेकिन इसका उपयोग बदलती हुई संभावनाओं के लिए भी किया जा सकता है। अंकगणित कोडिंग के बारे में विकिपीडिया लेख पढ़ें:

https://en.wikipedia.org/wiki/Arithmetic_coding


ठीक है, लेकिन यह मेरे प्रश्न का उत्तर नहीं देता है यदि यह सैद्धांतिक एन्ट्रापी एन्कोडिंग सीमा तक पहुंच सकता है, मैच कर सकता है या हरा सकता है। ऐसा लगता है कि चूंकि प्रत्येक में 1 / n संभावना के साथ n संभव डेक हैं, तो एन्ट्रापी एन्कोडिंग की सीमा है और हम बेहतर नहीं कर सकते (जब तक कि हम "धोखा" न दें और डिकोडर को इनपुट डेटा के बारे में कुछ बताएं जो समय से पहले एनकोडर में हो।
डेविड जेम्स

3

डीडब्ल्यू और मार्टिन कोचनस्की दोनों ने पहले ही सीमा में सौदों और पूर्णांकों के बीच एक आक्षेप का निर्माण करने के लिए एल्गोरिदम का वर्णन किया है , लेकिन ऐसा लगता है कि उनमें से किसी ने भी समस्या को उसके सरलतम रूप में कम नहीं किया है। (नोट 1)[0,52!(4!)13)

मान लीजिए कि हमें एक (आंशिक) डेक का आदेश दिया सूची द्वारा वर्णित है है, जहां एक मैं प्रकार के कार्ड की संख्या है मैं । ओपी में, प्रारंभिक डेक को 13 तत्वों की सूची द्वारा वर्णित किया गया है, जिनमें से प्रत्येक का मूल्य 4 है। इस तरह के डेक के अलग-अलग फेरबदल की संख्या हैaaii

c(a)=(ai)!ai!

जो कि द्विपद गुणांक का एक सामान्य सामान्यीकरण है, और वास्तव में केवल एक समय में वस्तुओं को एक प्रकार से व्यवस्थित करके साबित किया जा सकता है, जैसा कि मार्टिन कोचनस्की ने सुझाव दिया था। (नीचे देखें, नोट 2)

अब, ऐसे किसी भी (आंशिक) डेक के लिए, हम एक समय में एक कार्ड को फेरबदल कर सकते हैं, किसी भी का उपयोग कर सकते हैं जिसके लिए i > 0 । अद्वितीय शफ़ल की संख्या का आरम्भ करने का मैं हैiai>0i

{0if ai=0c(a1,...,ai1,ai1,ai+1,...,an)if ai>0.

और उपरोक्त सूत्र से, हमारे पास है

c(a1,...,ai1,ai1,ai+1,...,an)=aic(a)ai

हम तो डेक के माध्यम से recurse सकते हैं (या पुनरावृति) तक फेरबदल को देख कि एक उपसर्ग के लिए इसी शफ़ल की संख्या कोषगत अप करने के लिए उपसर्ग की तुलना में छोटे से पूरा हो गया है हैi

c(a)j=1iajj=1naj

मैंने एल्गोरिथ्म का वर्णन करने के लिए पायथन में यह लिखा था; पायथन किसी भी तरह से एक छद्म कोड के रूप में उचित है। ध्यान दें कि अधिकांश अंकगणित में विस्तारित परिशुद्धता शामिल है; मान (फेरबदल के क्रम का प्रतिनिधित्व करते हैं) और n (शेष आंशिक डेक के लिए संभावित फेरबदल की कुल संख्या) दोनों 166-बिट बोगम हैं। कोड को किसी अन्य भाषा में अनुवाद करने के लिए, किसी प्रकार की बाइनम लाइब्रेरी का उपयोग करना आवश्यक होगा।kn

इसके अलावा, मैं सिर्फ कार्ड के नामों के बजाय पूर्णांक की सूची का उपयोग करता हूं, और - उपरोक्त गणित के विपरीत - पूर्णांक 0-आधारित हैं।

एक फेरबदल को एनकोड करने के लिए, हम फेरबदल के माध्यम से चलते हैं, प्रत्येक बिंदु पर जमते हैं, जो उपरोक्त फार्मूले का उपयोग करके एक छोटे कार्ड के साथ शुरू होते हैं:

from math import factorial
T = factorial(52) // factorial(4) ** 13

def encode(vec):
    a = [4] * 13
    cards = sum(a)
    n = T
    k = 0
    for idx in vec:
        k += sum(a[:idx]) * n // cards
        n = a[idx] * n // cards
        a[idx] -= 1
        cards -= 1
    return k

166-बिट संख्या को डिकोड करना सरल व्युत्क्रम है। प्रत्येक चरण में, हमारे पास एक आंशिक डेक और एक क्रमिक का विवरण है; हमें छोटे कार्ड्स से शुरू होने वाले फेरबदल को छोड़ना होगा, जो कि आर्डिनल से मेल खाता है, और फिर हम चुने हुए कार्ड को आउटपुट देते हैं, इसे बचे हुए डेक से हटाते हैं, और चयनित उपसर्ग के साथ संभावित फेरबदल की संख्या को समायोजित करते हैं:

def decode(k):
    vec = []
    a = [4] * 13
    cards = sum(a)
    n = T
    while cards > 0:
        i = cards * k // n
        accum = 0
        for idx in range(len(a)):
            if i < accum + a[idx]:
                k -= accum * n // cards
                n = a[idx] * n // cards
                a[idx] -= 1
                vec.append(idx)
                break
            accum += a[idx]
        cards -= 1
    return vec

मैंने उपरोक्त कोड को अनुकूलित करने का कोई वास्तविक प्रयास नहीं किया। मैंने इसे पूरे 3mil.TXT फ़ाइल के विरुद्ध चलाया, जाँच की कि encode(decode(line))मूल एन्कोडिंग के परिणामस्वरूप; यह सिर्फ 300 सेकंड से कम समय लगा। (सात पंक्तियों को विचारधारा पर ऑन-लाइन परीक्षण में देखा जा सकता है ।) निचले स्तर की भाषा में फिर से लिखना और विभाजन को अनुकूलित करना (जो संभव है) शायद उस समय को कुछ प्रबंधनीय कम कर देगा।

चूंकि एन्कोडेड वैल्यू केवल एक पूर्णांक है, इसलिए यह 166 बिट्स में आउटपुट हो सकता है। अग्रणी शून्य को हटाने का कोई मूल्य नहीं है, क्योंकि तब यह जानने का कोई तरीका नहीं होगा कि एन्कोडिंग को कहाँ समाप्त किया गया है, इसलिए यह वास्तव में 166-बिट एन्कोडिंग है।

हालांकि, यह ध्यान देने योग्य है कि व्यावहारिक अनुप्रयोग में, फेरबदल को एन्कोड करने के लिए संभवतः कभी आवश्यक नहीं है; यादृच्छिक 166-बिट संख्या उत्पन्न करके और इसे डीकोड करके एक यादृच्छिक फेरबदल उत्पन्न किया जा सकता है। और यह वास्तव में आवश्यक नहीं है कि सभी 166 बिट्स यादृच्छिक हो; यह संभव होगा, उदाहरण के लिए, 32-बिट यादृच्छिक पूर्णांक के साथ शुरू करें और फिर 32-बिट नंबर के साथ वरीयता प्राप्त किसी भी मानक आरएनजी का उपयोग करके 166 बिट्स में भरें। इसलिए यदि लक्ष्य बस बड़ी संख्या में यादृच्छिक फेरबदल करने के लिए प्रतिलिपि प्रस्तुत करने में सक्षम है, तो आप प्रति-सौदा भंडारण आवश्यकता को कम या ज्यादा मनमाने ढंग से कम कर सकते हैं।

आप एक बड़ी संख्या में सांकेतिक शब्दों में बदलना चाहते हैं वास्तविक सौदों (कुछ अन्य फैशन में उत्पन्न किया था) की लेकिन, आप डेल्टा एन्कोड संख्या की क्रमबद्ध सूची कर सकते हैं सौदों के आदेश के बारे में परवाह नहीं है, लगभग बचत लोग इन 2 एन प्रत्येक के लिए बिट्स नंबर। (बचत परिणाम इस तथ्य से होता है कि एक क्रमबद्ध अनुक्रम में एक अनुक्रम से कम एन्ट्रॉपी होता है। यह अनुक्रम में एकल मूल्य के एन्ट्रॉपी को कम नहीं करता है।)Nlog2N

यह मानते हुए कि हमें k -bit संख्याओं की क्रमबद्ध सूची को एनकोड करना है , हम निम्नानुसार आगे बढ़ सकते हैं:N k

  1. लॉग 2 एन (या तो फर्श या छत काम करेगा के करीब एक पूर्णांक के रूप में चुनें ; मैं आमतौर पर छत के लिए जाता हूं)।plog2N

  2. हम संख्याओं की सीमा को द्विआधारी उपसर्ग द्वारा अंतराल में विभाजित करते हैं । प्रत्येक कश्मीर -बिट संख्या एक में बांटा गया है पी -बिट उपसर्ग और एक कश्मीर - पी -बिट प्रत्यय; हम केवल प्रत्यय लिखते हैं (क्रम में)। इसके लिए N ( k - p ) बिट्स की आवश्यकता होती है ।2pkpkpN(kp)

  3. इसके अतिरिक्त, हम थोड़ा-अनुक्रम बनाने के लिए: से प्रत्येक के लिए उपसर्गों (उपसर्ग को छोड़कर 0 ) हम एक को लिखने 0 कि उपसर्ग (यदि हो तो) एक के बाद के साथ एक नंबर के लिए 1 । इस अनुक्रम में स्पष्ट रूप से 2 पी + एन बिट्स हैं: 2 पी 1 एस और एन 0 एस।2p0012p+N2p 1N 0

संख्याओं को डीकोड करने के लिए हम 0 पर एक उपसर्ग काउंटर शुरू करते हैं, और बिट अनुक्रम के माध्यम से काम करने के लिए आगे बढ़ते हैं। जब हम एक देखते हैं , तो हम प्रत्यय सूची से वर्तमान उपसर्ग और अगले प्रत्यय का उत्पादन करते हैं; जब हम 1 देखते हैं , तो हम वर्तमान उपसर्ग बढ़ाते हैं।01

एन्कोडिंग की कुल लंबाई है जो बहुत करीब है एन * ( कश्मीर - पी ) + एन + एन , या एन * ( कश्मीर - पी + 2 ) , एक औसत के लिए की कश्मीर - पी + 2 मूल्य प्रति बिट्स।N(kp)+N+2pN(kp)+N+NN(kp+2)kp+2

टिप्पणियाँ

  1. है92024242230271040357108320801872044844750000000000, औरलोग इन252!52!(4!)1392024242230271040357108320801872044844750000000000 लगभग१६५.९ .६५ है। पाठ में, मैं कभी-कभी दिखावा करता हूं कि आधार -2 लघुगणक वास्तव में166 है; सीमा के भीतर यादृच्छिक अध्यादेश उत्पन्न करने के मामले में, एक अस्वीकृति एल्गोरिथ्म का उपयोग किया जा सकता है जो केवल बहुत कम ही उत्पन्न यादृच्छिक संख्या को अस्वीकार करेगा।log252!(4!)13165.9765166
  2. सुविधा के लिए, मैं लिखने के के लिए n Σ मैं = k एक मैं ; तो एक 1 प्रकार की वस्तुओं 1 में रखा जा सकता ( एस 1Ski=knaia11तरीके, और उसके बाद प्रकार की वस्तुओं2में रखा जा सकता(एस2(S1a1)2तरीके, और इतने पर। चूँकि ( Si)(S2a2), कि कुल गिनती की ओर जाता है(Siai)=Si!ai!(Siai)!=Si!ai!Si+1!

i=1nSi!i=1nai!Si+1!

जो ऊपर दिए गए सूत्र को सरल करता है।


टिप्पणियाँ विस्तारित चर्चा के लिए नहीं हैं; इस वार्तालाप को बातचीत में स्थानांतरित कर दिया गया है ।
DW

@rici - मैंने आपको +100 बाउंटी क्यूज़ दिया जिसमें आपने अपना उत्तर समझाया जिसमें कोड सहित एक बेहतर प्रस्तुति दी गई है जबकि अन्य उत्तर अधिक सार / सैद्धांतिक हैं, वास्तव में एन्कोड / डिकोड को लागू करने के कुछ विवरणों को छोड़कर। जैसा कि आप जानते हैं, कोड लिखते समय कई विवरण होते हैं। मैं स्वीकार करता हूं कि मेरा एल्गोरिथ्म सबसे सीधा, सरल, समझने में आसान नहीं है, लेकिन मुझे वास्तव में यह बहुत प्रयास के बिना काम कर रहा है और समय के साथ मैं इसे और अधिक संपीड़न के साथ तेजी से चालू कर सकता हूं। इसलिए आपके उत्तर के लिए धन्यवाद और अच्छे काम को जारी रखें।
डेविड जेम्स

2

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

मेरे एल्गोरिथ्म का अवलोकन यह है कि यह कार्ड के समूहों और मिश्रित आंशिक बिट एन्कोडिंग के संयोजन का उपयोग करता है। उदाहरण के लिए, मिलियन फेरबदल वाले डेक की मेरी साझा परीक्षण फ़ाइल में , पहले वाले में 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। प्रति कार्ड बिट्स की संख्या तो प्रति कार्ड थोड़ा कम अगर हम का उपयोग है पैकिंग विधि।26/7

तो , हम अपने मास्टर " 23456789 टी जे क्यू के " क्रमबद्ध रैंक की सूची में उन रैंक की क्रमिक स्थिति को देखते हैं । उदाहरण के लिए, के पहले वास्तविक कार्ड रैंक 5 के पद देखने स्ट्रिंग में देखने स्थिति है 4 । हम सिर्फ इन इलाज 7 एक आधार के रूप रैंक पदों 13 से 0 (ताकि स्थिति 4 हम पहले मिल गया वास्तव में एक 3 हो जाएगा) आरंभिक क्रमांक। वापस बेस 10 में परिवर्तित (प्रयोजनों की जाँच के लिए), हमें 15 , 565 , 975 मिलते हैं । में 2654A236J23456789TJQKA547131015,565,97526बाइनरी के बिट हमें 00111011011000010010010111

डीकोडर बहुत समान तरीके से काम करता है। यह (उदाहरण के लिए) बिट्स के स्ट्रिंग को लेता है और इसे दशमलव (बेस 10) में 15 , 565 , 975 पर वापस पहुंचाता है , फिर इसे ऑफ़सेट लुकअप स्ट्रिंग में ऑफ़सेट प्राप्त करने के लिए बेस 13 में परिवर्तित करता है , फिर यह रैंक को फिर से संगठित करता है। एक समय में एक और मूल 54 236 जे पहले 7 कार्ड प्राप्त करता है। ध्यान दें कि बिट्स का अवरोधन हमेशा 26 नहीं होगा, लेकिन हमेशा प्रत्येक डेक में 26 पर शुरू होगा। एनकोडर और डिकोडर दोनों के संचालन से पहले ही डेक डेटा के बारे में कुछ महत्वपूर्ण जानकारी होती है। यह इस एल्गोरिथ्म के बारे में असाधारण अच्छी बात है।2615,565,9751354A236J7

शेष रैंकों से प्रत्येक # (जैसे अपनी ही 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 ), बिट्स की संख्या कार्ड एन्कोड करने के लिए कम हो जाती है।125248,832218262,14418/53.61326/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
  9    16/5=3.200=3  1/5
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
  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
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,KK1312713रैंक एन्कोडिंग मोड, हम इसे पूरा करने के लिए को उस ब्लॉक में शामिल करते हैं । इस तरह बहुत कम बर्बादी होती है। ऐसे मामले भी हैं जब हम एक ब्लॉक को भरने की कोशिश कर रहे हैं, भरे हुए रैंकों का # 2 या उससे अधिक तक उछल जाता है । यह भी कोई समस्या नहीं है क्योंकि हम सिर्फ वर्तमान एन्कोडिंग मोड में ब्लॉक को भरते हैं, तो हम नए एन्कोडिंग मोड में उठाते हैं जो 1 , 2 , 3 हो सकता है ... कम या एक ही मोड में रहना (जैसा कि मामला था) डेटाफ़िले में पहले डेक में 13 रैंक एन्कोडिंग मोड में 3 पूर्ण ब्लॉक हैं )। यही कारण है कि आकार 1 और 7 के बीच के रूप में ब्लॉक को उचित बनाना महत्वपूर्ण हैK21,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)।


3
मैंने देखा कि आपने 9 घंटे के स्थान पर लगभग 24 संपादन किए हैं। मैं आपके उत्तर को बेहतर बनाने की आपकी इच्छा की सराहना करता हूं। हालाँकि, हर बार जब आप उत्तर को संपादित करते हैं, तो यह सामने वाले पृष्ठ के शीर्ष पर पहुंच जाता है। उस कारण से, हम अत्यधिक संपादन को हतोत्साहित करते हैं। यदि आप कई संपादन करने की उम्मीद करते हैं, तो क्या आपके संपादन को बैचना संभव होगा, इसलिए आप हर कुछ घंटों में केवल एक संपादन करते हैं? (: और "अद्यतन" गरीब शैली अपने जवाब में है आमतौर पर देखें संयोग से, ध्यान दें कि डाल "संपादित करें"। Meta.cs.stackexchange.com/q/657/755। )
DW

4
यह प्रगति रिपोर्ट, स्थिति अपडेट या ब्लॉग आइटम डालने का स्थान नहीं है। हम पूरी तरह से गठित जवाब चाहते हैं, न कि "जल्द ही आ रहा है" या "मेरे पास एक समाधान है लेकिन मैं इसका वर्णन नहीं करने जा रहा हूं कि यह क्या है"।
DW

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

3
@DavidJames, मुझे समझ में आता है। हालाँकि, यह अभी भी हमारे दिशानिर्देशों को नहीं बदलता है: कृपया इतने सारे संपादन न करें। (यदि आप वेबसाइट में सुधार प्रस्तावित करना चाहते हैं, तो बेझिझक हमारे कंप्यूटर साइंस मेटा पर या meta.stackexchange.com पर एक पोस्ट करने के लिए स्वतंत्र महसूस करें । यह सुझाव देते हुए देवता यह टिप्पणी धागा नहीं पढ़ते हैं।) लेकिन इस बीच, हम हमारे पास मौजूद सॉफ़्टवेयर के साथ काम करना, और कई संपादन करना हतोत्साहित करता है क्योंकि यह सवाल को सबसे ऊपर लाता है। इस बिंदु पर, अपने आप को प्रति दिन एक संपादन तक सीमित करना, शूटिंग के लिए एक अच्छा दिशानिर्देश हो सकता है। अगर मदद करता है कि ऑफ़लाइन संपादकों या StackEdit का उपयोग करने के लिए स्वतंत्र महसूस करें!
DW

3
मैं कई कारणों से आपका जवाब नहीं दे रहा हूं। 1) यह अनावश्यक लंबा है और FAR भी क्रिया है। आप इसकी प्रस्तुति को बहुत कम कर सकते हैं। 2) बेहतर जवाब पोस्ट किए गए हैं, जिन्हें आप मेरे लिए अनजाने कारणों से अनदेखा करना चाहते हैं। 3) उत्थान की कमी के बारे में पूछना आमतौर पर मेरे लिए "लाल झंडा" है। ४) यह लगातार INSANE मात्रा के कारण पहले पन्ने पर बना हुआ है।
निकोलस मंचुसो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.