Huffman Kodlamasının Aritmetik kodlamaya bir genellemesi var mı?


12

Huffman Kodlaması, Aritmetik Kodlama ve Aralık Kodlaması arasındaki ilişkileri anlamaya çalışırken, Huffman kodlamasının eksikliklerinin kesirli bit paketleme sorunuyla ilgili olduğunu düşünmeye başladım .

Yani, bir sembol için 240 olası değere sahip olduğunuzu ve bunu bitlere kodlamanız gerektiğini varsayalım, "tam" 8'e ihtiyacınız olmasa bile, sembol başına 8 bit ile sıkışmış olacaksınız, çünkü 8, 256 olası değeri ifade edebilir sembol başına. Bu soruna bir çözüm, "kesirli bit paketleme" olarak adlandırılan bir şeydir, burada çarpma kullanarak iki güç olmadan "bitshift" yapabilirsiniz. Sadece güçler-iki çoğalması gibi değiştiriyor x * 2 == x << 1ve x * 4 == x << 2böylece de sen fraksiyonel bit büyüklüğünde sembolleri olmayan bir güç-of-2 yerine çarparak ile "shift" ve paketi olabilir, ikisinin bütün güçler için ve benzeri .

Sorun Huffman kodlamasında benzerdir: kesirli olmayan bit boyutunda olması gereken kodlarla sonuçlanırsınız ve bu nedenle bu paketleme verimsizliğine sahiptir. Bununla birlikte, sadece fraksiyonel bit paketleme çözümünü kullanamazsınız, çünkü bu çözüm sabit boyutlu semboller varsayar.

Soru, aritmetik kodlamaya benzer bir şey elde etmek için kesirli bit paketlemesine benzer bir fikirle huffman kodlamasında iyileştirilecek herhangi bir kağıt veya çözüm var mı? (veya aksine herhangi bir sonuç).


1
Aritmetik kodlama zaten optimal. Geliştirmeye gerek yok.
Yuval Filmus

@YuvalFilmus evet demek istedim, aritmetik kodlama ile eşit hale getirmek için huffman kodlama geliştirmek nasıl.
Realz Slaw

1
Bir öneri olarak, Asimetrik Sayısal Sistem (ANS) kodlamasını, aritmetik kodlamaya göre daha kolay bulabilirsiniz. Özellikle, bu formülasyonun "kesirli bit paketleme" olarak görülmesi biraz daha kolaydır.
Takma isim

@Pseudonym RANS ve Huffman Kodlaması arasında bu bağlantıyı yapmış gibi görünen bu sayfayı buldum . Henüz anladığımı söyleyemem ama bence yeterli. Yorumu cevaplarsanız kabul edeceğim.
Realz Slaw

@YuvalFilmus Umarım aritmetik kodlamanın iyileştirmeye ihtiyacı olduğu ve ANS'nin bir iyileştirme olduğunu söyledim.
Takma ad

Yanıtlar:


13

Huffman kodlaması hakkında biraz farklı düşünme şekline bakalım.

0.5, 0.25 ve 0.25 olasılıkları olan A, B ve C olmak üzere üç sembolden oluşan bir alfabeniz olduğunu varsayalım. Olasılıkların hepsi ikisinin ters kuvvetleri olduğu için, bu optimal olan bir Huffman koduna sahiptir (yani aritmetik kodlama ile aynıdır). Bu örnek için 0, 10, 11 standart kodunu kullanacağız.

Bizim devlet olarak adlandırdığımız bir büyük tam sayı olduğu varsayalım . Kodlamayı, geçerli durumu alan bir işlev ve kodlanacak ve yeni durumu döndüren bir sembol olarak düşünebilirsiniz:s

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

Şimdi durum 11 ile (ikili olarak 1011) başlayalım, B sembolünü kodlayalım. Yeni durum 46, ikili olarak 101110. Gördüğünüz gibi, bu, dizi 10'un sonuna eklenmiş olan "eski" durumdur. Biz esas olarak bit dizisi 10 "çıktı" var.

Çok uzak çok iyi.

Şimdi bir an için aritmetik kodlamanın nasıl çalıştığını düşünün. Olasılıkları ortak bir payda üzerine koyarsanız, A sembolü aslında aralığı temsil eder , B sembolü[2[04,24)ve C sembolü[3[24,34).[34,44)

Temelde burada yaptığımız her şeyi ortak payda ile çarpmak. Durumun aslında taban 4'te olduğunu düşünün. Bir B sembolünü kodlamak gerçekten bu tabanda 2 rakamını çıkarır ve bir C sembolünü kodlamak o tabanda 3 rakamını çıkarır.

Bununla birlikte, A sembolü biraz farklıdır, çünkü taban 4'te tam bir rakam değildir.

Bunun yerine, alfabeyi A_0, A_1, B, C, eşit olasılıklı simgeler kümesi olarak düşünebiliriz. Bu, yine, optimum bir Huffman koduna 00, 01, 10, 11 sahiptir. Ya da, bunu taban 4'te düşünebiliriz. Bir sembolü kodlamak için sadece şunu yaparız:

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

Şimdi B ve C sembollerinin nasıl kodlanacağı açık, ancak A sembolünü kodlamak için bir seçeneğimiz var. Hangisi ve A 1 kullanacağız?A0A1

Şimdi burada akıllıca bir fikir: Biz devlet bilgilerin bir bit çalmak :s

i=smod2

s=s2
i=smod2

ve sonra .encode(s,Ai)

Önceki örneğimizi kullanarak, , s = 5 ve i = 1 olduğunu buldukve ( 5 , A 1 ) = 4 × 5 + 1 = 21 kodladık . Yeni durum ikili olarak 10101'dir.s=11s=5i=1encode(5,A1)=4×5+1=21

Şimdi bu, Huffman kodlamasıyla tam olarak aynı bit çıktısını üretmez, ancak aynı uzunlukta bir çıktı üretir. Ve umarım görebileceğiniz gibi, bu da benzersiz bir şekilde çözülebilir. Bir sembolün kodunu çözmek için, 4'e bölündükten sonra kalanları alırız. Değer 2 veya 3 ise, sembol sırasıyla B veya C'dir. 0 veya 1 ise, sembol A olur ve sonra durumu 2 ile çarpıp 0 veya 1 ekleyerek biraz bilgi ekleyebiliriz.

Bu yaklaşımla ilgili güzel olan şey, olasılıkların payı ve / veya paydası ikisinin gücü olmadığında, doğal olarak kesirli bit kodlamasına uzanmasıdır. A ve B olmak üzere iki sembolümüz olduğunu varsayalım, burada A olasılığı ve B olasılığı2'dir.35 . Sonra bir sembolü şu şekilde kodlayabiliriz:25

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

s=s3i=smod3encode(s,Ai)

Bu aritmetik kodlamaya eşdeğerdir. Aslında Asimetrik Sayısal Sistemler olarak bilinen bir yöntem ailesidir ve son birkaç yıldır Jarek Duda tarafından geliştirilmiştir. İsmin anlamı açık olmalıdır: sembolünü olasılık ile kodlamakpq

Kodlama yöntemleri ailesi olmasının nedeni, burada gördüğümüz şeyin kendi başına pratik olmamasıdır; durum değişkenini verimli bir şekilde manipüle etmek için muhtemelen sonsuz hassasiyetli tamsayılara sahip olmamanız için bazı değişikliklere ihtiyaç duyar ve bunu başarmanın çeşitli yolları vardır. Aritmetik kodlama, elbette, durumu için benzer bir soruna sahiptir.

Pratik varyantlar arasında rANS ("r", "oran" anlamına gelir) ve tANS ("tablo güdümlü") sayılabilir.

ANS'nin hem pratik hem de teorik olarak aritmetik kodlamaya göre birkaç ilginç avantajı vardır:

  • Aritmetik kodlamanın aksine, "durum" bir çift sözcük yerine tek bir kelimedir.
  • Sadece bu değil, aynı zamanda bir ANS kodlayıcısı ve karşılık gelen kod çözücüsü aynı durumlara sahiptir ve işlemleri tamamen simetriktir. Bu , kodlanmış sembollerin farklı akışlarını araya sokabilmeniz ve her şeyin mükemmel şekilde senkronize edilmesi gibi bazı ilginç olasılıkları artırır .
  • Pratik uygulamaların, elbette, bilgileri gittikçe "çıktılamak" ve sadece sonunda yazmak için büyük bir tamsayıda toplamak değil. Bununla birlikte, "çıktının" boyutu (genellikle mütevazı) sıkıştırma kaybı karşılığında yapılandırılabilir. Dolayısıyla, aritmetik kodlayıcıların bir kerede biraz çıktı alması gerektiğinde, ANS bir seferde bir bayt veya bir çakıl çıktısı verebilir. Bu size hız ve sıkıştırma arasında doğrudan bir denge sağlar.
  • Mevcut nesil donanımda ikili aritmetik kodlama kadar hızlı ve bu nedenle Huffman kodlaması ile rekabet edebilir görünmektedir. Bu onu büyük harfli aritmetik kodlama ve değişkenlerinden (ör. Aralık kodlama) çok daha hızlı yapar.
  • Patentsiz görünüyor.

Bir daha asla aritmetik kodlama yapacağımı sanmıyorum.


4
Şimdi bu gördüğüm ANS kodlamasıyla ilgili en açık açıklama.
Michael Deardeuff

2

Basit bir örnek olarak, her biri 1/3 olasılıklı üç sembolünüz varsa, optimum Huffman kodlamanızda ortalama 5/3 bitlik üç sembol 0, 10 ve 11 kullanılır.

Her biri 1/243 olasılığı olan orijinal sembollerden 5'ini birleştirerek oluşturulan 243 sembol vardır. 1/256'ya çok daha yakın. Optimal Huffman kodlaması, bu grupların 13'ünü 7 bitte ve 230 grupta 8 bitte kodlar, grup başına ortalama 7.9465 bit veya orijinal sembol başına 1.5893 bit, 1.5850 alan aritmetik kodlama ile 1.6667 bit bit.

Yani teoride iki simgeyi daha büyük bir simgede veya üç simgeyi daha büyük bir simgede birleştirebilir ve kombinasyonlar için Hufman kodlamasını kullanabilirsiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.