【问题标题】:How to implement a huge matrix in C如何在C中实现一个巨大的矩阵
【发布时间】:2011-02-09 07:54:37
【问题描述】:

我正在用 C 编写一个数值模拟程序。部分模拟是空间上固定的节点,它们彼此之间有一些浮点值。它就像一个有向图。但是,如果两个节点距离太远,(比某个截止长度 a 远)这个值为 0。

为了表示所有这些“相关性”或浮点值,我尝试使用二维数组,但由于我有 100.000 和更多节点,这将对应于 40GB 左右的内存。

现在,我正在尝试为这个问题想出不同的解决方案。我不想将所有这些值保存在硬盘上。我也不想即时计算它们。一种想法是某种稀疏矩阵,就像可以在 Matlab 中使用的那样。

你有什么其他想法,如何存储这些值?

我是 C 新手,所以请不要期望太多经验。

感谢和最好的问候, 简·奥利弗

【问题讨论】:

  • 关键所在的某种散列/映射(行 x 列)怎么样?它只会包含与矩阵中具有非零值的条目一样多的元素。
  • 这不是一个真正的具体问题......是的,稀疏矩阵。去查找一些算法....也许有一些关于矩阵中空节点百分比的详细信息,或者关于模拟的更多信息,也许有人可以提出除 grah 表示之外的其他解决方案。
  • ...例如,你想用这个矩阵做什么?
  • 如果您有
  • 另外——两个节点之间的“距离”不是相互的吗?因此,不是 n*n 距离,而是 2(n-1) 在这种情况下需要 774kB

标签: c memory matrix


【解决方案1】:

平均而言,给定节点的截止距离内有多少节点决定了您的内存需求,并告诉您是否需要分页到磁盘。占用内存最少的解决方案可能是将一对节点映射到一个距离的哈希表。由于每条距离都相同,因此您只需将其输入到哈希表中一次即可——将两个节点号按数字顺序排列,然后将它们组合成一个哈希键。您可以对哈希表使用 Posix hsearch/hcreate/hdestroy 函数,尽管它们不太理想。

【讨论】:

  • 这是个好主意。一个节点平均连接到其他节点的 0.2%。这取决于参数。
  • 不过,我有点担心查找过程的性能。这实际上比创建矩阵/哈希图更重要,因为后者只完成一次......
  • @janoliver 那么这就是 100,000 个节点中的 200 个?关于速度:哈希查找是 O(1),但常数时间可能会很大,尤其是当您的内存不足时。 (你有多少?)也许最好是一个节点数组,每个节点包含一个按节点号排序的附近节点列表;二进制查找需要对 200 个节点进行大约 9 次比较。这很容易实现,您可能想从它开始,只在必要时考虑其他东西。
  • P.S.讨论假定您需要按节点号进行查找,但这并不清楚。您需要确定您的模拟对节点表的要求。如果你只枚举节点,从不查找它们,那么线性数组绝对是要走的路。
  • 好吧,那么在这个邻居列表中,我还必须存储我需要的相关值。所以我必须使用一个包含邻居节点(或它的索引)和浮点值的结构......但是是的,这可能是最简单的事情。
【解决方案2】:

稀疏矩阵方法听起来很适合这个。 Wikipedia article on sparse matrices 讨论了几种实现方法。

【讨论】:

    【解决方案3】:

    稀疏邻接矩阵是一种想法,或者您可以使用邻接列表,只允许存储比您的截止值更近的边。

    【讨论】:

    • 嗨,吉姆,感谢您的想法。快速浏览这些列表后,两个索引引用的简单浮点值似乎比这些列表项之一消耗的内存更少。..
    【解决方案4】:

    您还可以为每个节点保存一个列表,其中包含与该节点相关的其他节点。然后,您将拥有 2*k 的列表条目总数,其中 k 是虚拟矩阵中非零值的数量。

    与允许随机访问的“真实”矩阵相比,将整个系统实现为哈希/集合/映射的组合在速度/性能方面仍然是可以接受的。

    edit:此解决方案是稀疏矩阵实现的一种可能形式。 (另请参阅下面 Jim Balter 的说明。谢谢您,Jim。)

    【讨论】:

    • 肯定是 2(k-1),因为节点不会链接到自身?请参阅我对主要问题的评论,我同意这是解决问题的方法。
    • 请注意,每个节点中的列表,其中列表中的每个条目都包含节点编号和非零距离,是一个形式稀疏矩阵,其中每个节点列表是一行(或一列)。
    • @SlappyTheFish Flinsch 写道“k 是虚拟矩阵中非零值的数量”——对角线在虚拟矩阵中全为零,因此 k 已经排除了这些条目。该列表实际上包括 k 个条目,其中每个条目有两个值,一个节点号和一个距离。
    • @Jim 谢谢你的笔记。我完全同意。
    【解决方案5】:

    如果可能,您确实应该使用稀疏矩阵。在 scipy 中,我们支持稀疏矩阵,所以你可以在 python 中玩,虽然说实话,稀疏支持仍然有粗糙的边缘。

    如果你有matlab,那肯定是更好的ATM。

    如果不使用稀疏矩阵,您可以考虑使用基于 memap 的数组,这样就不需要 40 Gb 的 RAM,但它仍然会很慢,并且只有在稀疏度较低的情况下才真正有意义(假设如果 100000x100000 矩阵中有 10-20% 包含项目,那么完整数组实际上会更快,甚至可能比稀疏矩阵占用更少的空间。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-07
      • 2013-05-29
      相关资源
      最近更新 更多