MapReduce下的矩阵乘法实现(包括稀疏矩阵):
建立输入文件,并在分布式存储系统中建立sparse输入文件夹,并上传输入文件:输入文件内分为矩阵M的三元组表达,与N矩阵的三元组表达。
M矩阵三元组表达(乘法左矩阵):
M 1 3 1
M 1 4 2
M 2 1 1
M 4 2 3
矩阵N的三元组表达(乘法右矩阵):
N 1 4 2
N 2 3 1
N 3 4 2
N 4 3 4
第一次map后经hadoop的shuffle阶段形成的(key,Iterable<Text>values)对;
详细过程:
M矩阵的元素经map后形成的键值对是(M_元素所在行_元素所在列,M_元素值)
N矩阵的元素经map后形成的键值对是(M_1_元素所在行,N_元素所在列_元素值)……. (M_M的总行数_元素所在行,N_元素所在列_元素值)
Reduce阶段接收到相同key的键值对(key,Iterable<Text>values)如下:
M_1_1 N 4 2
M_1_2 N 3 1
M_1_3 N 4 2 M 1
M_1_4 M 2 N 3 4
M_2_1 N 4 2 M 1
M_2_2 N 3 1
M_2_3 N 4 2
M_2_4 N 3 4
M_3_1 N 4 2 M 4
M_3_2 N 3 1
M_3_3 N 4 2
M_3_4 N 3 4
M_4_1 N 4 2
M_4_2 N 3 1 M 3
M_4_3 N 4 2
M_4_4 N 3 4
遍历值得列表,找到每个键值对的以M开头的value,解析出后面的值,过程中保存遍历的Value的String形式(hadoop的迭代器不允许重复访问values列表)。对于每一个键值对,将解析出的值分别和解析出的N开头的value保存的值相乘,结果上传结果,上传的形式是(key解析出的行号_N开头的value中解析出的列号,相乘的结果)
结果保存在sparse3文件中。
结果输出如下:
1 4 2
1 3 8
2 4 2
3 4 8
4 3 3
第二次mapreduce过程:
将第一次mapreduce输出的结果作为第二次的输入,第二次map将输入的value进行解析,分析出行号和列号以及对应的值。然后以(行号_列号,值)的(key,value)进行上传至结果。经过数据压缩阶段,与shuffle阶段,形成reduce阶段的输入,形式为(行号_列号,Iterable<IntWritable> values)。
Reduce接收输入,并将value列表的值相加合并,形成最终的在key指定的行列位置的值,并将结果上传至最终结果(程序上下文)导入到最终的输出文件。
第二次测试例子:
运算结果:
1 1 6
1 2 9
1 3 9
1 4 17
2 1 8
2 2 14
2 3 17
2 4 30
3 1 14
3 2 17
3 3 16
3 4 30
4 1 15
4 2 16
4 3 12
4 4 24
第一次mapreduce算法:
package sparse;
importjava.io.IOException;
importjava.util.StringTokenizer;
importjava.util.List;
importjava.util.ArrayList;
importjava.lang.Integer;
importorg.apache.hadoop.conf.Configuration;
importorg.apache.hadoop.fs.*;
importorg.apache.hadoop.io.IntWritable;
importorg.apache.hadoop.io.Text;
importorg.apache.hadoop.mapreduce.Job;
importorg.apache.hadoop.mapreduce.Mapper;
importorg.apache.hadoop.mapreduce.Reducer;
importorg.apache.hadoop.mapreduce.lib.input.FileInp