MapReduce框架中矩阵相乘的算法思路及其实现
关于在mapreduce框架中的两个矩阵相乘(A*B)的算法实现,有如下两种思路。。
?
第一,因为我们在学校课堂内的矩阵相乘的基本算法就是A的行与B的列相乘 当然要满足A的列的维数与B的行维数相同,才能满足相乘的条件。所以有如下基本思路:
让每个map任务计算A的一行乘以B的一列,最后由reduce进行求和输出。这是最原始的实现方法:
?
假设A(m*n)? B(n*s)
map的输入的格式如下<<x,y>,<Ax,By>>??? 0=<x<m,0=<y<s,0=<z<n
其中 <x,y>是key,x代表A的行号,y代表B的列号,<<Ax,By>>是value,Ax代表A的第x行第z列的元素,By代表B的第y列的第z行的一个元素,
A的一行与B的一列输入到一个maptask中,我们只需要对每个键值对中的value的两个值相乘即可,输出一个<<x,y>,Ax*By>
然后到洗牌阶段,将相同的可以输入到一个Reduce task中,然后reduce只需对相同key的value列表进行Ax*By进行求和即可。这个算法说起来比较简单,但是如何控制split中的内容是主要的问题。
?
首先需要重写InputSplit,InputFormat,Partion,来控制数据的流动,在数据结构方面需要定义一个实现的WritableComparable借口的类来保存两个整数(因为前面的key和value都出现两个整数),而且对象可以排序。
IntPair.class实现
public class MatrixNew{public static class MatrixMapper extends Mapper<IntPair, IntPair, IntPair, IntWritable>{public void map(IntPair key, IntPair value, Context context){ int left=0 ;int right=0;System.out.println("map is do");left = value.getLeft();right = value.getRight();IntWritable result = new IntWritable(left * right); // key不变,// value中的两个int相乘try{context.write(key, result);} catch (IOException e){// TODO Auto-generated catch blocke.printStackTrace();} catch (InterruptedException e){// TODO Auto-generated catch blocke.printStackTrace();} // 输出kv对}}public static class MatrixReducer extends Reducer<IntPair, IntWritable, IntPair, IntWritable>{private IntWritable result = new IntWritable();public void reduce(IntPair key, Iterable<IntWritable> values, Context context){int sum = 0;for (IntWritable val : values){int v = val.get();sum += v;}result.set(sum);try{context.write(key, result);} catch (IOException e){// TODO Auto-generated catch blocke.printStackTrace();} catch (InterruptedException e){// TODO Auto-generated catch blocke.printStackTrace();}}}public static class FirstPartitioner extends Partitioner<IntPair, IntWritable>{public int getPartition(IntPair key, IntWritable value, int numPartitions){int abs = Math.abs(key.getLeft()) % numPartitions;// numPartitions是reduce线程的数量return abs;}}public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException{Configuration conf=new Configuration();new GenericOptionsParser(conf, args);FileSystem fs=FileSystem.get(conf);Job job = new Job(conf, "New Matrix Multiply Job ");job.setJarByClass(MatrixNew.class);job.setNumReduceTasks(1);job.setInputFormatClass(matrixInputFormat.class);job.setOutputFormatClass(TextOutputFormat.class);job.setMapperClass(MatrixMapper.class);job.setReducerClass(MatrixReducer.class);job.setPartitionerClass(FirstPartitioner.class);job.setMapOutputKeyClass(IntPair.class);job.setMapOutputValueClass(IntWritable.class);job.setOutputKeyClass(IntPair.class);job.setOutputValueClass(IntWritable.class);matrixInputFormat.setInputPath(args[0]); FileOutputFormat.setOutputPath(job,new Path(fs.makeQualified(new Path("/newMartixoutput")).toString()));boolean ok = job.waitForCompletion(true);if(ok){ //删除临时文件}}}
?以上代码只是简单测试下。。如有问题欢迎大家指正!这里先谢过!
第二个方法就是矩阵分块相乘,这个算法网上有大牛已经给出了源代码。。。
1 楼 xinyiwust 2012-03-07 你好!我最近在做mapreduce矩阵计算,请问能不能看一下你这个例子的代码?如果可以的话,请麻烦你发到xy2006860@sohu.com,谢谢了! 2 楼 zxxapple 2012-03-07 xinyiwust 写道你好!我最近在做mapreduce矩阵计算,请问能不能看一下你这个例子的代码?如果可以的话,请麻烦你发到xy2006860@sohu.com,谢谢了!好的,我的上面都是测试的代码。。这要是算法的思想,有问题,大家一起讨论吧。。 3 楼 xinyiwust 2012-03-08 zxxapple 写道xinyiwust 写道你好!我最近在做mapreduce矩阵计算,请问能不能看一下你这个例子的代码?如果可以的话,请麻烦你发到xy2006860@sohu.com,谢谢了!
好的,我的上面都是测试的代码。。这要是算法的思想,有问题,大家一起讨论吧。。
邮件已收到,非常感谢!希望以后可以继续向你学习! 4 楼 Genie13 2012-03-08 你好,最近也在学习hadoop,想看下你这个例子的完整代码。如果可以,麻烦发到597271912@qq.com 谢谢来 5 楼 supercat_913805 2012-04-17 哥们,我最近正在做hadoop矩阵乘法,能不能把你的完整代码给我发一份 supercat_913805@163.com 谢谢!! 6 楼 lookqlp 2012-04-24 给我也发一份吧,特别是 Inputformat.class的实现,你说很简单,但我觉得老难了,它要同时获取两个文件的的内容呢,一个获取行,一个获取列。邮箱:lookqlp@126.com
万分感谢 7 楼 飘零雪 2012-05-10 你好,我最近也在做mapreduce矩阵计算,能把完整代码发给我一份吗,piaolingxue305@gmail.com谢谢你!!! 8 楼 xiaowoxiaoniu 2012-05-31 博主,求源码啊,万分感谢了,549885893@qq.com