luo weifeng 2011-7-3
宣告: 演算法不專業,高手請繞行。
bwt(
burrows-wheeler transformation)演算法在人類基因組測序方面有很重要的應用,開放原始碼的bzip就是bwt壓縮演算法的成功案例。關於這裡的其他知識可以去看維基百科。這篇文章主要介紹我設計的乙個生成bwt演算法所需的 l(也就是輪換矩陣最後一列)的桶排序的方法。
問題輸入:乙個2 m的人類基因組一條基因的序列chr1.fa。檔案內容是nacgt字母的亂序。整個檔案是乙個完整的序列。
要求輸出: bwt演算法的l串。
演算法分析:
資料模型:
演算法所需要的資料儲存在堆中的乙個區域,這個區域的頭為指標p,區域長度為n。那麼第乙個字串便是從p到p+(n-1)。第a個字串的第b個元素為 p+(a + b)%n。
f a(b)= p+( a + b)%n.
核心思想:
演算法的核心思想就是利用人類基因組串內有用字元只有acgt的特點,對數百萬個基因串進行桶排序,並且對每乙個子桶也進行相同的桶排序,直到桶裡邊的元素只剩下1個或0個,觸法桶的收集。桶的收集在檢查到父桶可以合併時觸法合併,直到合併完成。
詳細:桶存放的是串標識。桶裡邊的元素4,就表示第5個串,按照上頁得公式便表示從p+(5+0)%n到p+(5+n-1)%n的串。
預處理:首先由預處理程式從檔案中讀入原始資料檔案,對所有的n進行過濾,並將其他內容載入到內容堆中的乙個字元陣列中。然後初始化乙個0桶,這個桶包含了所有的字串(桶裡邊只存的是字串所在的偏移,比方說,我存了4,那麼就表示自 p+4 到p + (4 + n-1)%n的那個字串行)。
分發:由控制程式將0桶傳遞給分發程式進行分發處理。分發程式按照字串行的首個字母是a還是c、g、t,把這些字元標示分發到0a、0c、0g、0t桶裡邊。並且一邊分發一邊統計分發到這些桶裡的entry數量,若數量大於等於2則繼續下一層分發,否則對桶做標記,並觸發收集。(比如:如果檢測到桶0aa的資料條目少於兩條,將桶0aa重新命名為桶$aa)。
收集:收集時先檢測同目錄的桶是不是都被收集,若有桶沒有收集,則放棄執行,否則生成父收集桶,然後將四個子桶的資料收集到父桶之中。如果父桶不是$(最終桶),則觸發父桶的收集。(同樣接著前面的例子:現在觸發了對桶$aa的收集,則首先檢測$ac、$ag、$at是否存在,如果有乙個不存在則放棄執行並退出,如果都存在則建立父收集桶$a,並把$aa、$ac、$ag、$at裡邊的資料收集到父桶$a中)
收尾:程式到這裡,頂層收集桶$已經生成。依次提取桶中的串,輸出此串的最後乙個字元。即可得到bwt輪換矩陣的最後一列l。比如在裡邊拿到乙個int資料a,則需要輸出的是p+(a+n-1)%n。
問題: 這裡最直接的乙個問題就是,桶作為乙個檔案時,檔案的名稱的長度會隨著原始資料的增長而同步增長。解決的辦法是,在邏輯上還是使用剛才提到的方法,而在實際使用桶時,使用此桶名的32位md5值作為實際的檔名稱。
還有乙個問題,就是如果使用上面介紹的方法時在操作上會出現記憶體不夠、堆疊溢位的情況,解決的方法也很直接,通過第三方控制函式對這兩個原子操作進行控制,徹底拋棄遞迴方法。這個在以後慢慢改過來,現在貼乙個遞迴的實現,注意,這個程式有bug,主程式我會在有時間了把控制程式加進去,就可以避免記憶體問題了。
想了想還是直接上傳工程吧,工程是code::blocks的工程,使用標準c,現在的工程還很爛,等過幾天改改。
演算法的優缺點: 缺點很明顯了,就是需要大量的檔案操作,需要動態的建立和刪除檔案,但是優點也是很明顯的,整個生成過程不需要比較操作,操作被原子的分為了分發和收集,醬紫的模型與分布式hadoop幾乎完全一樣,也就是說,這樣的模型很容易被擴充套件到分布式處理應用當中,所以,儘管在單機看來,不如其他一些成型的演算法,也不如桶排加快排的做法,但是可以很容易的擴充套件到分布式處理當中,那時候效能的提高就非常明顯了。
演算法之桶排序
桶排序是計數排序的公升級版。它利用了函式的對映關係,高效與否的關鍵就在於這個對映函式的確定。桶排序 bucket sort 的工作的原理 假設輸入資料服從均勻分布,將資料分到有限數量的桶裡,每個桶再分別排序 有可能再使用別的排序演算法或是以遞迴方式繼續使用桶排序進行排 注意,如果遞迴使用桶排序為各個...
演算法之桶排序
思想 正如網上大部分文章所說,桶排序就是把原始陣列的資料防放入各個桶中。然後對桶再排序,然後把每個桶的資料依次輸出到原始陣列就可以了,我自己寫了個簡陋版本的,不求效率,只求簡易實現。我自己寫這個效率很低,有時間再改進吧。public class bucketsort long a system.cu...
排序演算法之桶排序
1 設定乙個定量的陣列當作空桶子 2 尋訪序列,並且按照要求把記錄乙個乙個放到對應的桶子去 3 對每個不是空的桶子進行排序。4 從不是空的桶子裡把專案再放回原來的序列中。include include include include typedef struct node node,list voi...