Apakah ada generalisasi dari Huffman Coding ke Arithmetic coding?

11

Dalam mencoba memahami hubungan antara Huffman Coding, Arithmetic Coding, dan Range Coding, saya mulai berpikir tentang kekurangan pengkodean Huffman terkait dengan masalah fraksional pengemasan bit .

Artinya, misalkan Anda memiliki 240 nilai yang mungkin untuk simbol, dan diperlukan untuk menyandikan ini menjadi bit, Anda akan terjebak dengan 8 bit per simbol, meskipun Anda tidak memerlukan "penuh" 8, karena 8 dapat mengekspresikan 256 nilai yang mungkin per simbol. Solusi untuk masalah ini adalah sesuatu yang saya lihat disebut sebagai "pengepakan bit fraksional", di mana Anda dapat "menggeser bit" dengan non-kekuatan dua menggunakan perkalian. Seperti halnya multiplikasi kekuatan-dua yang bergeser x * 2 == x << 1dan x * 4 == x << 2seterusnya untuk semua kekuatan dua, demikian pula Anda dapat "bergeser" dengan non-kekuatan-2 dengan mengalikannya, dan mengemasnya dalam simbol fraksional-bit-berukuran .

Masalahnya mirip dengan pengkodean Huffman: Anda berakhir dengan kode yang panjangnya harus non-fraksional, dan karenanya memiliki inefisiensi pengepakan ini. Namun, Anda tidak bisa hanya menggunakan solusi fracitonal-bit-packing, karena solusi ini mengasumsikan simbol berukuran tetap.

Pertanyaannya adalah, adakah makalah atau solusi untuk meningkatkan huffman coding dengan ide yang mirip dengan fraksional-bit-packing untuk mencapai sesuatu yang mirip dengan aritmatika coding? (atau hasil yang bertentangan).

Realz Slaw
sumber
1
Pengkodean aritmatika sudah optimal. Tidak perlu memperbaikinya.
Yuval Filmus
@YuvalFilmus ya saya maksudkan, bagaimana meningkatkan pengkodean huffman untuk membuatnya setara dengan pengkodean aritmatika.
Realz Slaw
1
Sama seperti saran, Anda mungkin menemukan pengkodean Sistem Angka Asimetris (ANS) lebih mudah dipahami daripada pengkodean aritmatika. Secara khusus, ini sedikit lebih mudah untuk melihat formulasi tertentu sebagai "pengemasan bit fraksional"
Nama samaran
@ Nama samaran Saya menemukan halaman ini yang sepertinya membuat hubungan ini antara rANS dan Huffman Coding. Tidak bisa mengatakan saya memahaminya, tapi saya pikir sudah cukup. Jika Anda membuat komentar sebagai jawaban saya akan menerimanya.
Realz Slaw
@YuvalFilmus Saya harap saya telah membuat kasus bahwa pengkodean aritmatika memang perlu perbaikan, dan ANS adalah perbaikan.
Nama samaran

Jawaban:

12

Mari kita lihat cara berpikir yang sedikit berbeda tentang pengkodean Huffman.

Misalkan Anda memiliki alfabet tiga simbol, A, B, dan C, dengan probabilitas 0,5, 0,25, dan 0,25. Karena probabilitasnya adalah semua kekuatan terbalik dari dua, ini memiliki kode Huffman yang optimal (yaitu identik dengan pengkodean aritmatika). Kami akan menggunakan kode kanonik 0, 10, 11 untuk contoh ini.

Misalkan negara kita adalah bilangan bulat besar, yang akan kita sebut . Anda dapat menganggap penyandian sebagai fungsi yang mengambil status saat ini, dan simbol untuk menyandikan, dan mengembalikan status baru:s

encode(s,A)=2sencode(s,B)=4s+2encode(s,C)=4s+3

Jadi mari kita mulai dengan negara 11 (yang 1011 dalam biner), menyandikan simbol B. Negara baru adalah 46, yang 101110 dalam biner. Seperti yang Anda lihat, ini adalah keadaan "lama" dengan urutan 10 ditambahkan di akhir. Kami memiliki dasarnya "output" urutan bit 10.

Sejauh ini baik.

Sekarang pikirkan sejenak tentang bagaimana pengkodean aritmatika bekerja. Jika Anda meletakkan probabilitas di atas penyebut umum, simbol A sebenarnya mewakili rentang , simbol B mewakili rentang dan simbol C mewakili kisaran .[04,24)[24,34)[34,44)

Pada dasarnya apa yang kita lakukan di sini adalah mengalikan semuanya dengan penyebut yang sama. Bayangkan bahwa keadaan sebenarnya dalam basis 4. Pengkodean simbol B benar-benar mengeluarkan angka 2 di basis itu, dan pengkodean simbol C menghasilkan keluaran angka 3 di basis itu.

Namun, simbol A sedikit berbeda, karena bukan seluruh digit pada basis 4.

Sebagai gantinya, kita dapat menganggap alfabet sebagai himpunan simbol A_0, A_1, B, C, dengan probabilitas yang sama. Ini, sekali lagi, memiliki kode Huffman optimal 00, 01, 10, 11. Atau, sekali lagi, kita dapat memikirkan hal ini di basis 4. Untuk menyandikan simbol, kita cukup melakukan:

encode(s,A0)=4s+0encode(s,A1)=4s+1encode(s,B)=4s+2encode(s,C)=4s+3

Jadi sekarang sudah jelas bagaimana cara menyandikan simbol B dan C, tetapi untuk menyandikan simbol A, kita punya pilihan. Manakah dari dan harus kita gunakan?A 1A0A1

Sekarang inilah ide cerdas: kita mencuri satu bit informasi dari negara :s

i=smod2

s=s2
i=smod2

dan kemudian .encode(s,Ai)

Dengan menggunakan contoh kami sebelumnya, , kami menemukan bahwa dan , dan kemudian . Status baru adalah 10101 dalam bentuk biner.s=11s=5i=1encode(5,A1)=4×5+1=21

Sekarang ini tidak menghasilkan keluaran bit yang persis sama dengan pengkodean Huffman, tetapi menghasilkan keluaran yang memiliki panjang yang sama. Dan saya harap Anda dapat melihat bahwa ini juga dapat diuraikan secara unik. Untuk mendekode simbol, kita mengambil sisanya ketika dibagi dengan 4. Jika nilainya 2 atau 3, maka simbolnya masing-masing adalah B atau C. Jika 0 atau 1, maka simbolnya adalah A, dan kemudian kita dapat mengembalikan sedikit informasi dengan mengalikan status dengan 2 dan menambahkan 0 atau 1.

Yang menyenangkan tentang pendekatan ini adalah bahwa ia meluas secara alami ke pengkodean fraksional-bit, ketika pembilang dan / atau penyebut probabilitas tidak kekuatan dua. Misalkan kita memiliki dua simbol, A dan B, di mana probabilitas A adalah dan probabilitas B adalah . Kemudian kita dapat menyandikan simbol dengan:3525

encode(s,A0)=5s+0encode(s,A1)=5s+1encode(s,A2)=5s+2encode(s,B0)=5s+3encode(s,B1)=5s+4

Untuk menyandikan simbol A, kita ambil dan , lalu .i=smod3encode(s,Ai)s=s3i=smod3encode(s,Ai)

Ini setara dengan pengkodean aritmatika. Ini sebenarnya keluarga metode yang dikenal sebagai Sistem Angka Asimetris , dan dikembangkan selama beberapa tahun terakhir oleh Jarek Duda. Arti nama harus jelas: untuk menyandikan simbol dengan probabilitas , Anda secara konseptual mencuri digit basis-p dari negara, dan kemudian menambahkan digit basis-q. Asimetri berasal dari menafsirkan negara sebagai angka dalam dua basis yang berbeda.pq

Alasan mengapa itu adalah keluarga metode pengkodean adalah bahwa apa yang kami lihat di sini tidak praktis dengan sendirinya; diperlukan beberapa modifikasi untuk menghadapi kenyataan bahwa Anda mungkin tidak memiliki bilangan bulat presisi tak terbatas untuk memanipulasi variabel keadaan secara efisien, dan ada berbagai cara yang dapat Anda lakukan untuk mencapai hal ini. Pengkodean aritmatika, tentu saja, memiliki masalah serupa dengan ketepatan untuk kondisinya.

Varian praktis termasuk rANS ("r" berarti "rasio") dan tANS ("table-driven").

ANS memiliki beberapa keunggulan menarik dibandingkan pengkodean aritmatika, baik yang praktis maupun teoritis:

  • Tidak seperti pengkodean aritmatika, "negara" adalah satu kata, bukan sepasang kata.
  • Tidak hanya itu, tetapi encoder ANS dan dekoder yang sesuai memiliki status yang identik dan operasinya sepenuhnya simetris. Ini memunculkan beberapa kemungkinan menarik, seperti Anda dapat menyisipkan berbagai aliran simbol yang disandikan dan semuanya disinkronkan dengan sempurna.
  • Implementasi praktis perlu, tentu saja, untuk "menampilkan" informasi saat Anda pergi, dan tidak hanya mengumpulkannya dalam bilangan bulat besar untuk ditulis di akhir. Namun, ukuran "output" dapat dikonfigurasi dengan imbalan kerugian kompresi (biasanya sederhana). Jadi di mana coders aritmatika harus menampilkan sedikit demi sedikit, ANS dapat menampilkan byte atau nybble pada suatu waktu. Ini memberi Anda tradeoff langsung antara kecepatan dan kompresi.
  • Tampaknya hampir secepat pada perangkat keras generasi saat ini sebagai pengkodean aritmatika biner, dan karenanya bersaing dengan pengkodean Huffman. Ini membuatnya jauh lebih cepat daripada pengkodean aritmatika alfabet besar dan variannya (mis. Pengkodean rentang).
  • Tampaknya bebas paten.

Saya tidak berpikir saya akan melakukan pengkodean aritmatika lagi.

Nama samaran
sumber
3
Nah, itulah penjelasan paling jelas tentang pengkodean ANS yang pernah saya lihat.
Michael Deardeuff
2

Sebagai contoh sederhana, jika Anda memiliki tiga simbol dengan probabilitas 1/3 masing-masing, pengodean Huffman optimal Anda akan menggunakan tiga simbol 0, 10 dan 11 dengan rata-rata 5/3 bit.

Ada 243 simbol yang dibuat dengan menggabungkan 5 simbol asli, masing-masing dengan probabilitas 1/243. Yang jauh lebih dekat dengan 1/256. Pengodean Huffman yang optimal akan mengkodekan 13 dari kelompok-kelompok ini dalam 7 bit dan 230 kelompok dalam 8 bit, untuk rata-rata 7,9465 bit per grup atau 1,5893 bit per simbol asli, turun dari 1,6667 bit untuk pengkodean Huffman asli, dengan pengkodean hitung mengambil 1,5850 bit.

Jadi secara teori Anda hanya bisa menggabungkan dua simbol masing-masing menjadi satu simbol yang lebih besar, atau tiga simbol masing-masing menjadi satu simbol yang lebih besar, dan menggunakan kode Hufman untuk kombinasi.

gnasher729
sumber