使用MapReduce實現矩陣相乘演算法

2021-08-27 15:44:19 字數 1994 閱讀 6269

看到一篇文章,列出了幾個使用mapreduce完成的演算法(附有實現案例),但是還是想自己實現下,所以自己寫了乙個,後來看了下案例,不是太一樣,但是我實現了,不管效果如何,或者好不好看,總之我實現了。這裡就跟大家分享下,同時也希望能得到乙個建議。

首先介紹下我的實現思想:

1.兩個矩陣相乘,我們假設為a[i][j],b[x][y],若a*b則i==y,即c[n][n]=a[i][j]*b[x][y](n==i==y),圖方便直接使用對稱矩陣。

2.使用matrix物件來封裝乙個矩陣的節點,matrix物件有三個變數:flag,script1,script2。flag用來標示該矩陣節點屬於左邊的矩陣(a)還是右邊的矩陣(b),又或是結果矩陣(c),因為左右矩陣需要不同的方式進行處理,所以需要區分開。

3.我們知道c[i][j]=sum(a[i][x]*b[x][j])(x=1-->n),根據此公式,我們可以知道乙個c節點的值由a,b的哪些節點決定,我們這些a,b節點同c[i][j]放到一起,作為map的輸出,reduce的輸入。然後通過使用合適的分組比較器和排序比較器,我們可以讓所有決定c[i][j]值的a和b節點放到乙個reduce方法中,這樣我們就可以方便的計算出c[i][j]的值了。

4.分組比較器:map的輸出是[c[i][j],a[i][x]/b[x][j]},a[i][x]/b[x][j]的值],這樣的方式,而我們需要所有包含c[i][j]的key放到一起,所以分組比較器只要針對key的第乙個物件進行比較即可,在對key的第乙個物件(c)進行比較時,先flag進行比較(這裡不出意外應該都是一樣的),再根據script1進行比較,最後根據script2進行比較,這樣得到的可能排序結果如下:

c[1][1],c[1][2],c[2][1],c[2][2],...正是我們需要的順序,我們可以按此順序將值一次寫入輸出檔案中,配置合理的換行機制,就可以得到乙個很清晰的矩陣結果。

5.排序比較器:上面的分組比較器可以使得計算乙個c[i][j]所需要的所有a和b矩陣節點都在乙個reduce方法中進行計算,這樣雖然可以滿足我們的需求,但是計算相對來說還是比較麻煩的。比如我們需要計算c[2][3](假設矩陣大小=10),那麼我們需要計算a[2][1]*b[1][3]+a[2][2]*b[2][3]+...+a[2][10]*b[10][3],而reduce方法提供給我們的只是乙個iterable迭代器,我們需要在這個迭代器中找到a[2][1],b[1][3]然後再相乘,但是迭代器只能迭代一次,固然我們可以將其儲存到乙個list中,但是還是需要對該list進行n次遍歷,效率低下。這時就需要排序比較器出場了,從前面的計算公式我們可以看出,a的列標和b的行標其實是相同的,同時所有的a的行標是一致的,所有b的列標是一致的,因此我們在對其進行排序時完全可以按照a的列標和b的行標進行排序,這樣得到的排序結果如下:a[2][1],b[1][3],a[2][2],b[2][3],...這樣我們可以直接將相鄰兩個值相乘然後求和即可獲得最終的c[2][3]的值。這裡不要誤會,reduce是先排序,然後再對排序結果進行遍歷時才呼叫分組比較器判斷組的,這裡先介紹分組後介紹排序只是因為方便講解。所以在排序時實際上我們實現按照key的第乙個矩陣物件,即c矩陣進行排序,然後再根據第二個物件進行排序。

5.在計算出c[i][j]的值之後我們需要將其寫入到輸出檔案中,同時我們想要保持良好的顯示風格,保持矩陣的順序,因為在排序時已經保證了矩陣的順序,所以我們只需順序寫入輸出檔案即可,但是我們需要合理的換行。實現方法是自定義recordwriter物件,然後在每次呼叫recordwriter的write方法時將引數key儲存到乙個變數中(last),然後每次呼叫該方法時將last的行標同key的行標進行比較,如果相同則不換行,不相同則換行。

以上就是我的整個實現思想,如有不妥之處還望賜教,順便附上自己的**,在執行時可以先呼叫util裡的fileutil寫兩個矩陣檔案,這裡需說明下因為在計算過程中需要根據檔名區分a和b矩陣,所以a矩陣的檔名需要包含」1「,而b矩陣的檔名不能包含1,則檔案中每行的第乙個值是行號,且從1開始。也可以直接使用files裡面的檔案。

《請將檔案上傳到hdfs中》

該方法支援檔案切分,但是最好使用乙個reduce,因為多個reduce會將結果輸出到多個檔案,不易檢視。

大矩陣乘法運算map reduce實現思路

實現思路 儲存 大矩陣很多都是稀疏矩陣,並且有可能有上百萬的行和上百萬的列。那麼矩陣可以存在類似hbase面向列的分布式資料庫中。假設htable中有兩個表a和表b分別儲存兩個巨型矩陣a和b。表a和表b都是只有乙個列族。列名都是1開始計數。那麼表a和表b所儲存的矩陣a和矩陣b表示為如下形式 矩陣a ...

使用Python實現Map Reduce程式

使用python實現map reduce程式 起因想處理一些較大的檔案,單機執行效率太低,多執行緒也達不到要求,最終採用了集群的處理方式。詳細的討論可以在v2ex上看一下。步驟hadoop jar contrib streaming hadoop streaming 1.1.2.jar reduce...

基於MapReduce的矩陣乘法運算

1 採用兩個mapreduce運算串聯來實現 p ik mij njk 第一步 map函式 將每個矩陣運算mij傳給鍵值對 j,m,i,m ij 將每個矩陣元素njk傳給鍵值對 j,n,k,n jk reduce函式 對每個鍵j,檢查與之關聯的值的列表。對每個來自m的值 m,i,m ij 和來自n的...