ในฐานะที่เป็นทางเลือกในการแก้ไขปัญหานี้อัลกอริทึมของฉันใช้บิตเศษส่วน (ไม่ใช่จำนวนเต็ม) ต่อบัตรสำหรับกลุ่มของการ์ดในสำรับตามจำนวนอันดับที่ไม่สำเร็จที่เหลืออยู่ มันเป็นอัลกอริทึมที่ค่อนข้างหรูหรา ฉันตรวจสอบอัลกอริทึมการเข้ารหัสด้วยมือและมันก็ดูดี ตัวเข้ารหัสกำลังแสดงผลสิ่งที่ดูเหมือนว่าเป็นบิตที่ถูกต้อง (ในรูปแบบไบต์เพื่อความเรียบง่าย)
ภาพรวมของอัลกอริทึมของฉันคือมันใช้การรวมกันของกลุ่มของการ์ดและการเข้ารหัสเศษส่วนแบบเศษส่วน ยกตัวอย่างเช่นในการทดสอบของฉันไฟล์ร่วมกันของล้านชั้นสับคนแรกที่มีคนแรกที่7ไพ่54 236 J เหตุผลที่ฉันเลือกขนาดบล็อกการ์ด7ใบเมื่อมี13การ์ดที่เป็นไปได้คือเพราะ13 7 "รองเท้า" (พอดีอย่างอบอุ่น) เป็น26บิต (ตั้งแต่13 7 = 62 , 748 , 517และ2 26 = 67 , 108 ,3754A236J7131372613762,748,517226 ) โดยหลักการแล้วเราต้องการให้ตัวเลขทั้งสองนั้นใกล้เคียงที่สุดเท่าที่จะเป็นไปได้ (แต่ด้วยพลังของตัวเลข 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 T J Q K A " ของอันดับที่เรียงลำดับ ยกตัวอย่างเช่นอันดับบัตรแรกที่เกิดขึ้นจริงของ5มีตำแหน่งการค้นหาในสตริงอันดับการค้นหาของ4 เราปฏิบัติต่อตำแหน่ง7อันดับเหล่านี้เป็นฐาน13หมายเลขเริ่มต้นด้วย 0 (ดังนั้นตำแหน่ง 4 ที่เราได้รับก่อนหน้านี้จะเป็น 3) แปลงกลับไปที่ฐาน10 (สำหรับการตรวจสอบวัตถุประสงค์) เราได้รับ15 , 565 , 975 ใน2654 A 236 J23456789 TJคิวเคA547131015 , 565 , 97526บิตไบนารีที่เราได้รับ0011101101100001001001011100111011011000010010010111
ตัวถอดรหัสทำงานในลักษณะที่คล้ายกันมาก มันใช้เวลา (ตัวอย่าง) สตริงที่บิตและแปลงกลับเป็นทศนิยม (ฐาน 10) เพื่อรับ15 , 565 , 975จากนั้นแปลงเป็นฐาน13เพื่อให้ออฟเซ็ตเป็นสตริงการค้นหาอันดับจากนั้นจะจัดลำดับใหม่ ในช่วงเวลาหนึ่งและได้รับเดิม54 236 Jแรก7บัตร โปรดทราบว่าขนาดบล็อกของบิตจะไม่เป็น 26 แต่จะเริ่มต้นที่ 26 ในแต่ละสำรับเสมอ เข้ารหัสและถอดรหัสทั้งสองมีข้อมูลที่สำคัญบางอย่างเกี่ยวกับข้อมูลสำรับแม้กระทั่งก่อนที่พวกเขาทำงาน นั่นเป็นสิ่งที่ดีเป็นพิเศษเกี่ยวกับอัลกอริทึมนี้2615 , 565 , 9751354 A 236 J7
แต่ละ # ของการจัดอันดับที่เหลือ (เช่นมี 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เราควรทำอย่างไร ง่าย ๆปกติKจะปล่อยตัวเข้ารหัสจากโหมดการเข้ารหัส13อันดับไปเป็นโหมดการเข้ารหัส12อันดับ อย่างไรก็ตามเนื่องจากเรายังไม่ได้กรอกบล็อกแรกของ7ใบใน1375 , 6 , 7 , 7 , 7 , 7 , KK1312713อันดับการเข้ารหัสโหมดเรารวมในบล็อกนั้นเพื่อให้เสร็จสมบูรณ์ มีขยะน้อยมากด้วยวิธีนี้ นอกจากนี้ยังมีบางกรณีที่เราพยายามเติมบล็อกหมายเลข # ของอันดับที่เต็มไปด้วย2หรือมากกว่านั้น นั่นก็ไม่มีปัญหาเมื่อเราเติมบล็อกในโหมดการเข้ารหัสปัจจุบันจากนั้นเราเลือกโหมดการเข้ารหัสใหม่ซึ่งอาจเป็น1 , 2 , 3 ...น้อยลงหรือแม้กระทั่งอยู่ในโหมดเดียวกัน (เช่นกรณี ในสำรับแรกใน datafile เนื่องจากมี3บล็อกเต็มในโหมดการเข้ารหัส13อันดับ) นี่คือเหตุผลว่าทำไมจึงสำคัญที่จะต้องทำการบล็อกบล็อคอย่างสมเหตุสมผลเช่นระหว่างขนาด1ถึง7K21 , 2 , 3 ...31317. ถ้าเราทำให้มันมีขนาดเราจะต้องเติมบล็อกนั้นด้วยอัตราบิตที่สูงกว่าถ้าเราปล่อยให้การเปลี่ยนเอ็นโค้ดเดอร์เข้าสู่โหมดการเข้ารหัสที่มีประสิทธิภาพมากขึ้น20
เมื่อฉันใช้อัลกอริธึมนี้ (ด้วยมือ) บนสำรับแรกของไฟล์ข้อมูล (ซึ่งสร้างขึ้นโดยใช้การสุ่มแบบไม่เอนเอียงของ Fisher-Yates) ฉันได้รับบิตที่น่าประทับใจในการเข้ารหัสซึ่งเกือบจะเหมือนกับการเข้ารหัสแบบไบนารีที่เหมาะสมที่สุด ความรู้เกี่ยวกับตำแหน่งลำดับของสำรับที่เป็นไปได้ทั้งหมดไม่มีจำนวนมากและไม่มีการค้นหาแบบไบนารี อย่างไรก็ตามมันต้องการการผสมแบบไบนารี่และเรเดียนซ์ (พลังของ13 , 12 , 11 ... )16813 , 12 , 11
10777748747s หากเด็คจบลงด้วยการเป็นคู่ (เช่น 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 ...322223333444455556666777788889999 TTTTJJJJQ Q Q Q KKKKA A A A40
1103 , 7K8101บัตรที่เหลืออยู่ สิ่งนี้มีความสำคัญเนื่องจากทำให้กระบวนการเข้ารหัสมีประสิทธิภาพมากขึ้นเมื่อตัวถอดรหัสสามารถกำหนดสมมติฐานที่ถูกต้องได้โดยไม่ต้องใช้ตัวเข้ารหัสเพื่อส่งข้อความพิเศษให้
313121110
54 236 J 87726 Q 3 3969 Q J K 7 T 9292 Q 36 K J 57 T 8 T K J 4 48 Q 8 T 55 K 4 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 บิตในการเข้ารหัสสำรับนั้นกรณีที่การบรรจุจริง ๆ เอนโทรปีของการเข้ารหัสเลขฐานสองตรงของตำแหน่งลำดับของมัน
ตอนนี้ฉันมีรหัสที่ใช้ในการคำนวณความต้องการบิตและมันแสดงให้ฉันโดยเฉลี่ยประมาณ 175 บิตต่อเดสก์ที่ต่ำ 155 และสูง 183 สำหรับไฟล์ทดสอบเด็ค 3 ล้าน อัลกอริทึมของฉันดูเหมือนว่าจะใช้ 9 บิตเพิ่มเติมต่อหนึ่งดาดฟ้าเทียบกับการเข้ารหัสไบนารี่ไบน์โดยตรงของวิธีการหาตำแหน่งแบบเลขลำดับ ไม่เลวเกินไปที่ต้องใช้พื้นที่เก็บข้อมูลเพิ่มเติมเพียง 5.5% 176 บิตเท่ากับ 22 ไบต์ดังนั้นจึงค่อนข้างดีกว่า 52 ไบต์ต่อเด็ค เด็คเคสที่ดีที่สุด (ไม่แสดงในไฟล์ทดสอบเด็ค 3 ล้าน) แพ็คเป็น 136 บิตและเด็คเคสที่แย่ที่สุด (แสดงใน testfile 8206 ครั้ง) คือ 183 บิต การวิเคราะห์แสดงให้เห็นว่ากรณีที่เลวร้ายที่สุดคือเมื่อเราไม่ได้รับรูปสี่เหลี่ยมแรกจนกระทั่งใกล้กับ (หรือที่) การ์ด 40 จากนั้นเมื่อโหมดการเข้ารหัสต้องการที่จะลดลงอย่างรวดเร็วเราจึง "บล็อก" บรรจุอยู่ โหมดการเข้ารหัสบิตที่สูงขึ้น บางคนอาจคิดว่าการไม่ได้รับการแจ้งเตือนใด ๆ จนกว่าการ์ด 40 จะค่อนข้างหายากโดยใช้สำรับที่สับ แต่โปรแกรมของฉันบอกฉันว่ามันเกิดขึ้น 321 ครั้งใน testfile 3 ล้านสำรับเพื่อให้ประมาณ 1 ออกจาก 9346 สำรับ นั่นบ่อยกว่าที่ฉันคาดไว้ ฉันสามารถตรวจสอบกรณีนี้และจัดการกับบิตน้อย แต่มันหายากมากที่มันจะไม่ส่งผลกระทบต่อบิตเฉลี่ยพอ
นอกจากนี้ที่นี่เป็นอย่างอื่นที่น่าสนใจมาก หากฉันจัดเรียงเด็คบนข้อมูลเด็คดิบความยาวของคำนำหน้าที่ทำซ้ำ # จำนวนครั้งที่สำคัญจะมีความยาวประมาณ 6 เท่านั้น (เช่น 222244) อย่างไรก็ตามด้วยข้อมูลที่บรรจุความยาวนั้นเพิ่มขึ้นถึง 16 นั่นหมายความว่าถ้าฉันเรียงลำดับข้อมูลที่บรรจุฉันควรจะได้รับการประหยัดที่สำคัญโดยเพียงแค่ระบุตัวถอดรหัสคำนำหน้า 16 บิตแล้วนำออกส่วนที่เหลือของสำรับ (ลบด้วยคำนำหน้าซ้ำ) ที่มีคำนำหน้าเหมือนกันจากนั้นไปยังคำนำหน้าถัดไปและทำซ้ำ สมมติว่าฉันบันทึกแม้แต่ 10 บิตต่อเด็คในแบบนี้ฉันควรเอาชนะ 166 บิตต่อเด็ค ด้วยเทคนิคการแจงนับที่ระบุโดยคนอื่นฉันไม่แน่ใจว่าคำนำหน้าจะยาวเท่ากับอัลกอริทึมของฉันหรือไม่ ความเร็วในการบรรจุและการเปิดออกโดยใช้อัลกอริทึมของฉันก็ดีเช่นกัน
เกี่ยวกับการบีบอัดระดับที่ 2 ที่ฉันเรียงลำดับ bitstrings เอาท์พุทของอัลกอริทึมของฉันจากนั้นใช้การเข้ารหัส "ความแตกต่าง": วิธีการที่ง่ายมากคือการเข้ารหัสคำนำหน้า 16 บิต 61,278 เฉพาะที่แสดงอย่างน้อยสองครั้งในข้อมูลเอาต์พุต จาก 89 ครั้งที่รายงาน) เพียงแค่นำหน้า 0 ในผลลัพธ์เพื่อบ่งบอกถึง decompressor ระดับที่ 2 ที่เรากำลังเข้ารหัสคำนำหน้า (เช่น 0000111100001111) แล้วสำรับใด ๆ ที่บรรจุด้วยคำนำหน้าเดียวกันนั้นจะตามด้วย 1 บิตนำไป ระบุส่วนที่ไม่ใช่คำนำหน้าของสำรับที่บรรจุ ค่าเฉลี่ย # ของสำรับที่บรรจุด้วยคำนำหน้าเหมือนกันคือประมาณ 49 สำหรับแต่ละคำนำหน้าไม่รวมถึงจำนวนเล็กน้อยที่ไม่ซ้ำกัน (เฉพาะ 1 สำรับเท่านั้นที่มีคำนำหน้านั้น) ดูเหมือนว่าฉันสามารถบันทึกประมาณ 15 บิตต่อเด็คโดยใช้กลยุทธ์ง่ายๆนี้ (เก็บคำนำหน้าร่วมกันหนึ่งครั้ง)
หลังจากการบีบอัดระดับที่ 2 โดยใช้การเข้ารหัส (prefix) ความแตกต่างของเอาต์พุต bitstring ที่เรียงลำดับแล้วของตัวเข้ารหัสแรกตอนนี้ฉันได้รับประมาณ 160 บิตต่อเด็ค ฉันใช้คำนำหน้าความยาว 18 และเก็บไว้เหมือนเดิม เนื่องจากเกือบทั้งหมด (245013 จาก 262144 = 93.5%) ของคำนำหน้า 18 บิตที่เป็นไปได้เหล่านั้นปรากฏขึ้นจึงเป็นการดีกว่าถ้าจะเข้ารหัสส่วนนำหน้า บางทีฉันสามารถใช้ 2 บิตเพื่อเข้ารหัสประเภทข้อมูลที่ฉันมี 00 = ความยาวปกติ 18 คำนำหน้าเก็บไว้ 01 = "คำนำหน้า 1 ขึ้น" (เหมือนกับคำนำหน้าก่อนหน้ายกเว้น 1 เพิ่ม), 11 = การเข้ารหัสแบบตรงจากการบรรจุระดับที่ 1 (ประมาณ 175 บิตโดยเฉลี่ย) 10 = การขยายตัวในอนาคตเมื่อฉันคิดถึงการเข้ารหัสที่จะประหยัดบิต
มีใครชนะ 160 บิตต่อเด็คหรือยัง ฉันคิดว่าฉันสามารถลดลงได้เล็กน้อยด้วยการทดลองและใช้ตัวอธิบาย 2 บิตที่ฉันได้กล่าวถึงข้างต้น บางทีมันอาจจะถึงจุดต่ำสุดที่ 158ish เป้าหมายของฉันคือรับไปที่ 156 บิต (หรือดีกว่า) เพราะนั่นจะเป็น 3 บิตต่อบัตรหรือน้อยกว่า ที่น่าประทับใจมาก. มีการทดลองมากมายที่จะทำให้มันลงมาถึงระดับนั้นเพราะถ้าฉันเปลี่ยนการเข้ารหัสระดับแรกฉันต้องทดสอบอีกครั้งซึ่งเป็นการเข้ารหัสระดับที่ดีที่สุดอันดับ 2 และมีชุดค่าผสมมากมายให้ลอง การเปลี่ยนแปลงบางอย่างที่ฉันทำอาจจะดีสำหรับข้อมูลแบบสุ่มอื่นที่คล้ายคลึงกัน แต่บางคนอาจมีอคติกับชุดข้อมูลนี้ ไม่แน่ใจจริงๆ แต่ถ้าฉันได้รับการกระตุ้นฉันสามารถลองชุดข้อมูลสำรับอีก 3 ล้านชุดเพื่อดูว่าเกิดอะไรขึ้นถ้าฉันได้ผลลัพธ์ที่คล้ายกัน
1050
ใครบ้างมีความคิดเกี่ยวกับวิธีการทำให้อัลกอริทึมของฉันดีขึ้นเช่นกรณีอื่น ๆ ฉันควรเข้ารหัสที่จะลดบิตของการจัดเก็บสำหรับแต่ละสำรับโดยเฉลี่ย? ใคร?
อีก 2 สิ่ง: 1) ฉันค่อนข้างผิดหวังที่มีผู้คนจำนวนมากที่ไม่ได้แก้ปัญหาของฉันซึ่งแม้ว่าจะไม่เหมาะกับพื้นที่ แต่ก็ยังดีและใช้งานได้ง่าย (ฉันทำงานได้ดี) 2) ฉันทำการวิเคราะห์ดาต้ามาล์เด็ล 3 ล้านของฉันและสังเกตว่าการ์ดที่เกิดขึ้นบ่อยที่สุดที่อันดับที่ 1 (เช่น 4444) อยู่ที่การ์ด 26 ซึ่งเกิดขึ้นประมาณ 6.711% ของเวลา (สำหรับ 201322 ของ 3 ล้านเด็ค ) ฉันหวังว่าจะใช้ข้อมูลนี้เพื่อบีบอัดเพิ่มเติมเช่นเริ่มต้นในโหมดเข้ารหัสสัญลักษณ์ 12 เนื่องจากเรารู้โดยเฉลี่ยเราจะไม่เห็นทุกระดับจนกระทั่งเกี่ยวกับ middeck แต่วิธีนี้ล้มเหลวในการบีบอัดใด ๆ เป็นค่าใช้จ่ายเกินออม ฉันกำลังมองหาการปรับแต่งอัลกอริทึมของฉันที่สามารถบันทึกบิต
ดังนั้นใครมีความคิดใด ๆ สิ่งที่ฉันควรลองถัดไปเพื่อบันทึกไม่กี่บิตต่อเด็คโดยใช้อัลกอริทึมของฉัน ฉันกำลังมองหารูปแบบที่เกิดขึ้นบ่อยครั้งมากพอที่ฉันจะสามารถลดบิตต่อเด็คแม้หลังจากค่าใช้จ่ายเพิ่มเติมในการบอกตัวถอดรหัสว่ารูปแบบที่คาดหวัง ฉันกำลังคิดบางอย่างเกี่ยวกับความน่าจะเป็นที่คาดหวังของการ์ดที่ยังไม่ได้มองเห็นที่เหลืออยู่และจับการ์ดทั้งหมดที่เหลืออยู่ในที่เก็บข้อมูลใบเดียว สิ่งนี้จะทำให้ฉันสามารถเข้าสู่โหมดการเข้ารหัสที่ต่ำกว่าได้เร็วขึ้นและอาจบันทึกบิตบ้าง แต่ฉันสงสัย
นอกจากนี้ FYI ฉันสร้างการสุ่ม 10 ล้านครั้งและเก็บไว้ในฐานข้อมูลเพื่อการวิเคราะห์ที่ง่าย มีเพียง 488 คนที่อยู่ในรูปสี่เหลี่ยม (เช่น 5555) หากฉันแพ็คเฉพาะผู้ที่ใช้อัลกอริทึมของฉันฉันจะได้รับ 165.71712 บิตโดยเฉลี่ยที่ 157 บิตต่ำและ 173 บิตสูง ต่ำกว่า 166 บิตเล็กน้อยโดยใช้วิธีการเข้ารหัสอื่น ฉันค่อนข้างประหลาดใจที่กรณีนี้ไม่บ่อยนัก (เฉลี่ยประมาณ 1 จากทุก ๆ 20,492 shuffles)