2020編碼大賽(3)無失真壓縮演算法

2021-10-10 03:01:29 字數 3717 閱讀 4764

無失真壓縮演算法,按照我的理解,可以分為三大塊知識:直接編碼、轉換、上下文編碼。

一,直接編碼

1,哈夫曼編碼

哈夫曼編碼就是把各個字元轉換成不同長度的01串,按照固定的替換規則全文替換即可。

當然,哈夫曼編碼的依據,可以是硬編碼的,也可以是根據文字內容統計計算出來的。

2,算術編碼、區間編碼

這2個編碼方式在我理解差不多,根據不同字元的概率不一樣,把乙個字串編碼成乙個實數。

二,轉換

1,遊程編碼    run-length encoding

輸入: aaabbccccdeeeeeeaaaaaaaaa

輸出: 3a2b4c1d6e9a

這種轉換,是字元到字元的轉換,轉換之後,仍然可以用哈夫曼編碼等從字元轉換成二進位制。

2,bwt轉換演算法    burrows-wheeler transform

bwt演算法,就是壓縮之前把字串a轉換成字串b,壓縮b即可,解壓的時候得到b之後,再把b轉換成a。

例如字串「banana#」轉換為了「annb#aa,其中#是演算法新增的特殊識別符號。

如果字串比較長,轉換後的字串可以出現很長的一段相同字元,所以bwt轉換之後再用別的壓縮演算法,比如lzw,可以提高lzw的壓縮率。

3,滑動視窗(lz系列演算法)

如果abcde出現兩次,第一次出現是在下標3處,第二次出現是在下標13處,那麼第二次出現的abcde就可以用二元組(10,5)表示

三,上下文編碼

上下文編碼,如ppmd、paq 利用的是上下文**,消除二進位制串的重複,達到壓縮的目的。

四,復合壓縮演算法

常見的壓縮演算法,都是轉換+編碼

1,lzw

初始化字典為255個字元,隨著壓縮的過程,字典一步步擴充,最終把全文本轉換成字典的id序列,再用變長編碼的方法,把id序列編碼成二進位制。

2,deflate

lz77 + 哈夫曼編碼

3,lzma

lz77 + 區間編碼

五,我對壓縮演算法的理解

1,壓縮演算法能接力嗎?

不能,無論是先用a壓縮再用a壓縮,還是先用a壓縮再用b壓縮,都沒有效果。

2,有沒有一種無失真壓縮演算法,保證壓縮之後一定比原資料要小?

不存在,無失真壓縮是一種從二進位製流到二進位製流的一一對映,任何一種無失真壓縮演算法,都能找到某個二進位製流,使得用這個演算法壓縮之後長度不變或變長。

也就是說,當資料有重複資訊的時候,通過去除重複資訊可以壓縮資料量,但是如果資料沒有任何重複資訊,壓縮率可能就是接近1或者超過1

3,壓縮演算法為什麼不能接力?

簡單理解,資料可以分為文字資訊、二進位製流、等。

這裡的二進位製流指的是隨機二進位製流,比如乙個常見的exe,它的二進位製流就幾乎是隨機的,壓縮演算法很難壓縮。

理論上來講,所有資料都是二進位製流,都是0和1組成的序列,但是資料的屬性決定了我們如何理解資料。

比如乙個通用英文文字,雖然也是二進位制串,但是26個英文本母的ascii碼對應的8個位元,肯定是大量出現的。

所有的演算法,經過壓縮之後,都會變成二進位製流,剩下的重複資訊就很少了。

所有的演算法,都是幾乎無法壓縮二進位製流的。

4,bwt轉換演算法,只涉及把字元重排,是否可以用在所有壓縮演算法上?比如先用bwt轉換再用ppmd?

不行。通用英文文字,先用bwt轉換再用ppmd,壓縮率比單純的ppmd還小。

bwt轉換可以提高某些演算法的壓縮率,比如lzw,但是並不能提高所有演算法的壓縮率。

因為,同樣的二進位製流,不同的壓縮演算法有不同的理解角度,並不是每個角度看來,字串重排都變得更加規整。

例如,我的演算法依據是,當乙個單詞是字母e開頭的時候,下乙個字母大概率是n,(隨便舉的例子)

也就是說空格符合字母e連續出現的話,下乙個字母大概率是n,那麼這就是我消除重複的乙個依據,如果重排就沒有這個依據了。

這裡說的對資料的理解角度,還有演算法依據,其實都是資料本身的特點。

5,資料有哪些特點可以用來壓縮?這些特點是怎麼來的?

如果把01串看成數列,那麼所有我們能想到的數列規律,都能以某種形式展現在某個01串的,但是並不是所有的都能用來壓縮。

反過來,對於乙個01串,可以用任意角度去理解它,如果某個角度看來,它具有一種重複性的規律,那麼就可以用來壓縮。

這麼說還是太主觀了,或許還是用熵來表述更為精確。

資料的特點,自然是來自產生資料的源,比如文字,來自人類交流的語料庫,有語法限制,字母按照一定的規則組合成詞,漢字按照一定的規則組合成詞,比如,來自大自然,由於地球(宇宙)上的原子排列是有規律的,原子都是扎堆出現的,而光學原理是簡潔而和諧的,所以拍出來的**總是以色塊的形式展現出來。

再比如,假設我在手算圓周率pi,需要記錄一串實數:

3,   3.1,   3.14,   3.141,   3.1415   ......

顯然,這串資料把它當做通用文字壓縮,也會有不錯的壓縮率,應該比一般的通用文字壓縮率更高。

但是,如果我確定所有的資料都是pi的前若干位,而pi的前10000萬都是確定的,那麼以此規律為基礎,就可以自創乙個壓縮演算法,針對此類資料壓縮率很高。

上面的串其實就可以轉換成0   1   2   3   4   ......

如果規律變得複雜一點,每個數都是pi的前若干位向上或者向下取整,比如:

3,   4,   3.1,   3.2,   3.14,   3.15   ......

那麼,壓縮演算法肯定要複雜一點。

如果再允許一點誤差,比如3.16也是有可能出現的,但是統計規律顯示3.16出現的概率遠小於3.14和3.15,那麼我們仍然可以定製壓縮演算法,使得壓縮率遠高於通用壓縮演算法。

總之,資料的特點,無論是數學公式的強規律,還是基於統計的弱規律,都可以用來壓縮。

6,什麼是資訊?什麼是熵?

資訊是由資料來承載的。

個人理解:資料的資訊,是乙個主觀的屬性,而資訊的資訊熵,是乙個客觀的屬性。

就像文字,它所傳達的資訊到底是01串還是字串,這是乙個主觀的,甚至我們可以把某個01串先按照計算公式轉換成3,   3.1,   3.14,   3.141,   3.1415   ...... ,再按照pi的數值作為對照表,把序列轉換成0   1   2   3   4   ......,然後說這才是這個01串表達的資訊。

也就是說,資訊是由資料+理解資料的角度決定的

而在每乙個角度之下,這個資料的資訊熵都是乙個確定的量,同乙個資料在不同的角度下資訊熵不一樣

再舉個例子,如果乙個文字全都是數字和空格組成的,那麼我們可以說,這個文字熵比較低。

如果我們又知道,這個文字其實是一串正整數的最簡表示,那麼它的熵更低了,因為我們排除了形如01 02 03這樣的文字,因為01不是任何正整數的最簡表示,當然,形如額外約定用第乙個數字表示正負的規則除外,這又是一種新的理解這個文字的角度。

所以,這個文字可以是這樣的:1   3     124    56     2     38   ......

如果我們又知道,每個整數都是素數,比如2     13    5    7   11   5    97  ...... 這樣的串,那麼熵就更低了。

所以,熵表示的是不確定性,規律越嚴格,熵越低

熱力學裡面的熵,和資訊學裡面的熵,本質上是一樣的。

ps:2     13    5    7   11   5    97  ...... 這樣的素數串,如果看做通用文字,先用bwt轉換,再用任何壓縮演算法壓縮都不好用了。

這也是乙個例子,可以用來幫助理解為什麼bwt轉換針對文字並不具有普適性。

2020編碼大賽(5)半決賽

2020編碼大賽題目 半決賽,是32個隊伍選出8個隊伍。一,需求變更 我的解讀 1,檔案大小是1024的倍數 2,可以混合裝載 3,排程階段可以訪問檔案 二,壓縮演算法 在寫了乙個很簡單的lzw演算法之後,經過多日的攻堅,終於把ppmd寫出來了。壓縮率 2 7,也就是說一般情況下可以裝載7份 這裡列...

無失真信源編碼

1 信源編碼 質量一定,如何提高資訊傳輸速度 編碼效率,壓縮比 2 通道編碼 通道傳輸速度一定,如何提高資訊傳輸質量 抗干擾能力 信源編碼 以提高通訊有效性為目的的編碼。通常通過壓縮信源的冗餘度來實現,採用的一半方法是壓縮每個信源符號的平均位元數或信源的位元速率 bit 符號 即同樣多的資訊用較少的...

杭電oj編碼2020

問題描述 輸入n n 100 個整數,按照絕對值從大到小排序後輸出。題目保證對於每乙個測試例項,所有的數的絕對值都不相等。輸入 輸入資料有多組,每組佔一行,每行的第乙個數字為n,接著是n個整數,n 0表示輸入資料的結束,不做處理。輸出 對於每個測試例項,輸出排序後的結果,兩個數之間用乙個空格隔開。每...