1. 程式人生 > >噴泉碼的原理詳解以及實現

噴泉碼的原理詳解以及實現

      噴泉碼是一類基於圖的線性糾刪碼,在廣播方式的通訊系統中,傳送端對原始資訊進行編碼,得到源源不斷的編碼資訊並且傳送,只要接收端能正確接收到足夠的編碼資訊就可以譯出原始資料信源,反饋重傳的差錯摔制方式相比,其更為有效,尤其適用於深空通訊環境。LT碼是一種典型的噴泉碼,本文將介紹LT碼的編譯碼過程及思路推導,具體的程式碼我寫了3份,一份是c++的,將LT碼的整體功能封裝為了一個類,如果要使用只需註冊一個傳送回撥函式即可使用,另一份是純c語言編寫的,這一份c語言的提供了LT碼的各種編譯碼功能函式,還有一份是matlab的,方便理解數學推導過程,我的程式碼放在GitHub上,網址為:。如果你使用覺得還可以請為我點一顆星。下面我將開始介紹噴泉碼的設計思路以及編譯碼過程。

噴泉碼的設計需要主要考慮2方面的問題:①譯碼開銷儘量小,使其趨近於0;②編譯碼複雜度儘量低:理想情況下,希望做到每個編碼分組需要的運算量是一個與K無關的常量,獲得K個原始資料分組的成功譯需要的運算量是K的線性函式。,下面就介紹一下LT碼的編譯碼過程。

1. LT碼的編碼演算法

      LT碼作為第一種實用的噴泉碼,其編碼過程較為簡單,下面就某一編碼包的產生過程介紹如下:

①  由已定的度分佈ρ(d);

②  隨機選取一個度值d;

③  將這d 個不同的資料包求異或和,生成該編碼包。

具體過程如下圖所示

      不斷重複上面的步驟,就可以得到無限多個編碼分組。在這些步驟中一些細節需要注意:LT 碼編碼之前要先確定度分佈函式,度值的確定由度分佈函式來計算。不同的度分佈,k的概率值是不同的,但度分佈概率函式只是確定了取度值為d的概率是多少,而並不能確定這d個原始編碼分組是哪些,所以對於這d個原始編碼分組的選擇來說是任意的,本文對這d個原始編碼分組的選擇採用均勻分佈來進行選取,即從區間[1,k]中按均勻分佈隨機生成d個整數。區間[1,k]中所有整數被選取的概率是相等的。把這d個整數進行異或,就得到了一個編碼分組。

      譯碼演算法本文就只介紹GE(高斯消元法),BP演算法其實就是GE方法的簡單版,GE是每接收到資料包就對生成矩陣進行恢復,而 BP演算法僅在接收到度數為1的訊息包時才進行譯碼。BP演算法的好處是演算法複雜度較低(GE演算法每次收到資料包就進行恢復,會對接受方的譯碼效能有要求),壞處就是當度數為1的包丟失時無法譯碼,造成接收方等待時間過長,誤位元速率高等情況,下面就來介紹LT碼的譯碼演算法。

2.LT碼的譯碼演算法

      編碼器在編碼後會給每一個生成的資料包伴隨一個生成向量,比如:我的原始編碼分組有10個,我生成的訊息包度數為3,由原始編碼分組的第1個,第3個,第5個得到,那麼我的伴隨向量就為[1 0 1 0 1 0 0 0 0 0]';通過編碼,我將源源不斷的獲得訊息包和伴隨向量,接收方將收到的訊息包和伴隨向量組合起來就是收到的訊息矩陣和伴隨矩陣,伴隨矩陣進行高斯消元,同時對訊息矩陣做同樣的行列變換,當伴隨矩陣的秩等同於其行數時,那麼,訊息矩陣就可以成功恢復了。示例如下:

      

      伴隨矩陣經過高斯消元后,秩為8,說明還未成功恢復出來,但其對角元的第一行至第四行均為1,說明其第1到第4個數據包均已得到成功恢復,再繼續接收資料包,等其對角元均為1後(等同於秩為10),則說明原始資料的10個編碼分組均已得到成功恢復。

      說的這麼複雜,總結一下,譯碼過程就是編碼過程的逆,編碼過程就是先生成一個度分佈,然後每次要生成資料包時,去度分佈裡隨機抽取一個,得到度數d,然後去編碼分組裡抽d個出來做異或,同時將做異或的資料包通過一個向量來記錄,傳送時將向量和訊息一同發出,接收呢就是把訊息包收到後再通過異或運算將其對應的伴隨向量消除的只剩一個1就行啦。

      LT碼的編譯碼演算法我覺得其實不是難點,難點在於度分佈函式的設計,如果我們需要傳輸l個位元,那麼我們可以將其分為m個輸入分組,每個輸入分組中包含n個位元,其中l=m×n。我們根據噴泉碼的原理將這m個輸入分組進行編碼,編碼之後生成p個輸出分組,我們可以將每個分組看作一個符號,輸入分組就是輸入符號,輸出分組就是輸出符號。良好的度分佈函式的作用就是保證編碼的時候,這m個分組均有機會參與到混合過程來,這樣才能保證譯碼的時候不會因為有一個數據包沒有參與到編碼或者傳送時丟包,遲遲無法譯碼的問題,如何設計度分佈函式呢?先思考一個問題,假設獨立地把n個球扔到k個筐中,當n和k很大時,求每個筐中至少有一個球的概率。這個問題就可以看作是一個度分佈,每一次投球的過程中,只有一個筐可以接到這個球,而每個筐接到這個球的概率是相等的,都是1/k,所以這種度分佈可以看作是均勻分佈。我們把每個球看作一個編碼符號,它就表示所有的編碼符號的度數都是1,而成功譯碼的前提就是每個筐中都有球。

      在k 保持不變且n≥k 時,n 越大,每個筐中至少有一個球的概率越大,而經過概率論的知識可以求得,在k不變時,若要使每個筐中都有球的概率是1 -p,則需要球的數量為:

          n =k ln(k /p )(這裡是約等於)

      而將n 個球獨立地扔到k 個筐中,空筐數量的期望也可求得是k*e^(-n/k)。可見我們如果要保證每個容器中都有球,就必須要扔很多的球,讓期望儘可能是一個很小的數值x ,而這時就需要n > k ln(k /p )。