【LB】稀疏矩陣的快速轉置原理及其算法

    關於稀疏矩陣的快速轉置法,首先得明白其是通過對三元表進行轉置。如果誤以爲是對矩陣進行轉置,毫無疑問就算你想破腦袋也想不出個所以然,別陷入死衚衕了!

         對於一個三元表,行爲i,列爲j,值爲v。需將其ij的值對調才能得到新的三元表,但是如果直接進行轉換,得到的新的三元表的順序是混亂的,不符合三元表的規則。所以,課本首先介紹了一個用掃描來轉置的算法(這個算法比較容易,在這裏我就不說了),但是這個轉置算法的時間複雜度太高,於是就有了接下來的快速轉置算法。

 

         要你對一個三元表進行步驟最少的轉置,你可能會想,如果知道三元表中每一項在轉置後的新的三元表中的位置,然後直接放進去,豈不是極大的縮小了時間複雜度?沒錯!快速轉置法正是基於這種思想而設計的。



        那麼如何知道三元表中某一項的位置呢?在課本98頁的a.data這個三元表可以看到,j爲列號,在轉置後即爲新的三元表的行號,三元表正是按照行序進行排列的,而j=12個、j=22個、j=32個、j=41個、j=61個。根據這些數據按照從小到大排列,j=1的項在新的三元表中應占據第12位,j=2的項在新的三元表中應占據第34位,j=3的項在新的三元表中應占據第56位,j=4應占據第7位,j=6應占據第8位。

         接下來就輕鬆多了,轉置的時候直接從第一項讀起,讀取其j值,比如課本中a.data這個三元表的第一項的j值爲2,因爲j=2佔據第34位,所以應該從第三位開始放,接下來如果讀取的某一項的j值也是2,就放在第4位。因爲j=2的項只有兩個,所以第5位絕對不會被j=2的項佔據,第56項本來就是留給j=3的。再比如當讀到j=6的那項時,第8位是留給它的,就可以直接放進第8位了。這樣,讀取每一項,都能在三元表中找到相應的位置,這就是稀疏矩陣快速轉置的原理。

         當然,上面只是快速轉置的原理,要實現它,就要設計算法來實現了。首先,我們需要兩個變量。第一個num[col]用於記錄原三元表中列數爲col的項的數目,例如col=3時,num[col]=2;第二個cpot[col]用於記錄原三元表中列數爲col的項在新三元表中的首位置,例如col=3時,cpot[col]=5。你可以打開書本第99頁,我想你現在應該是能看懂表5.1了吧。



         接下來說一說快速轉置算法的具體事項,在課本的100頁代碼如下:


逐句解釋:

  此函數名爲FastTransposeSMatrix,形參有原三元表TSMatrix M,作用是傳入三元表;三元表TSMatrix &T,採用引用以返回一個三元表。

  三元表T可能沒有初始化,這句的意思是將矩陣M的行數,列數,以及非零元個數傳給矩陣T,使其初始化。

  T.tu爲真時,即矩陣M中至少存在一個非零元。

  初始化數組num

  書中的註釋是求M中每一列含非零元的個數。具體來說,當原三元表M中某兩項或多項的j值相同時,M.data[t].j的值是相等的,因此這個循環完成後,比如說num[3]的值就是原三元表M列數爲3的個數。

  書中的註釋標錯位置了,應該是第一個for循環的後面。Cpot[1]=1的用處是第一列的在新三元表T的第一個插入位置爲1Cpot[0]是留給儲存三元錶行列數和非零元個數的。

  這句話是用來求除第一列外其它每一列的第一個非零元在新三元表T中的位置。第col列第一個非零元的位置爲第col-1列第一個非零元的位置加上第col-1列非零元的個數,這是個非常簡單的數學問題,沒必要多說了。

  M.tu的值是原三元表M的非零元個數,這個循環是用來遍歷原三元表M的每一項。

  Col=M.data[p].j的作用是得到循環當前項p的列數值j,賦給colcpot[col]的值即爲第col列的第一個插入位置,如果你問爲什麼,請看第七句。q=cpot[col]作用是用q來記錄當前第col列的插入位置(當然你也可以不用這個賦值,只需把接下來出現的q都改爲cpot[col]就行)。

  將原三元表M的當前第p項的ij值進行交換後給新三元表T的第q項,這樣第p項就轉置後正確的插入到新三元表的正確位置。

  將當前原三元表的第p項的非零元的值給新三元表的第p項。後一句++cpot[col]這個自增語句是使列數位col的項在新三元表的插入位置移動一位,下次再碰到列數位col的列時,插入位置即爲此次插入位置的下一個。 


如果有說錯的地方麻煩指正
如果有轉載的想法,不甚榮幸,但請註明出處,打字好累的T T ,尊重下吧。


發佈了20 篇原創文章 · 獲贊 63 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章