前文

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

矩阵相乘计算思想

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

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

数据预处理

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

图2 输入的矩阵元素

图3 预处理后的矩阵元素

我们对图2进行举例说明,假如一行记录为:。则其代表左矩阵第一行第二列的元素值为

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

统计与分段

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

图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列被分为段,右矩阵被分为段。

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

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

代表该分段在接下来的过程中总共需要个拷贝,element_list表示该分段中的元素集合。

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

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

图5中代表矩阵L中第1列的元素个数为M1,每个分段的元素个数为w,所以对该列的分段数目为;同理表示矩阵R中第1行的元素个数为N1,每个分段的元素个数为w,所以对该行的分段数目为

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

Map迭代算法

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

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

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

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

式(3)中代表该记录(分段)需要拷贝份,拷贝标识号为1至;同理解释式(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迭代过程。

最后计算模块

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

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

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

在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),则其原本的形态为:

在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阶段进行汇合,汇合后如下所示:

代表L矩阵第k列第i个分段,代表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. sql server 常用的系统存储过程

      系统存储过程 说明 sp_databases 列出服务上的所有数据库 sp_helpdb 报告有关指定数据库或所有数据库的信息 sp_renamedb 更改数据库的名称 sp_tables 返回当 ...

  2. Post Complex JavaScript Objects to ASP.NET MVC Controllers

    http://www.nickriggs.com/posts/post-complex-javascript-objects-to-asp-net-mvc-controllers/     Post ...

  3. 在Discuz中增加创始人

    第一步 在 /config/config_uccenter.php 中 修改 $_config['admincp']['founder'] = '用户UID,用户UID2';   第二步 在 UPDA ...

  4. snort-2.9.7.0源码安装过程

    2015/02/15,centos6.5-64-minimal,初始205个包 [root@localhost snort]# yum install wget[root@localhost snor ...

  5. Linux-NTP-Server+Client

    GMT/UTC/CST;/etc/localtime,/usr/share/zoneinfo/*时区文件,/etc/profile加TZ变量;硬件时间RTC,系统时间;date,hwclock,tzs ...

  6. js键盘事件全面控制

    js键盘事件全面控制 主要分四个部分第一部分:浏览器的按键事件第二部分:兼容浏览器第三部分:代码实现和优化第四部分:总结 第一部分:浏览器的按键事件 用js实现键盘记录,要关注浏览器的三种按键事件类型 ...

  7. 安卓中Activity的onStart()和onResume()的区别是什么

    知道Activity的四种状态:Active/Runing 一个新 Activity 启动入栈后,它在屏幕最前端,处于栈的最顶端,此时它处于可见并可和用户交互的激活状态. Paused 当 Activ ...

  8. jquery淡入淡出

    html代码: <button id="b1" type="button">淡出</button> <button id=&quo ...

  9. git在本地创建远程仓库

    类似的博文,在前面的帖子里面也提到过,当时讲述的是一个入门级别的.其URL是ssh://username@repo-host-address/repo-path这种格式. 今天再说说如何创建类似Git ...

  10. CentOS下的网络配置文件说明

    CentOS网络配置主要涉及到以下四个文件: 1./etc/sysconfig/network 在CentOS官方网站上给出了如下说明: The/etc/sysconfig/networkfile i ...