【问题标题】:Finding changes between 2 huge arrays查找 2 个巨大数组之间的变化
【发布时间】:2017-01-23 21:49:56
【问题描述】:

为了简单起见,我将一个非常大的 2D 空间映射到一个简单的位数组(实际上它大约有 200k 个成员)。

现在假设我运行了一个小算法,它在给定中心点和半径的情况下绘制1s 的“圆”。

这是一个例子,在左侧画了一个圆,在下一次计算中,它的中心向上移动了 1。

0000000        0001000
0001000        0011100
0011100    ->  0011100
0011100        0001000
0001000        0000000
0000000        0000000

现在我有很多层这些地图,在我计算它们之后,我需要“展平”它们(有点像 Photoshop 混合图层选项) - 目前我每次都在整个数组上迭代并组合整个数组- 尽管其中 95% 不会真正改变。

伪代码

for(int x = 0; x < width; x++)
   for(int y = 0; y < height; y++)
      int index = x + y * width
      result[index] = layer1[index] * layer2[index]

这是非常低效的,我需要提高我的表现。

更新:我们最终做了什么

稀疏矩阵正是我们需要的,我们最终使用了最适合我们使用的键字典(DOK)(动态构建每一层并“混合"他们在一起)。

我们想出的解决方案是使用 3 个数组:

  1. 浮点数组,大小为我们可能拥有的最大成员数(值)
  2. 位数组(大小相同),标记值数组中哪个成员有效
  3. int 数组(大小相同),保存值数组中使用的索引(以便稍后对其进行迭代)+ 增量 int,用作指向索引数组中成员数量的指针

由于我们的需求严重依赖内存使用和 CPU,我们将每个稀疏矩阵包装在双缓冲区形式中,以免每次混合都生成新数组。

最终,这个解决方案在 CPU 方面为我们提供了大约 x15-x20 更好的结果(比我们之前天真的蛮力方法),在内存方面我们将 RAM 使用率降低了大约 98%。

【问题讨论】:

    标签: arrays algorithm multidimensional-array


    【解决方案1】:

    据我了解,并使用 Photoshop 图层类比:

    你有你的底层“图像”,存储为一个“密集”二维数组,当然,因为这是你的数据,每个“像素”都很重要。到目前为止一切顺利。

    额外的层表示小的变化:当表示为二维数组时,几乎所有其条目都将为零。

    在这种情况下,您需要查看稀疏矩阵表示:您只需存储一个元组列表[(i1,j1), (i1, j2), ..., ],它记录非零的坐标,而不是存储完整的二维数组细胞。

    这样,在这些矩阵上运行的任何算法都将按照有多少非零的顺序运行,而不是基于矩阵的总条目数。

    【讨论】:

    • 您好,感谢您的回复 - 我考虑过,但我怎么知道这个解决方案在什么时候变得比我目前的解决方案效率低?
    • 一旦你的修改层不再“稀疏”。
    • 另一个问题,正如我所说,我的示例被简化了 - 我将数据存储为每个“像素”的浮点数 - 我将如何存储这个稀疏矩阵?动态列表显然是非常低效的。它看起来像PixelData[width * height] _sparseMatrix吗?
    • 为此,我建议您查找各种稀疏格式的实现,然后选择最适合您的应用程序需求的一种。现在材料有点多。有诸如坐标甲酸盐之类的东西,您可以在其中存储每个非零的行、列和条目。或者有压缩的行存储,或者压缩的列存储等。它们都有优点和缺点,所以你必须让它特定于应用程序。
    • 现在在维基百科上阅读它,我明天在办公室试试。谢谢!
    猜你喜欢
    • 2022-01-04
    • 2021-09-27
    • 1970-01-01
    • 1970-01-01
    • 2021-06-10
    • 2014-01-21
    • 1970-01-01
    • 2011-02-05
    • 1970-01-01
    相关资源
    最近更新 更多