`
zxxapple
  • 浏览: 79500 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

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实现

package com.zxx.matrix;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;

import org.apache.hadoop.io.WritableComparable;

public class IntPair implements WritableComparable
{
    
	private int right=0;
	private int left=0;
	
	public IntPair(){}
	
	public IntPair(int right,int left){
		this.right=right;
		this.left=left;
	}
	
	public int getRight(){
		return right;
	}
	
	public int getLeft(){
		return left;
	}
	public void setRight(int right){
		this.right=right;
	}
	public void setLeft(int left){
		this.left=left;
	}
	public String toString(){
		return left+","+right;
	}
	@Override
	public void readFields(DataInput arg0) throws IOException
	{
		// TODO Auto-generated method stub
		right=arg0.readInt();
		left=arg0.readInt();
	}

	@Override
	public void write(DataOutput arg0) throws IOException
	{
		// TODO Auto-generated method stub
		arg0.writeInt(right);
		arg0.writeInt(left);
	}

	@Override
	public int compareTo(Object arg0)
	{
		// TODO Auto-generated method stub
		IntPair o=(IntPair)arg0;
		if(this.right<o.getRight())
		{
			return -1;
		}else if (this.right>o.getRight()) {
			return 1;
		}else if (this.left<o.getLeft()) {
			return -1;
		}else if (this.left>o.getLeft()) {
			return 1;
		}
		return 0;
	}
	
}

 InputSplit.class(样例)

在这个类中用一个ArrayWritable 来保存元素的位置信息以及具体的元素信息

public class matrixInputSplit extends InputSplit implements Writable
{
    private IntPair[] t;//具体元素信息
    private IntPair location;//key的值,元素位置信息
	private ArrayWritable intPairArray;
	
	public matrixInputSplit()
	{
		
	}
	public matrixInputSplit(int row,matrix left,int col,matrix right)
	{
		//填充intPairArray
		intPairArray=new ArrayWritable(IntPair.class);
		t=new IntPair[4];
		location=new IntPair(row,col);
				for(int j=0;j<3;j++)
				{
                    IntPair intPair=new IntPair();
                    intPair.setLeft(left.m[row][j]);
                    intPair.setRight(right.m[j][col]);
					t[j]=intPair;
				}
				t[3]=location;
				intPairArray.set(t);
	}
    
    
	@Override
	public long getLength() throws IOException, InterruptedException
	{
		return 0;
	}

	@Override
	public String[] getLocations() throws IOException, InterruptedException
	{
		return new String[]{};   //返回空  这样JobClient就不会从文件中读取split
	}

	@Override
	public void readFields(DataInput arg0) throws IOException
	{
		this.intPairArray=new ArrayWritable(IntPair.class);
		this.intPairArray.readFields(arg0);
	}

	@Override
	public void write(DataOutput arg0) throws IOException
	{
		/*arg0.writeInt(t.length);
		for(int i=0;i<t.length;i++)
		{
			t[i].write(arg0);
		}*/
		intPairArray.write(arg0);
		
	}
	public IntPair getLocation()
	{
		t=new IntPair[4];
		try
		{
			t=(IntPair[])intPairArray.toArray();	
		} catch (Exception e)
		{
			System.out.println("toArray excption");
		}
		return t[3];
	}
	public IntPair[] getIntPairs()
	{
		t=new IntPair[4];
		try
		{
			t=(IntPair[])intPairArray.toArray();	
		} catch (Exception e)
		{
			System.out.println("toArray excption");
		}
		IntPair[] intL=new IntPair[3];
		for(int i=0;i<3;i++)
		{
		   intL[i]=t[i];	
		}
		return intL;
	}
}

 Inputformat.class

这个类比较简单,只需要实现getSplit方法即可,不过需要用户自定义一个方法就是从getInputfile获得的路径来解析矩阵,输入到split中即可。

matrixMul.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 block
				e.printStackTrace();
			} catch (InterruptedException e)
			{
				// TODO Auto-generated catch block
				e.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 block
				e.printStackTrace();
			} catch (InterruptedException e)
			{
				// TODO Auto-generated catch block
				e.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){  //删除临时文件
			
		}
	}

}

 以上代码只是简单测试下。。如有问题欢迎大家指正!这里先谢过!

第二个方法就是矩阵分块相乘,这个算法网上有大牛已经给出了源代码。。。

分享到:
评论
24 楼 amy929 2015-01-15  
你好!我最近在做学mapreduce,可否发一份这个代码给我学习,不胜感激。邮箱:1394921892@qq.com
23 楼 微笑春天 2014-10-28  
楼主 你好 花了一晚上的时间看了下你这个算法的实现 说实话 我接触hadoop时间也刚好一周左右 目前在研究PageRank与mapreduce的结合 以及PageRank算法改进的实现 不知可否把完整源代码发给我一份 我的代码能力不是很强 我想调试着一步步的走 我的邮箱是463520202@qq.com 如果不懂 还请多多指教下 。
22 楼 gaycolour 2014-02-26  
大大,同求完整代码!634677370@qq.com
21 楼 zarchary-10 2013-09-16  
你好,同求完整代码,可否发份zzy07053437@163.com,谢谢
20 楼 developerinit 2013-08-09  
你好,最近也在研究mapreduce矩阵乘法,想看下你这个例子的完整代码。如果可以,麻烦发到15821861795@139.com 。另外想请教下,你们做矩阵乘法的时候,两个矩阵是如何构建的,也就是说实际生产当中如何把传统关系数据库中的数据或者说hbase中的数据给构造成mapreduce需要输入的格式文件,能否给讲解下或者提供下思路,或许我说的不对,能否告知下, Thank you very much !
19 楼 developerinit 2013-08-07  
楼主的文章都很有深度,非常好,谢谢。
18 楼 Chris_program 2013-05-07  
还想再问下,我看您写了不少mapreduce的文章,都挺不错的,想请教下,您是怎么学习mapreduce编程的?比如说有什么学习步骤和学习素材?
17 楼 Chris_program 2013-05-07  
您好,博主,最近我在mapreduce上做推荐,发现这个矩阵相乘很有用,就发现您这篇文章了,能否给我发一份完整的代码吗?谢谢了先!我的邮箱:516841811@qq.com
16 楼 dongshilongdsl 2013-04-18  
你好!我最近在做mapreduce调度算法的研究,需要用到矩阵计算,请问能不能看一下你这个例子的代码?如果可以的话,请麻烦你发到wodedsl@163.com,谢谢了!
15 楼 wang_jian8855 2013-01-01  
你好,你的程序写的很有深度,能发给我一份学习学习吗? 576415346@qq.com  谢谢了
14 楼 csluqiang 2012-12-23  
博主,我最近在学习hadoop,是个菜鸟,您能把完整的源代码发一份给我吗?万分感激!luqcc@qq.com
13 楼 贞智smile 2012-11-25  
博主,急需源代码学习,希望您能麻烦发一下邮箱,554021876@qq.com,万分感谢
12 楼 davidzhou 2012-08-29  
你好!我最近在做mapreduce矩阵计算,请问能不能看一下你这个例子的代码?如果可以的话,请麻烦你发到davidzhou0621@163.com,谢谢了!
11 楼 hunan 2012-08-22  
您好!我最近也在研究mapreduce矩阵乘法,请问能看一下你写的程序代码吗!如果可以,请麻烦你给我发一份呀,我将感激不尽,zhenzonghu@163.com ,非常的感谢呀!!
10 楼 chthp 2012-08-14  
你好,我的邮箱是yuwenhui2@yahoo.com.cn,能不能把源码发我邮箱,谢谢
9 楼 醉香那风情 2012-08-09  
博主,我最近在学mapreduce ,能传完整的代码吗?万分感谢~~356549530@qq.com
8 楼 xiaowoxiaoniu 2012-05-31  
博主,求源码啊,万分感谢了,549885893@qq.com
7 楼 飘零雪 2012-05-10  
你好,我最近也在做mapreduce矩阵计算,能把完整代码发给我一份吗,piaolingxue305@gmail.com谢谢你!!!
6 楼 lookqlp 2012-04-24  
给我也发一份吧,特别是 Inputformat.class的实现,你说很简单,但我觉得老难了,它要同时获取两个文件的的内容呢,一个获取行,一个获取列。邮箱:lookqlp@126.com
万分感谢
5 楼 supercat_913805 2012-04-17  
哥们,我最近正在做hadoop矩阵乘法,能不能把你的完整代码给我发一份   supercat_913805@163.com   谢谢!!

相关推荐

    MapReduce实现矩阵相乘算法

    本话题将深入探讨如何使用Hadoop MapReduce实现两个矩阵相乘的算法,这在数据分析、机器学习以及高性能计算中有着重要应用。 首先,理解矩阵相乘的基本原理至关重要。矩阵相乘不是简单的元素对元素相乘,而是对应...

    mapreduce大的稀疏矩阵相乘

    在MapReduce框架中,稀疏矩阵相乘可以通过Map函数和Reduce函数来实现。Map函数将稀疏矩阵分解成小块,并将其分配给不同的计算节点;Reduce函数则将这些小块的结果合并,得到最终的结果。 在MapReduce框架中,稀疏...

    一种基于分布式平台Hadoop的矩阵相乘算法.pdf

    一种基于分布式平台Hadoop的矩阵相乘算法 本文介绍了一种基于分布式平台Hadoop的矩阵相乘算法,旨在解决单节点上大矩阵相乘运算量过大的问题。该算法采用了字节文件作为输入,以及最优化的分片方式,去掉了不必要的...

    java 矩阵乘法的mapreduce程序实现

    java 矩阵乘法的mapreduce程序实现是使用Hadoop的MapReduce框架来实现矩阵乘法的操作。矩阵乘法是一种基本的线性代数操作,用于计算两个矩阵的乘积。在大规模数据处理中,矩阵乘法是非常常见的操作,但是传统的矩阵...

    1-MapReduce矩阵乘法 600.rar

    描述中提到,“采用python基于MapReduce架构实现矩阵相乘”,这表明代码是用Python语言编写的,并且利用了MapReduce的特性来处理矩阵乘法的计算任务。大数据离线运算意味着这不是实时或流式计算,而是处理预先存储的...

    Hadoop MapReduce实现tfidf源码

    本篇文章将详细讲解如何利用Hadoop MapReduce实现TF-IDF(Term Frequency-Inverse Document Frequency)算法,这是一种在信息检索和文本挖掘中用于评估一个词在文档中的重要性的统计方法。 首先,我们要理解TF-IDF...

    Hadoop实现大矩阵乘法

    描述中提到的`Bigmmult.java`是实现这个算法的主要Java源代码文件。在这个程序中,mapper会接收到矩阵A的小块和矩阵B的整个列,然后计算部分乘积。这些部分乘积作为键值对输出,键通常包含了矩阵坐标信息,以便...

    2013广工虚拟化与云计算试卷

    使用 Hadoop 的 MapReduce 算法实现矩阵相乘需要三大步骤:数据输入、Map 和 Reduce。其中,数据输入是将矩阵分割成小块,Map 是将小块矩阵相乘,Reduce 是将小块矩阵相加。三大步骤的输入、输出数据可以用 ,value&gt; ...

    基于用户共现矩阵乘子的分布式协同过滤推荐.pdf

    在本文中,作者通过将用户相似性矩阵与项目评分矩阵相乘,获取了项目预测评分矩阵。然后,利用用户相似性矩阵和项目相似性矩阵的乘积生成候选项目集合,对于每个用户而言。基于这一原理,传统的协同过滤算法根据...

    分布式环境中基于核函数的极限学习机.pdf

    然而,在海量数据规模下,集中式核函数极限学习机的性能受限于核函数矩阵运算,尤其是矩阵求逆和矩阵相乘等操作,会因数据量的增大而导致运算效率大幅下降。针对这一问题,本文提出了一种基于MapReduce的分布式核...

    matrix multiplication_matrix_

    在提供的压缩包文件5b35d44e8ba3dd718e595e40184d03f0-75f183012236045a53ebc148aaea0265963c0273中,可能包含了关于矩阵乘法算法的具体实现、性能测试或者相关研究的代码和文档。解压后仔细研究这些内容,可以帮助...

    云计算第二版

    6.8.1 矩阵相乘算法设计 223 6.8.2 编程实现 224 习题 226 参考文献 226 第7章 Eucalyptus:Amazon云计算的开源实现 228 7.1 Eucalyptus简介 228 7.2 Eucalyptus技术实现 229 7.2.1 体系结构 229 7.2.2 主要构件 230...

Global site tag (gtag.js) - Google Analytics