一些算法的MapReduce实现——矩阵-向量乘法实现

Problem

假定有一个n×n的矩阵M,其第 i 行和第 j 列的元素是 m(i,j). 假定有一个n维向量V, 其第 j 个元素记为Vj 。于是,矩阵M和向量V的乘积结果是一个n维向量X,其第 i 个元素 x(i)

矩阵M和向量V各自都会在DFS中存成一个文件。假定要么是从矩阵元素在文件中位置,要么是从元素显示存储的三元组 (i, j, m[i, j])中,我们都可以获得矩阵元素的行列下标。同样我们假设向量V的元素v(j) 下标可以通过类似的方法来获得。

  Map 函数 每个Map任务将整个向量V和矩阵M的一个文件块作为输入。对每个矩阵元素 m(i, j) ,Map任务会产生键-值对 (i, m(i, j) * v(j))。因此,计算 x(i)的所有n个求和项 m(i, j) * v(j)的键值都相同。
   Reduce函数 Reduce任务将所有与给定键值i关联的值相加即可得到 (i, x(i)).

以上情况是针对于向量V可以一次性读入内存计算的。如果向量V无法放入内存该怎么办呐?

一种替代方案是,将矩阵分割成多个宽度相等的垂直条,同时将向量分割成同样数目的水平条。每个水平条的高度等于矩阵垂直条的宽度。我们的目标是使用足够的条以保证向量的每个条能够方便的放入计算节点的内存中。下图是上述分割的示意图,其中矩阵和向量都分割成5个条
矩阵第 i 个垂直条只和向量的第 i 个水平条相乘。因此,可以将矩阵的每个条存成一个文件,同样将向量的每个条存成一个文件。矩阵某个条的一个文件条及对应的完整向量条输送到每个Map任务。然后,Map和Reduce任务可以按照一开始所描述的过程运行,不同的是在哪里Map任务获得了完整的向量
一些算法的MapReduce实现——矩阵-向量乘法实现_第1张图片

Example

矩阵A是一个 m×n 矩阵



向量V的长度为n

一些算法的MapReduce实现——矩阵-向量乘法实现_第2张图片

那么A*V之后的向量X为长度m的向量



Pseudocode

现在放上向量V可以一次性读入内存的伪代码,这个比较简单,MapReduce代码就不写了。
map(key, value):
    for (i, j, a_ij) in value:
        emit(i, a_ij * v[j])
 
reduce(key, values):
    result = 0
    for value in values:
        result += value
    emit(key, result)

Map端的时间复杂度为: O(mn + n)
Reduce端的复杂度为:O(mn)

具体的MapReduce代码后续在 一些算法的MapReduce实现——块矩阵乘法实现里把参数改一下就变成矩阵向量乘法了。

Reference

1、Mining the Massive Datasets 

你可能感兴趣的:(mapreduce,算法,矩阵运算)