合并大型矩阵的 CPU 和内存友好解决方案

Posted

技术标签:

【中文标题】合并大型矩阵的 CPU 和内存友好解决方案【英文标题】:CPU and Memory Friendly Solution to Merge Large Matrix 【发布时间】:2017-08-15 14:30:15 【问题描述】:

针对以下典型案例:

n = 1000000;
r = randi(n,n,2);

(假设所有行之间有 0.05% 的公共数字;n 甚至可能是几千万)

我正在寻找一种 CPU 和内存高效解决方案,以根据任何常见项目(此处为整数)合并行。 here 提供了 Python 中的示例代码列表,并且可以找到将其中的示例代码快速转换为 Matlab 的方法here

在我的尝试中,它们需要很长时间(几分钟到几小时),所以我赞成找到更快的解决方案。

对于上面的例子,典型的输出应该是(单元格):


[1 90 34 67 ... 9]
[35 89]
[45000 23 828 130 8999 45326 ... 11]
...

还要注意,我曾尝试编译为 mex,但由于 Matlab-Coder 中不支持单元格而失败。

编辑:一个小小的演示示例

%---------------------------------------
clc
n = 100;
r = randi(n,n,2);        % random integers in [1,n], size(n,2)
%---------------------------------------
>> r
r =
    82    17             % (1) 82 17
    91    13             % (2) 91 13
    13    32             % (3) 91 13 32            merged with (2), common 13
    82    53             % (4) 82 17 53            merged with (1), common 82
    64    17             % (5) 82 17 53 64         merged with (4), common 17
    ...
    94    45
    13    31             % (77) 91 13 32 31        merged with (3), common 13
    57    51
    47    52
     2    13             % (80) 91 13 32 31 2      merged with (77), common 13
    34    80
%---------------------------------------
c = merge(r);            % cpu and memory friendly solution is searched for.
%---------------------------------------
c =
    [82 17 53 64]
    [91 13 32 31 2]
    ...

【问题讨论】:

您需要在这里定义“合并”的含义。或者给出产生该示例输出的确切输入 @LuisMendo 在新添加的演示中,针对给定数据显示了产品。所以这个问题变得很清楚了。注意演示代码中的cmets。 我明白了。有趣的问题,但很棘手 您正在无向图中搜索连通分量。如果你有2015b或者以后的,可以试试graph.conncomp,不过不知道有多快。 @beaker 我明白了,不幸的是,它是 Matlab 的低版本,似乎没有 graph 工具箱或 conncomp 功能可供我使用。因此,如果有人可以通过conncomp 的纯 Matlab 实现做出贡献,那就太好了,因此不需要任何其他第三方或其他许可证。 【参考方案1】:

你需要一个索引。

在 Python 中,使用字典。在 MATLAB 中 - 我不会使用 MATLAB,因为开源是未来,而 MATLAB 正在消亡。

但是 Python 很慢。通过使用例如,您可能会获得 10 倍的加速。 Cython 来翻译和优化 C 中的代码。避免使用 Python 数据类型,例如 listint,因为它们非常占用内存。 numpy 具有内存有效的整数数组。

如果你得到一个新的对 (a,b),你可以使用这个字典来找到现有的项目来合并。然后在合并后更新字典。 实际上对于整数,您应该使用数组而不是字典。

最棘手的部分是处理 a 和 b 都存在但属于不同组的情况。如果还不够快的话,这里可以进行一些巧妙的优化。

不是集群,而是连接组件。

【讨论】:

您对开源部分可能是正确的。但是,这是一个要求在 Matlab 中为所述问题实施解决方案的提示或指导或经验的问题。我很想看到连接组件的纯 Matlab 或 Python(所以我可以将其翻译成 Matlab)实现。 我可能需要深入了解scipy.sparse.csgraph.connected_components 看看是否有简单的实现。 简单往往与“CPU 和内存效率”相矛盾。

以上是关于合并大型矩阵的 CPU 和内存友好解决方案的主要内容,如果未能解决你的问题,请参考以下文章

在有限内存上对大型矩阵进行矩阵运算

算法----稀疏矩阵之三元组

如何在大型矩阵中合并具有相似名称的列

大型稀疏矩阵分解

使用数据流引擎进行大型矩阵操作

使用大型数据集在 R 中创建二进制矩阵