วิธีที่มีประสิทธิภาพมากที่สุดในการจัดเก็บช่วงตัวเลขคืออะไร


29

คำถามนี้เกี่ยวกับจำนวนบิตที่ต้องใช้ในการจัดเก็บช่วง หรือใส่อีกวิธีหนึ่งสำหรับจำนวนบิตที่กำหนดช่วงสูงสุดที่สามารถจัดเก็บได้คือเท่าใด

ลองนึกภาพเราต้องการเก็บช่วงย่อยภายในช่วง 0-255

ตัวอย่างเช่น 45-74

เราสามารถเก็บตัวอย่างด้านบนเป็นสองไบต์ที่ไม่ได้ลงชื่อ แต่มันทำให้ฉันรู้สึกว่าต้องมีข้อมูลซ้ำซ้อน เรารู้ว่าค่าที่สองมีขนาดใหญ่กว่าค่าแรกดังนั้นในกรณีที่ค่าแรกมีขนาดใหญ่จำเป็นต้องใช้บิตที่น้อยกว่าสำหรับค่าที่สองและในกรณีที่ค่าที่สองมีขนาดใหญ่จำเป็นต้องใช้บิตที่น้อยกว่าสำหรับครั้งแรก .

ฉันสงสัยว่าเทคนิคการบีบอัดใด ๆ จะให้ผลลัพธ์ที่ได้เล็กน้อยดังนั้นจึงอาจเป็นคำถามที่ดีกว่าที่จะถาม "ช่วงสูงสุดที่สามารถเก็บไว้ในไบต์เดียวคืออะไร" นี่ควรใหญ่กว่าสิ่งที่ทำได้โดยจัดเก็บตัวเลขสองตัวแยกกัน

มีอัลกอริธึมมาตรฐานสำหรับการทำสิ่งนี้หรือไม่?


คุณต้องเก็บจุดเริ่มต้นของช่วงหรือไม่?
Ewan

@Ewan ฉันไม่ได้ติดตามจริงๆ ในตัวอย่างข้างต้น 45 คือจุดเริ่มต้น (ขั้นต่ำ) และ 74 คือจุดสิ้นสุด (สูงสุด) และทั้งคู่จะต้องเก็บไว้
rghome

2
ดังนั้นคำถามคือประเภทของพื้นที่ที่สามารถเก็บช่วงใดก็ได้ หรือประเภทพื้นที่ที่สามารถเก็บ 45-74 ต้องการพื้นที่เท่าใด
Ewan

1
ในขณะที่คิดเกี่ยวกับสิ่งนี้ดีแน่นอนฉันหวังว่าคุณจะไม่ทำสิ่งนี้ในแอปพลิเคชันจริง เหตุผลก็คือปริมาณของความซับซ้อนของแอปพลิเคชันจริงนั้นใหญ่มากจนเราต้องยอมรับโค้ดที่ปรับให้เหมาะสมน้อยกว่า 100% นั่นคือสาเหตุที่คอมไพเลอร์มีอยู่
NoChance

3
@rghome ฉันเห็นด้วยแม้ข้อกำหนดที่ง่ายที่สุดก็สามารถสร้างโค้ดได้หลายร้อยบรรทัด แต่ละข้อผิดพลาดได้ง่าย โดยส่วนตัวฉันจะจ่ายค่าฮาร์ดแวร์มากกว่าเพิ่มความซับซ้อนของซอฟต์แวร์
NoChance

คำตอบ:


58

เพียงนับจำนวนช่วงที่เป็นไปได้ มีช่วง 256 ช่วงที่มีขอบเขตล่าง 0 (0-0, 0-1, ... 0-254, 0-255), 255 ช่วงที่มีขอบเขตล่าง 1, ... และสุดท้าย 1 ช่วงที่มีขอบเขตล่าง 255 (255- 255) ดังนั้นจำนวนทั้งหมดคือ (256 + 255 + ... + 1) = 257 * 128 = 32,896 เนื่องจากสูงกว่า 2 15 = 32,768 เล็กน้อยคุณจะต้องมีอย่างน้อย 16 บิต (2 ไบต์) เพื่อจัดเก็บข้อมูลนี้

โดยทั่วไปสำหรับตัวเลขตั้งแต่ 0 ถึง n-1 จำนวนของช่วงที่เป็นไปได้คือ n * (n + 1) / 2 นี่คือน้อยกว่า 256 ถ้า n เป็น 22 หรือน้อยกว่า: n = 22 ให้ 22 * ​​23/2 = 253 ความเป็นไปได้ ดังนั้นหนึ่งไบต์พอเพียงสำหรับการย่อยช่วงของ0-21

อีกวิธีในการดูปัญหามีดังต่อไปนี้: การจัดเก็บคู่ของจำนวนเต็มในช่วง 0 ถึง n-1 นั้นเกือบจะเหมือนกับการจัดเก็บช่วงย่อยที่ 0 (n-1) บวกบิตเดียวซึ่งกำหนดว่าหมายเลขแรก ต่ำกว่าหรือสูงกว่าอันที่สอง (ความแตกต่างมาจากกรณีที่เมื่อจำนวนเต็มทั้งสองเท่ากัน แต่โอกาสนี้มีขนาดเล็กลงเรื่อย ๆ เมื่อ n โตขึ้น) นั่นเป็นเหตุผลที่คุณสามารถบันทึกเพียงเล็กน้อยด้วยเทคนิคนี้และอาจเป็นเหตุผลหลักว่าทำไมมันจึงไม่ค่อยใช้


ขอบคุณ จำนวนบิตที่จำเป็นสำหรับช่วง n คือ log (n) / log2 การใส่เข้าไปใน Wolfram Alpha ทำให้ฉันมีสูตรที่เข้ากันได้กับ Excel ต่อไปนี้สำหรับการคำนวณค่าสูงสุดสำหรับช่วงย่อยสำหรับจำนวนบิตที่กำหนด: = INT ((SQRT (POWER (2, N + 3) + 1)) - 1) / 2 )
rghome

9
TLDR คือคุณได้รับประมาณครึ่งหนึ่งดังนั้นโดยทั่วไปแล้วมันไม่คุ้มค่ากับการบีบอัด
rghome

ใช่มันมีแนวโน้มที่จะบิตหนึ่งสำหรับ N ขนาดใหญ่ แต่มันก็ไม่คุ้มกับความยุ่งยาก
Glorfindel

FYI, N + 3 ในสมการนั้นดูแปลก แต่พลังหนึ่งของ 2 มาจากสมการของคุณและอีกสองมาจาก 4ac ส่วนหนึ่งของสูตรกำลังสอง
rghome

1
BTW การนับของคุณจะลดช่วงที่ว่างซึ่งชุดค่าผสมที่ไม่นับรวมทั้งหมดตั้งอยู่ ดังนั้นn * (n + 1) / 2 + 1! การเปลี่ยนแปลงเล็ก ๆ น้อย ๆ
Deduplicator

17

สำหรับบิตจำนวนน้อยเช่นนี้มันเป็นไปไม่ได้ที่จะบันทึกหลาย ๆ บิตตามที่Glorfindel ได้ชี้ไว้ อย่างไรก็ตามหากโดเมนที่คุณใช้มีบิตมากกว่าสองสามคุณสามารถประหยัดได้อย่างมากสำหรับตัวพิมพ์เล็กโดยการเข้ารหัสช่วงด้วยค่าเริ่มต้นและเดลต้า

ให้ถือว่าโดเมนเป็นจำนวนเต็มดังนั้น 32 บิต ด้วยวิธีการที่ไร้เดียงสาคุณต้องใช้ 64 บิต (เริ่มต้นสิ้นสุด) เพื่อจัดเก็บช่วง

หากเราเปลี่ยนเป็นการเข้ารหัส (start, delta) เราสามารถสร้างจุดสิ้นสุดของช่วงจากนั้น เรารู้ว่าในกรณีที่เลวร้ายที่สุดการเริ่มต้นคือ 0 และเดลต้ามี 32 บิต

2 ^ 5 คือ 32 ดังนั้นเราเข้ารหัสความยาวของเดลต้าในห้าบิต (ไม่มีความยาวเป็นศูนย์เพิ่ม 1 เสมอ) และการเข้ารหัสจะกลายเป็น (เริ่มต้นความยาวเดลต้า) ในกรณีที่เลวร้ายที่สุดค่าใช้จ่ายนี้ 32 * 2 + 5 บิตดังนั้น 69 บิต ดังนั้นในกรณีที่เลวร้ายที่สุดถ้าทุกช่วงยาวมันแย่กว่านั้นการเข้ารหัสที่ไร้เดียงสา

ในกรณีที่ดีที่สุดมีค่าใช้จ่าย 32 + 5 + 1 = 38 บิต

ซึ่งหมายความว่าหากคุณต้องเข้ารหัสช่วงจำนวนมากและช่วงเหล่านั้นครอบคลุมเฉพาะส่วนเล็ก ๆ ของโดเมนคุณจะใช้พื้นที่โดยเฉลี่ยน้อยลงเมื่อใช้การเข้ารหัสนี้ ไม่สำคัญว่าการกระจายเริ่มต้นจะเป็นอย่างไรตั้งแต่เริ่มต้นใช้เวลา 32 บิตเสมอ แต่ไม่สำคัญว่าจะกระจายความยาวของช่วงอย่างไร หากคุณมีความยาวขนาดเล็กมากเท่าใดยิ่งมีการบีบอัดมากเท่าใดก็ยิ่งมีช่วงที่ครอบคลุมความยาวทั้งหมดของโดเมนยิ่งการเข้ารหัสนี้ยิ่งแย่ลงเท่านั้น

อย่างไรก็ตามหากคุณมีช่วงจำนวนมากที่จัดกลุ่มรอบจุดเริ่มต้นที่คล้ายกัน (เช่นเนื่องจากคุณได้รับค่าจากเซ็นเซอร์) คุณสามารถประหยัดได้มากขึ้น คุณสามารถใช้เทคนิคเดียวกันกับค่าเริ่มต้นและใช้อคติเพื่อชดเชยค่าเริ่มต้น

ให้บอกว่าคุณมี 10,000 ช่วง ช่วงจะถูกจัดกลุ่มรอบค่าที่แน่นอน คุณเข้ารหัสอคติด้วย 32 บิต

เมื่อใช้วิธีการที่ไร้เดียงสาคุณจะต้องใช้ 32 * 2 * 10 000 = 640 000 บิตเพื่อจัดเก็บช่วงเหล่านั้นทั้งหมด

การเข้ารหัสไบแอสใช้เวลา 32 บิตและการเข้ารหัสแต่ละช่วงใช้เวลาในกรณีที่ดีที่สุดจากนั้น 5 + 1 + 5 + 1 = 12 บิตรวม 120,000 + 32 = 120 032 บิต ในกรณีที่เลวร้ายที่สุดคุณต้องมี 5 + 32 + 5 + 32 บิตดังนั้น 74 บิตรวมเป็น 740 032 บิต

ซึ่งหมายความว่าสำหรับ 10,000 ค่าในโดเมนที่ใช้เวลา 32 บิตในการเข้ารหัสเราได้รับ

  • 120 032 บิตพร้อมการเข้ารหัสเดลต้าอัจฉริยะในกรณีที่ดีที่สุด
  • 640,000 บิตที่มีจุดเริ่มต้นไร้เดียงสา, สิ้นสุดการเข้ารหัส, เสมอ (ไม่มีตัวพิมพ์ที่ดีที่สุดหรือแย่ที่สุด)
  • 740 032 บิตพร้อมการเข้ารหัสสมาร์ทเดลต้าในกรณีที่แย่ที่สุด

หากคุณใช้การเข้ารหัสที่ไร้เดียงสาเป็นพื้นฐานนั่นหมายความว่าสามารถประหยัดได้มากถึง 81.25% หรือค่าใช้จ่ายที่สูงขึ้นถึง 15.625%

ขึ้นอยู่กับวิธีการกระจายค่าของคุณการออมเหล่านั้นมีความสำคัญ รู้จักโดเมนธุรกิจของคุณ! รู้ว่าคุณต้องการเข้ารหัสอะไร

ในฐานะที่เป็นส่วนขยายคุณสามารถเปลี่ยนอคติ หากคุณวิเคราะห์ข้อมูลและระบุกลุ่มของค่าคุณสามารถจัดเรียงข้อมูลลงในที่เก็บข้อมูลและเข้ารหัสแต่ละที่เก็บข้อมูลแยกต่างหากโดยมีอคติของตนเอง ซึ่งหมายความว่าคุณสามารถนำเทคนิคนี้ไปใช้กับช่วงที่จัดกลุ่มไว้รอบ ๆ ค่าเริ่มต้นเดียว แต่ยังรวมถึงช่วงที่จัดกลุ่มตามค่าหลายค่าด้วย

หากจุดเริ่มต้นของคุณมีการกระจายอย่างเท่าเทียมกันการเข้ารหัสนี้ไม่ได้ผลดีนัก

เห็นได้ชัดว่าการเข้ารหัสนี้ไม่ดีอย่างยิ่งต่อดัชนี คุณไม่สามารถอ่านค่า x-th ได้อย่างง่ายดาย มันสามารถอ่านได้เรียงตามลำดับ ซึ่งเหมาะสมในบางสถานการณ์เช่นการสตรีมผ่านเครือข่ายหรือที่เก็บข้อมูลจำนวนมาก (เช่นบนเทปหรือ HDD)

การประเมินข้อมูลการจัดกลุ่มข้อมูลและการเลือกอคติที่ถูกต้องสามารถทำงานได้อย่างมีนัยสำคัญและอาจต้องมีการปรับแต่งอย่างละเอียดเพื่อผลลัพธ์ที่ดีที่สุด


8

ปัญหาแบบนี้เป็นเรื่องของเอกสารน้ำเชื้อของ Claude Shannon, A Mathematical Theory of Communicationซึ่งแนะนำคำว่า "bit" และการบีบอัดข้อมูลที่คิดค้นขึ้นหรือน้อยลง

แนวคิดทั่วไปคือจำนวนบิตที่ใช้ในการเข้ารหัสช่วงนั้นแปรผกผันกับความน่าจะเป็นของช่วงที่เกิดขึ้น ตัวอย่างเช่นสมมติว่าช่วง 45-74 ปรากฏขึ้นประมาณ 1/4 ของเวลา คุณอาจบอกว่าลำดับ 00 สอดคล้องกับ 45-74 หากต้องการเข้ารหัสช่วง 45-74 ให้คุณออก“ 00” แล้วหยุดตรงนั้น

ลองสมมุติว่าช่วง 99-100 และ 140-155 แต่ละอันปรากฏประมาณ 1/8 ของเวลา คุณสามารถเข้ารหัสแต่ละรายการด้วยลำดับ 3 บิต 3 บิตใด ๆ จะทำตราบเท่าที่ไม่ได้ขึ้นต้นด้วย“ 00” ซึ่งถูกสงวนไว้สำหรับช่วง 45-74

00: 45-74
010: 99-100
101: 140-155

คุณสามารถดำเนินการต่อในลักษณะนี้จนกว่าทุกช่วงที่เป็นไปได้จะมีการเข้ารหัส ช่วงที่เป็นไปได้น้อยที่สุดอาจต้องการมากกว่า 100 บิต แต่ก็ไม่เป็นไรเพราะมันไม่ค่อยปรากฏ

มีเป็นขั้นตอนวิธีการที่จะหาที่ดีที่สุดการเข้ารหัส ฉันจะไม่พยายามอธิบายพวกเขาที่นี่ แต่คุณสามารถหาข้อมูลเพิ่มเติมได้โดยไปที่ลิงก์ด้านบนหรือค้นหา "ทฤษฎีข้อมูล", "การเข้ารหัส Shannon-fano" หรือ "การเข้ารหัส Huffman"

ตามที่คนอื่น ๆ ได้ชี้ให้เห็นควรเก็บหมายเลขเริ่มต้นและความแตกต่างระหว่างหมายเลขเริ่มต้นและหมายเลขท้าย คุณควรใช้รหัสเดียวสำหรับการเริ่มต้นและอีกอันสำหรับความแตกต่างเนื่องจากมีการแจกแจงความน่าจะเป็นที่แตกต่างกัน (และฉันเดาว่าอันหลังนั้นซ้ำซ้อนมากขึ้น) ตามที่แนะนำ polygnome อัลกอริทึมที่ดีที่สุดขึ้นอยู่กับโดเมนของคุณ


1
ใช่โดเมนธุรกิจมีความสำคัญจริงๆ เราพิจารณาการใช้การเข้ารหัส Huffmann สำหรับอคติสำหรับวันที่เริ่มต้น แต่ในที่สุดก็ตัดสินใจได้หลังจากทำการวิเคราะห์ทางสถิติเกี่ยวกับข้อมูลโลกแห่งความจริง ความเรียบง่ายของการใช้การเข้ารหัสแบบเดียวกันสำหรับอคติและเดลต้ามีความสำคัญมากกว่าจากนั้นจึงเพิ่ม Huffmann ที่ด้านบนและคุณต้องส่งต้นไม้ Huffmann ทั้งหมดด้วย เป็นความคิดที่ดีที่จะระลึกถึงการเข้ารหัสของ Huffmann
Polygnome

1

หากต้องการขยายคำตอบจาก @Glorfindel:

ในฐานะ n →∞, (n - 1) → n ดังนั้นΩ (ช่วง) →n² / 2 และบันทึก (Ω (ช่วง)) → (2n - 1) เนื่องจากการเข้ารหัสไร้เดียงสาใช้เวลา 2n บิตการบีบอัดสูงสุดแบบ asymptotic จึงประหยัดเพียง 1 บิต


1

มีคำตอบที่คล้ายกัน แต่เพื่อให้ได้การบีบอัดที่ดีที่สุดคุณต้อง:

  1. วิธีการเข้ารหัสเอนโทรปีที่ดีที่สุด (อ่านค่าการเข้ารหัสทางคณิตศาสตร์และเทียบเท่าที่สำคัญ (อัตราส่วนการบีบอัดเดียวกันเร็วขึ้นเล็กน้อย แต่ยากต่อการเข้าใจ) ANS )
  2. ข้อมูลมากที่สุดเท่าที่เป็นไปได้เกี่ยวกับการกระจายของข้อมูล สิ่งสำคัญไม่เพียง แต่เกี่ยวข้องกับ "การเดา" ว่าจะมีหมายเลขหนึ่งปรากฎบ่อยแค่ไหน แต่คุณสามารถแยกแยะความเป็นไปได้บางอย่างได้อย่างแน่นอน ตัวอย่างเช่นคุณสามารถแยกช่วงของขนาดติดลบและขนาด 0 อาจขึ้นอยู่กับวิธีที่คุณกำหนดช่วงเวลาที่ถูกต้อง หากคุณมีการเข้ารหัสหลายช่วงเวลาพร้อมกันคุณสามารถเรียงลำดับได้เช่นในการลดความกว้างหรือเพิ่มค่าเริ่มต้น / สิ้นสุดและออกกฎค่าจำนวนมาก (เช่นถ้าคุณรับประกันคำสั่งโดยลดความกว้างช่วงก่อนหน้านี้ มีความกว้าง 100 และค่าเริ่มต้นสำหรับถัดไปคือ 47 คุณจะต้องพิจารณาความเป็นไปได้สูงสุด 147 สำหรับค่าสิ้นสุด)

ที่สำคัญคือหมายเลข 2 หมายถึงคุณต้องการเข้ารหัสสิ่งต่าง ๆ ในลักษณะที่คุณค่าของข้อมูลมากที่สุด (ต่อบิตที่เข้ารหัส) มาก่อน ตัวอย่างเช่นในขณะที่ฉันแนะนำการเข้ารหัสรายการที่เรียงลำดับ "ตามที่เป็น" มันมักจะฉลาดกว่าที่จะเข้ารหัสเป็น "ต้นไม้ไบนารี" - เช่นถ้าพวกเขาเรียงตามความกว้างและคุณมีlenองค์ประกอบเริ่มต้นด้วยองค์ประกอบการเข้ารหัสlen/2. บอกว่ามันกว้าง ทีนี้คุณก็รู้องค์ประกอบทั้งหมดก่อนที่มันจะมีความกว้างที่ไหนสักแห่งใน [0, w] และองค์ประกอบทั้งหมดหลังจากนั้นก็มีความกว้างที่ [w, max val ที่คุณยอมรับ] ทำซ้ำซ้ำ (แบ่งครึ่งแต่ละรายการอีกครึ่ง) จนกว่าคุณจะครอบคลุมlenองค์ประกอบ (เว้นแต่ว่าจะได้รับการแก้ไขคุณจะต้องเข้ารหัสlenก่อนอื่นคุณจึงไม่ต้องกังวลกับการสิ้นสุดโทเค็น) หาก "val สูงสุดที่คุณยอมรับ" เปิดจริง ๆ อาจเป็นการฉลาดที่จะเข้ารหัสค่าสูงสุดที่ปรากฏในข้อมูลของคุณเช่นองค์ประกอบสุดท้ายจากนั้นทำการแบ่งพาร์ติชันแบบไบนารี อีกครั้งอะไรก็ตามที่ให้ข้อมูลมากที่สุดต่อหนึ่งบิตก่อน

นอกจากนี้หากคุณเข้ารหัสความกว้างของช่วงเวลาก่อนและคุณทราบค่าสูงสุดที่เป็นไปได้ที่คุณกำลังเผชิญอยู่แน่นอนว่าคุณสามารถแยกแยะค่าเริ่มต้นทั้งหมดที่จะทำให้เกิดการไหลล้น ... คุณจะได้รับแนวคิด แปลงและจัดลำดับข้อมูลของคุณในแบบที่คุณสามารถอนุมานได้มากที่สุดเท่าที่จะเป็นไปได้เกี่ยวกับข้อมูลที่เหลือในขณะที่คุณถอดรหัสและอัลกอริธึมการเข้ารหัสแบบเอนโทรปีที่ดีที่สุดจะทำให้แน่ใจได้ว่า .

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.