1 Shannon és Huffman kód konstrukció tetszőleges véges test felett Mire is jók ezek a kódolások? A szabványos karakterkódolások (pl. UTF-8, ISO-8859 ) általában 8 biten tárolnak egy-egy karaktert. Ha tudjuk, hogy a szövegben melyet át akarunk küldeni valahova nem használjuk fel az összes létező karaktert, akkor egy új fajta kódolással, amely csak azokra a karakterekre vonatkoznak melyek üzenetünkben állnak, lecsökkenthetjük a küldendő kódunk hosszát. Ezeket változóhosszú kódolásoknak is szoktuk nevezni hiszen egy-egy karakterkód hosszúsága nem feltétlen egyezik meg. A kódolások elméleti háttere Egy ilyen kódolási módot dolgozott ki Claude Shannon és Robert Fano. Módszerük röviden, érthetően leírva: a szövegben lévő karakterek előfordulása alapján sorrendbe állítjuk majd ezt a listát két részre osztjuk úgy hogy a két részben lévő előfordulások összege közel azonos legyen. Majd az így kapott részekre újra megismételjük ezt, amíg már csak egy tagú részhalmazok nem maradnak. A művelet után egy bináris fát kapunk, ennek éleit rendre elnevezzük úgy, hogy a bal élek 0-ás, míg a jobb élek az 1-es számot kapják. Így megkapjuk az úgynevezett kódfát. Egy karakter kódját pedig megkapjuk, ha a gyökértől az odavezető élek nevét leírjuk jó sorrendbe. (A példában tehát az D-nek a kódja 110) Példa:
2 Egy másikfajta módszer megalkotója, ugyancsak erre a problémára David A. Huffman. Ő is a karakterek előfordulását vizsgálta először és ugyancsak egy bináris kódfát épít fel a következő módon: Kiválasztjuk a sorozat két legkisebb gyakoriságú elemét, amely egy háromcsúcsú bináris fa két levele lesz (amelyeket a gyakorisággal címkézzük meg), majd ezekhez hozzárendelünk egy gyökeret, amelyet a két gyakoriság összegével címkézünk meg. Ezután a két vizsgált elemet kitöröljük a sorozatból, és azok összegét beszúrjuk az érték szerinti megfelelő helyre. Ezután folytatjuk az előző műveletet mindaddig, amíg van elem a sorozatban. A fa éleit a már a Shannon módszernél leírtak szerint elnevezzük és a karaktereket is hasonló módon látjuk el a megfelelő kódjaikkal. Példa:
3 Kódolások megvalósítása Maple illetve Sage-ben Maple Párhuzamosan fogunk haladni, a kétfajta kódolással mivel teljesen megegyezik a két módszer a bináris fafelépítést eltekintve. 1. lépés: A szöveg betűinek megszámlálása Erre tökéletes a StringTools csomagban lévő CharacterFrequencies() függvény. Azonban ez még nem állítja növekvő sorrendbe (egyszerűen csak berakjuk őket egy halmazba) illetve később majd úgy kell nekünk hogy a darabszám legyen elől és utána a karakter. Erre szolgál a Freq() függvény. 2. lépés: A bináris fák előállítása listás ábrázolással Shannon-fa: Tulajdonképpen az lett lekódolva amit fent szabadabban megfogalmaztunk. n- ben tároljuk azt hogy hány karakter van a listánkban, split azt mutatja meg hanyadik karakternél kell szétválasztani két részre a listát, cumul-al pedig azt számoljuk hogy a két részhalmazban az előfordulások összege közel azonos legyen, mindezt egy ciklus segítségével. Majd rekurzívan meghívjuk, a kiszámolt helyen szétválasztva, önmagát, úgy hogy külön listába kerüljenek a szétválasztott részek. (persze az egész egy nagy lista marad)
4 Huffman-fa: Ugyancsak a fentiekben már leírt módon dolgozunk itt is. Meghívjuk rekurzív módon önmagát, úgy hogy az első két elem már ne legyen benne, hisz annak az összegét uniózzuk hozzá (kihasználva, hogy halmaz típust hoz létre a Freq() függvényünk). Tehát kialakult a két bináris fánk: 3.lépés: Karakter kódjainak generálása Ugyancsak rekúrzív módon dolgozunk itt is úgy, hogy a párokba rendezett listában a pár első eleméhez 0-t a másodikhoz 1-et rendel. 4.lépés: A szöveg és a karakterkódok egyeztetése Erre tökéletesen alkalmas az ugyancsak a StringTools csomagból az Explode() függvény ezt minden tábla-béli elemre meghívva és a cat() függvény segítségbevételével egy egész számsorrá gyúrhatjuk a szöveget:
5 Láthatjuk, hogy a Huffman kódolás jóval hatékonyabb. Ha már itt tartunk számoljuk ki mennyi bitet spóroltunk a kódolásokkal. Az eredeti szöveg 66 karaktert tartalmaz ez szabályos kódolással 528 bit, Shannon kódunk hossza: 413 Huffman kódunké: 251 tehát spóroltunk 115 illetve 277(!) bitet egyetlen mondat lekódolásával. 5.lépés: Dekódolás Dekódoláshoz létrehozunk egy segédvektort, ami olyan hosszú, mint a dekódolandó szöveg ebbe a vektorba írjuk bele egyesével a megfelelő betüket a megfelelő helyre úgy hogy a kódfában haladunk mindig a megfelelő irányba.a végén a StringTools csomagból az Implode() függvény ad segítséget arra hogy egy egész szöveg legyen a vektorból. Példa egy betű menetének megtalálása:
6 Sage Sage-ben könnyebb dolgunk van, hiszen a Huffman-kódolost ott már implementálták sage.coding.source_coding.huffman osztályból elérhetjük.