編碼 | 解碼 | 壓縮

> mtf | move | front <

// Move-to-Front —— 為更佳壓縮效果而動態重排清單

[ADAPTIVE]

自我調適

會自動適應資料中的區域模式。

[LOCALITY]

善用區域性

最近出現的符號擁有較小的索引,壓縮率更佳。

[BZIP2]

bzip2 的一部分

在 bzip2 壓縮流程中,通常用於 BWT 之後的階段。

>> 技術說明

MTF 的運作方式:

MTF 維護一個包含所有可能符號的清單。當編碼某個符號時,會輸出該符號在清單中的目前位置,然後將它移到清單最前端。如此一來,最近使用的符號會集中在前端、索引較小,而後續的熵編碼就能更有效率地壓縮資料。

編碼範例:

文字:"banana" 初始清單:[a,b,c,d,...] "b":索引 1,將 b→前端 [b,a,c,d,...] "a":索引 1,將 a→前端 [a,b,c,d,...] "n":索引 13,將 n→前端 [n,a,b,c,...] "a":索引 1,將 a→前端 [a,n,b,c,...] "n":索引 1,將 n→前端 [n,a,b,c,...] "a":索引 1,將 a→前端 [a,n,b,c,...] 輸出:[1,1,13,1,1,1]

為什麼要使用 MTF:

  • >提升區域重複資料的可壓縮性
  • >與 BWT 有良好搭配
  • >實作簡單
  • >可逆轉換
  • >可依模式自動調整

>> 常見問題

什麼是 Move-to-Front 編碼?

MTF 是一種資料轉換演算法,會將每個符號編碼為在動態更新清單中的索引。每次完成編碼後,該符號會被移到清單最前端,讓經常出現的符號擁有較小的索引。

為什麼要把 MTF 和 BWT 一起使用?

BWT 會把相似的上下文集中在一起,產生許多區域重複。MTF 再把這些重複轉成較小的數字(包含大量 0 和 1),非常適合接續使用區段長度編碼或 Huffman 編碼來進一步壓縮。

MTF 的清單是怎麼運作的?

清單一開始包含依序排列的 256 個可能位元組值。隨著符號被編碼,已使用的符號會移到清單前端。最近使用的符號會停留在前端附近、索引較小,而長期未使用的符號則會被推向尾端、索引變大。

MTF 和其他轉換相比有何不同?

MTF 是為接在 BWT 後面而設計的。單獨使用時效果有限,但在將 BWT 輸出轉換成更容易壓縮的形式方面非常出色。與算術編碼相比,它實作更簡單,但在壓縮最優性上略遜一籌。

// 計算範例

#SymbolIndexList
1b1abcdefg…
2a1bacdefg…
3n13abcdefg…
4a1nabcdef…
5n1anbcdef…
6a1nabcdef…

// 程式碼範例

Input     banana       initial list: a b c d ... z (index from 0)
Output    1 1 13 1 1 1
Encode    output the index of the symbol, then move it to the front
Decode    read index, output list[index], move it to the front
Use       after BWT: runs of equal symbols become runs of 0s,
          which RLE and Huffman/arithmetic coding then compress well (bzip2)

>> 更多問題

問:Move-to-Front 有什麼用?

答:MTF 本身不是壓縮,而是一種轉換:最近出現的符號獲得較小的索引,產生大量 0 和 1,便於後續熵編碼(霍夫曼、算術編碼)壓縮。

問:它與 Burrows-Wheeler 轉換有什麼關係?

答:BWT 會把相同字元聚成連續段,MTF 再把它們變成一串小數字,尤其是 0。bzip2 使用的就是 BWT → MTF → RLE → 霍夫曼 這條鏈。

問:MTF 是無損且可逆的嗎?

答:是。解碼端從相同的初始清單出發,重複相同的移動即可還原。初始清單(字元集與順序)兩端必須一致。

其他語言