利用Hadoop实现超大矩阵相乘之我见(二)

时间:2022-09-27 15:30:36

前文

《利用Hadoop实现超大矩阵相乘之我见(一)》中我们所介绍的方法有着“计算过程中文件占用存储空间大”这个缺陷,本文中我们着重解决这个问题。

矩阵相乘计算思想

传统的矩阵相乘方法为行、列相乘的方式,即利用左矩阵的一行乘以右矩阵的一列。不过该方法针对稀疏矩阵相乘,会造成过多的无效计算,降低计算效率。为了解决这个问题,本发明采用列、行相乘计算方式,即利用左矩阵的一列中的元素与右矩阵对应行中的所有元素依次相乘,该方法有效避免了稀疏矩阵相乘过程中产生的无效计算。具体计算过程示意图如图1所示。

利用Hadoop实现超大矩阵相乘之我见(二)

图1 列、行矩阵相乘计算示意图

数据预处理

为了便于Map-Reduce模型对矩阵元素进行处理,所有的矩阵元素都存储在文本文件中,一行记录代表一个矩阵元素,针对稀疏矩阵,0元素不纳入输入文本。如图2所示。

利用Hadoop实现超大矩阵相乘之我见(二)

图2 输入的矩阵元素

利用Hadoop实现超大矩阵相乘之我见(二)

图3 预处理后的矩阵元素

我们对图2进行举例说明,假如一行记录为:利用Hadoop实现超大矩阵相乘之我见(二)。则其代表左矩阵第一行第二列的元素值为利用Hadoop实现超大矩阵相乘之我见(二)

在一个Map过程中,我们对每一行输入数据进行预处理,若一行记录代表左矩阵元素,则提取列号作为Key值,剩余信息组成Value值;若一行记录代表右矩阵元素,则提取行号作为Key值,剩余信息组成Value值,如图3所示。之所以这样做,是为了下一步在Reduce过程中能够按照Key值统计左矩阵第Key列极其对应右矩阵第Key行中的元素。

统计与分段

当矩阵规模大到一定程度时,内存可能会碰到加载不了左矩阵的一列或右矩阵的一行元素的问题。为了提高矩阵相乘运算的可扩展性,本发明提出了对左矩阵元素按列进行分段,对右矩阵元素按行进行分段的方法,这样,单个计算节点就可以加载左矩阵的一段与右矩阵的一段至内存进行相乘运算,突破了内存的限制。分段相乘示意图如图4所示。

利用Hadoop实现超大矩阵相乘之我见(二)

图4 矩阵分段相乘示意图

接下来我们结合图4来说明Reduce阶段如何来完成统计与分段工作。Reduce阶段首先将所有Key相同的Value集合在一起,形成一个Value-List。若Key为k,那么Value-List则代表了左矩阵第k列与右矩阵第k行的所有元素,这些元素时混合在一起的。在Reduce阶段,我们第一轮遍历Value-List,获得左矩阵第k列的元素个数为Mk,右矩阵第k行的元素个数为Nk。接下来我们通过第二轮遍历对左矩阵第k列、右矩阵第k行的元素进行分段操作,假设每个分段包含w个元素,则左矩阵第k列被分为段,右矩阵被分为段。

利用Hadoop实现超大矩阵相乘之我见(二)

图5 分布式缓存存储矩阵分段信息

本发明将L矩阵中第k列中第i个分段表示成如下格式:

利用Hadoop实现超大矩阵相乘之我见(二)

利用Hadoop实现超大矩阵相乘之我见(二)代表该分段在接下来的过程中总共需要利用Hadoop实现超大矩阵相乘之我见(二)个拷贝,element_list表示该分段中的元素集合。

同理,R矩阵中第k行中第j个分段表示成如下格式:

利用Hadoop实现超大矩阵相乘之我见(二)

为了便于后续Map-Reduce过程的处理,我们将每一个分段都存储在磁盘文件中,文件中的一样代表一个分段。同时,我们将两个矩阵中的具体分段信息存储在分布式缓存中,有利于解决后续步骤中不同节点间的通信与数据查询问题。具体存储格式如图5所示。

图5中利用Hadoop实现超大矩阵相乘之我见(二)代表矩阵L中第1列的元素个数为M1,每个分段的元素个数为w,所以对该列的分段数目为利用Hadoop实现超大矩阵相乘之我见(二);同理利用Hadoop实现超大矩阵相乘之我见(二)表示矩阵R中第1行的元素个数为N1,每个分段的元素个数为w,所以对该行的分段数目为利用Hadoop实现超大矩阵相乘之我见(二)

拷贝任务分发——Map迭代算法

Map迭代算法

如图4所示,我们需要将两个矩阵中的分段一一对应相乘。我们做如下举例:由于矩阵L中的第k列中的第i段需要与矩阵R中第k行中的所有段依次相乘,所以需要将L中第k列第i段的内容拷贝利用Hadoop实现超大矩阵相乘之我见(二)份;同理,R中第k行中的每一个分段需要拷贝利用Hadoop实现超大矩阵相乘之我见(二)份。当然,拷贝工作是通过Map-Reduce来完成的,现在的问题是,若两个矩阵中每一个分段需要拷贝的数量都很大,则一个Map对每行记录都需要执行好多遍拷贝工作,大大延长了Map执行的时间,同时,可能使得很多计算节点没有参与运算。

利用Hadoop实现超大矩阵相乘之我见(二)

图6 Map迭代拷贝任务分发算法

为了解决上述问题,本发明提出了“Map迭代拷贝任务分发算法”来对每条记录(每个分段)的拷贝任务进行分发,这样有效的控制每个节点对每个分段的拷贝数量,同时更有效的使得更多的节点参与拷贝运算工作。

为了便于每条数据知道自己需要拷贝的分数,我们对公式(1)、(2)进行简单的修改:

利用Hadoop实现超大矩阵相乘之我见(二)

利用Hadoop实现超大矩阵相乘之我见(二)

式(3)中代表该记录(分段)需要拷贝利用Hadoop实现超大矩阵相乘之我见(二)份,拷贝标识号为1至利用Hadoop实现超大矩阵相乘之我见(二);同理解释式(4)。

这里,我们结合图7进行举例说明,假设…1#10000…是式(3)或式(4)的缩写形式,代表一条记录需要拷贝10000份,同时假设所有分段需拷贝的份数都是10000,那么初始时,将有N个节点参与拷贝工作。为了使得更多的计算节点参与拷贝工作,我们设计了此Map迭代拷贝任务分发算法。假设分发扩展率为10,则经过一次迭代后,文件大小扩大了约10倍,则大约有10*N个计算节点将参与拷贝工作,依次类推,三次迭代后,约有1000*N个计算节点参与拷贝工作,当有1000*N个节点参与拷贝工作时,每条记录被拷贝的最大份数为10,如图7所示。

迭代次数控制

在现实大矩阵相乘中,由于大部分情况下矩阵都为稀疏矩阵,那么每行每列包含的元素个数就不一样,所以每个分段需拷贝的份数都不确定。这样我们就需要计算Map迭代过程的迭代次数,依次来控制Map迭代的过程。在此,我们利用图5所示存储在分布式缓存中的各个分段信息来得到最大分段数目,同时结合分发扩展率n,利用公式(5)来计算Map迭代的次数,依次来控制Map迭代过程。

利用Hadoop实现超大矩阵相乘之我见(二)

最后计算模块

完成记录的拷贝工作后,我们还需要两轮Map-Reduce过程完成矩阵的运算。

第一轮Map-Reduce——分段拷贝与对应

在此轮中,我们首先在Map阶段完成分发到的拷贝任务,若图(7)中的….2191#2200…格式符合式(3),则其原本的形态为:

利用Hadoop实现超大矩阵相乘之我见(二)

在Map中执行拷贝工作后记录样式为:

k−i−2191   element_list

k−i−2192   element_list

......

k−i−2199   element_list

k−i−2200   element_list

若图(7)中的….2191#2200…格式符合式(3),则其原本的形态为:

利用Hadoop实现超大矩阵相乘之我见(二)

在Map中执行拷贝工作后记录样式为:

k−2191-j   element_list

k−2192-j   element_list

......

k−2199-j   element_list

k−2200-j   element_list

经过此轮Map阶段,每个key(拷贝后每条记录的前半部分)对应两个Value,也就是L矩阵中的一个段与R矩阵中的一个段,同一个key的两个Value将在该轮的Reduce阶段进行汇合,汇合后如下所示:

利用Hadoop实现超大矩阵相乘之我见(二)

利用Hadoop实现超大矩阵相乘之我见(二)代表L矩阵第k列第i个分段,利用Hadoop实现超大矩阵相乘之我见(二)代表R矩阵第k行第j个分段,然后在下一轮Map-Reduce进行如图(4)所示的两个段的相乘工作。

第二轮Map-Reduce——相乘并汇总

Map阶段对每条记录进行相乘运算,即将L中每个元素依次与R中每个元素相乘,若element_list_(L,k,i)中某个元素Li,k与element_list_(R,k,j)中某个元素Rk,j相乘,则结果记录成“i-j value”格式。 然后每个Map结束后执行combine操作,combine操作与该轮Reduce操作一样,执行相同key的value相加,便得到了最终的矩阵运算结果。

 推荐一个自己业余时间开发的网盘搜索引擎,360盘搜www.360panso.com

某研究开发中心云计算组     小周       

利用Hadoop实现超大矩阵相乘之我见(二)的更多相关文章

  1. 利用Hadoop实现超大矩阵相乘之我见(一)

    前记 最近,公司一位挺优秀的总务离职,欢送宴上,她对我说“你是一位挺优秀的程序员”,刚说完,立马道歉说“对不起,我说你是程序员是不是侮辱你了?”我挺诧异,程序员现在是很低端,很被人瞧不起的工作吗?或许 ...

  2. Java实现矩阵相乘问题

    1 问题描述 1.1实验题目 设M1和M2是两个n×n的矩阵,设计算法计算M1×M2 的乘积. 1.2实验目的 (1)提高应用蛮力法设计算法的技能: (2)深刻理解并掌握分治法的设计思想: (3)理解 ...

  3. java 写一个 map reduce 矩阵相乘的案例

    1.写一个工具类用来生成 map reduce 实验 所需 input 文件 下面两个是原始文件 matrix1.txt 1 2 -2 0 3 3 4 -3 -2 0 2 3 5 3 -1 2 -4 ...

  4. 利用Cayley-Hamilton theorem 优化矩阵线性递推

    平时有关线性递推的题,很多都可以利用矩阵乘法来解决. 时间复杂度一般是O(K3logn)因此对矩阵的规模限制比较大. 下面介绍一种利用利用Cayley-Hamilton theorem加速矩阵乘法的方 ...

  5. POJ 2246 Matrix Chain Multiplication(结构体+栈+模拟+矩阵相乘)

    题意:给出矩阵相乘的表达式,让你计算需要的相乘次数,如果不能相乘,则输出error. 思路: 参考的网站连接:http://blog.csdn.net/wangjian8006/article/det ...

  6. MapReduce实现矩阵相乘

    矩阵相乘能够查看百度百科的解释http://baike.baidu.com/view/2455255.htm?fr=aladdin 有a和b两个矩阵 a:                1   2   ...

  7. Python+MapReduce实现矩阵相乘

    算法原理 map阶段 在map阶段,需要做的是进行数据准备.把来自矩阵A的元素aij,标识成p条<key, value>的形式,key="i,k",(其中k=1,2,. ...

  8. python版 mapreduce 矩阵相乘

    参考张老师的mapreduce 矩阵相乘. 转载请注明:来自chybot的学习笔记http://i.cnblogs.com/EditPosts.aspx?postid=4541939 下面是我用pyt ...

  9. Java实验项目四——多线程矩阵相乘算法的设计

    Program:多线程矩阵相乘算法的设计 Description:利用多线程实现矩阵相乘,因为各个线程的运算互不影响, 所以不用使用锁,代码如下: thread.OperateMatrix类,实现矩阵 ...

随机推荐

  1. flag--命令行参数定义多标签示例

    // TestFlag2 project main.go package main import ( "flag" "fmt" ) func main() { ...

  2. double截取小数点位数

    (double)decimal.Round(decimal.Parse((planVoSt.TotalCompleteAmount / planVoSt.TotalUserCount).ToStrin ...

  3. php获取当前方法名和类名

    php提供的一些系统常量可以完成这些 php获取当前方法名(函数名) __FUNCTION__ php获取当前类名 __CLASS__ 或者 get_class($this); php获取本类所有的方 ...

  4. android开发,socket发送文件,read阻塞,得不到文件尾-1

    这是我的接收文件代码:开始可以读取到-1,但是现在又读取不到了,所以才加上红色字解决的(注释的代码) File file = new File(mfilePath,"chetou.&quot ...

  5. Filter案例

    1.有选择的被访问 描述:首先若用户没有在页面提交注册(直接访问list.jsp),就只能被允许访问a.jsp.其他页面均不被允许访问 在login.jsp提交信息之后,可以在b.jsp访问, 代码如 ...

  6. javascript设计模式——模板方法模式

    前面的话 在javascript开发中用到继承的场景其实并不是很多,很多时候喜欢用mix-in的方式给对象扩展属性.但这不代表继承在javascript里没有用武之地,虽然没有真正的类和继承机制,但可 ...

  7. centos6&period;5 yum update 报错Couldn&&num;39&semi;t resolve host &&num;39&semi;centos&period;ustc&period;edu&period;cn&&num;39&semi;

    异常信息 [root@localhost ~]# yum -y update Loaded plugins: fastestmirror, refresh-packagekit, security S ...

  8. I&sol;O输入流基础之FileInputStream

    InputStream:是所有字节输入流的父类,其作用是:用这个流把网络数据(getOutputStream()),文件系统的数据读入内存 由与  public abstract class Inpu ...

  9. python语法&lowbar;json&lowbar;pickle

    ---恢复内容开始--- dic = {"name":"kevin","age":"20"} f = open(&quo ...

  10. 孙子兵法的计是最早的SWOT分析,《孙子兵法》首先不是战法,而是不战之法。首先不是战胜之法,而是不败之法

    孙子兵法的计是最早的SWOT分析,<孙子兵法>首先不是战法,而是不战之法.首先不是战胜之法,而是不败之法 在打仗之前,你要详细地去算. 计算的目的是什么呢?孙子说,是为了知胜,就是为了知道 ...