資料壓縮演算法 1入門介紹

2021-09-03 01:26:18 字數 3480 閱讀 8074

無失真壓縮演算法設計:對原始資料在單字元、單詞或片語等不同單位上出現的頻率構建統計模型,然後將頻率最高的單位編碼成最短的編碼,但最短的編碼永遠小於整條資訊的熵,即整條資訊所需的位數。

什麼是熵

資料壓縮不僅起源於 40 年代由 claude shannon 首創的資訊理論,而且其基本原理即資訊究竟能被壓縮到多小,至今依然遵循資訊理論中的一條定理,這條定理借用了熱力學中的名詞「熵」( entropy )來表示一條資訊中真正需要編碼的資訊量:

考慮用 0 和 1 組成的二進位制數碼為含有 n 個符號的某條資訊編碼,假設符號 fn 在整條資訊中重複出現的概率為 pn,則該符號的熵也即表示該符號所需的位數字為:

en = - log2( pn )

整條資訊的熵也即表示整條資訊所需的位數為:e = ∑en

舉個例子,對下面這條只出現了 a b c 三個字元的字串:

aabbaccbaa

字串長度為 10,字元 a b c 分別出現了 5 3 2 次,則 a b c 在資訊中出現的概率分別為 0.5 0.3 0.2,他們的熵分別為:

ea = -log2(0.5) = 1

eb = -log2(0.3) = 1.737

ec = -log2(0.2) = 2.322

整條資訊的熵也即表達整個字串需要的位數為:

e = ea * 5 + eb * 3 + ec * 2 = 14.855 位

回想一下如果用計算機中常用的 ascii 編碼,表示上面的字串我們需要整整 80 位呢!現在知道資訊為什麼能被壓縮而不丟失原有的資訊內容了吧。簡單地講,用較少的位數表示較頻繁出現的符號,這就是資料壓縮的基本準則。

細心的讀者馬上會想到,我們該怎樣用 0 1 這樣的二進位制數碼表示零點幾個二進位制位呢?確實很困難,但不是沒有辦法。一旦我們找到了準確表示零點幾個二進位制位的方法,我們就有權利向無失真壓縮的極限挑戰了。

模型從上面的描述,我們明白,要壓縮一條資訊,首先要分析清楚資訊中每個符號出現的概率。不同的壓縮程式通過不同的方法確定符號的出現概率,對符號的概率計算得越準確,也就越容易得到好的壓縮效果。在壓縮程式中,用來處理輸入資訊,計算符號的概率並決定輸出哪個或哪些**的模組叫做模型。

難道對資訊中字元的出現概率這麼難以估計以至於有各種不同的壓縮模型嗎?對上面的字串我們不是很容易就知道每個字元的概率了嗎?是的是的,不過上面的字串僅有 10 個字元長呀,那只是例子而已。考慮我們現實中要壓縮的檔案,大多數可是有幾十 k 甚至幾百 k 長,幾 m 位元組的檔案不是也屢見不鮮嗎?

是的,我們可以預先掃瞄檔案中的所有字元,統計出每個字元出現的概率,這種方法在壓縮術語裡叫做**「靜態統計模型」。但是,不同的檔案中,字元有不同的分布概率,我們要麼先花上大量的時間統計我們要壓縮的所有檔案中的字元概率,要麼為每乙個單獨的檔案儲存乙份概率表以備解壓縮時需要。糟糕的是,不但掃瞄檔案要消耗大量時間,而且儲存乙份概率表也使壓縮後的檔案增大了不少。所以,在實際應用中,「靜態統計模型」應用的很少。

真正的壓縮程式中使用的大多是一種叫「自適應模型」的東西。自適應模型可以說是一台具有學習功能的自動機。他在資訊被輸入之前對資訊內容一無所知並假定每個字元的出現概率均等,隨著字元不斷被輸入和編碼,他統計並紀錄已經出現過的字元的概率並將這些概率應用於對後續字元的編碼。也就是說,自適應模型在壓縮開始時壓縮效果並不理想,但隨著壓縮的進行,他會越來越接近字元概率的準確值,並達到理想的壓縮效果。自適應模型還可以適應輸入資訊中字元分布的突然變化,可以適應不同的檔案中的字元分布而不需要儲存概率表。

上面提到的模型可以統稱為「統計模型」**,因為他們都是基於對每個字元出現次數的統計得到字元概率的。另一大類模型叫做「字典模型」。實際上,當我們在生活中提到「工行」這個詞的時候,我們都知道其意思是指「中國工商銀行」,類似的例子還有不少,但共同的前提是我們心中都有一本約定俗成的縮寫字典。字典模型也是如此,他並不直接計算字元出現的概率,而是使用一本字典,隨著輸入資訊的讀入,模型找出輸入資訊在字典中匹配的最長的字串,然後輸出該字串在字典中的索引資訊。匹配越長,壓縮效果越好。事實上,字典模型本質上仍然是基於對字元概率的計算的,只不過,字典模型使用整個字串的匹配代替了對某一字元重複次數的統計。可以證明,字典模型得到的壓縮效果仍然無法突破熵的極限。

當然,對通用的壓縮程式來說,儲存一本大字典所需的空間仍然是無法讓人忍受的,況且,任何一本預先定義的字典都無法適應不同檔案中資料的變化情況。對了,字典模型也有相應的「自適應」方案。我們可以隨著資訊的不斷輸入,從已經輸入的資訊中建立合適的字典,並不斷更新這本字典,以適應資料的不斷變化。

讓我們從另乙個角度理解一下自適應模型。cluade shannon 曾試圖通過乙個「聚會遊戲」(party game)來測定英語的真實資訊容量。他每次向聽眾公布一條被他隱藏起乙個字元的訊息,讓聽眾來猜下乙個字元是什麼,一次猜乙個,直到猜對為止。然後,shannon 使用猜測次數來確定整個資訊的熵。在這個實驗中,一種根據前面出現過的字元估計下乙個字元概率的模型就存在於聽眾的頭腦中,比計算機中使用的自適應模型更為高階的是,聽眾除了根據字元出現過的次數外,還可以根據他們對語言的經驗進行猜測。

編碼通過模型,我們已經確定了對某乙個符號該用多少位二進位制數進行編碼。現在的問題是,如何設計一種編碼方案,使其盡量精確地用模型計算出來的位數表示某個符號。

最先被考慮的問題是,如果對 a 用 3 個二進位制位就可以表示,而對 b 用 4 個二進位制位就可以表示,那麼,在解碼時,面對一連串的二進位製流,我怎麼知道哪三個位是 a,哪四個位是 b 呢?所以,必須設計出一種編碼方式,使得解碼程式可以方便地分離每個字元的編碼部分。於是有了一種叫**「字首編碼」**的技術。該技術的主導思想是,任何乙個字元的編碼,都不是另乙個字元編碼的字首。反過來說就是,任何乙個字元的編碼,都不是由另乙個字元的編碼加上若干位 0 或 1 組成。

看一下字首編碼的乙個最簡單的例子:

符號 編碼

a  0

b  10

c  110

d  1110

e  11110

有了上面的碼表,你一定可以輕鬆地從下面這串二進位製流中分辨出真正的資訊內容了:

1110010101110110111100010 - dabbdceaab

下乙個問題是:象上面這樣的字首編碼只能表示整數字的符號,對幾點幾位的符號只能用近似的整數字輸出,那麼怎樣輸出小數字數呢?科學家們用算術編碼解決了這個問題。

總結一下

不同的模型使用不同的方法計算字元的出現概率,由此概率可以得出字元的熵;然後使用不同的編碼方法,盡量接近我們期望得到的熵值。所以,壓縮效果的好壞一方面取決於模型能否準確地得到字元概率,另一方面也取決於編碼方法能否準確地用期望的位數輸出字元**。換句話說,壓縮 = 模型 + 編碼。如下圖所示:

符號      概率      **

輸入 ---------------> 模型 ---------------> 編碼 ---------------> 輸出

資料壓縮演算法

之前在聽到資料壓縮的時候,想著肯定是某些高深莫測的演算法,能夠完成資料的壓縮這種事情,最近看了看,嗯,至少咱還是能看懂的.眾所周知,不管你是exe,word,txt,dmg等等,在儲存上都是以二進位制進行儲存的,所以,在討論壓縮時,忽略檔案格式即可,只要將其看做一串數字即可.開始了,上數字串 111...

LZW資料壓縮演算法

表4 15 詞典 碼字 code word 字首 prefix 1 193 a194b 255 1305 abcdefxyf01234 lzw編碼器 軟體編碼器或硬體編碼器 就是通過管理這個詞典完成輸入與輸出之間的轉換。lzw編碼器的輸入是字元流 charstream 字元流可以是用8位ascii字...

資料壓縮演算法LZO C

lzo 是致力於解壓速度的一種資料壓縮演算法,lzo 是 lempel ziv oberhumer 的縮寫。這個演算法是無損演算法,參考實現程式是執行緒安全的。lzo 庫實現了許多有下述特點的演算法 解壓簡單,速度非常快。解壓不需要記憶體。壓縮相當地快。壓縮需要 64 kb 的記憶體。允許在壓縮部分...