从模拟数据构建一个非常大的马尔可夫链的最佳/最快方法是什么?

时间:2013-10-27 10:38:18

标签: c++ graph markov-chains

我编写了一个C ++程序来模拟我正在研究的某个过程。它在模拟的每个时间步输出离散的“状态”。例如:

a
b
c
b
c
b

将是模拟运行的输出,其中a作为初始条件(由我设置或随机生成)和b& c将是系统在两者之间振荡的状态。

我想将这些运行中的许多运行组合成马尔可夫链,以便它变成具有以下顶点和边的图。 (最好在运行时,因为保存输出首先需要大量的磁盘空间。)括号之间的数字表示遇到某个顶点或边的次数,因此也应该存储。

Vertices: a(1), b(3) and c(2).

Edges: a->b(1), b->c(2), c->b(2).

真实状态包含112位信息,我正在生成数十亿这些转换。问题是我没有找到图形库或程序来有效和快速地生成马尔可夫链。我一直在玩弄:

  • 谷歌稀疏哈希在C ++中构建我自己的图表类。
  • Neo4J(我刚刚开始使用这个)
  • 柠檬库

我刚刚完成了“Google稀疏哈希图”,但事实证明它在运行中途变得非常缓慢。大约一天后(内存使用量超过20 GB,本身不是问题,因为还有更多问题),它会变慢,大约需要三周才能完成。

我可以访问具有12或16个内核以及256或512 GB内存的计算机,我觉得他们应该为这项工作做好准备。

由于我不是一名训练有素的程序员而且编码速度很慢,所以在我花费大量时间研究另一种不完美的解决方案之前,我正在寻找一些信息。

  • 什么是能够快速接受大量顶点和边缘构建马尔可夫链的最佳程序/库?
  • 缓慢是使用错误的工具还是不完美的编码(我怀疑)或者我只是想做一些总会花费很多时间的事情?

我希望我能够清楚地解决问题。提前感谢任何智慧或答案。

编辑:

基于评论中的问题和答案,我想我的问题应该是:什么是适合C ++的快速矩阵库?

1 个答案:

答案 0 :(得分:1)

你看过boost :: numeric :: ublas吗?它有一个成员稀疏矩阵,为您提供类似访问的矩阵,但不是在内存中构建NxN数组,而是保留每个节点的边缘列表。

因此,如果N是节点中的节点数而不是NxN数组,则每个节点保留Nx30 -avg num个边数 -

然而,即使假设您可以使用单个字节来计算边缘的重新计算,您仍然有600M节点,每个节点都有30个边缘的列表。

列表条目是边缘名称uint32,内容至少为1个字节。所以列表最少150字节。它的内存至少达到90GB。可能更高,因为列表中的每个元素都有开销。

如果你可以将这一切保留在内存中,而不需要将数据交换到磁盘,那么就没有理由不能快速工作。当然,有序地图可能会执行hash_map。它取决于实现和使用的哈希函数。

Naively std::map<uint32, std::map<uint32, unint8>>如果树是平衡的,那么大树的长度是30,小的树很小。所以访问不应该花费很长时间。有可能hash_map对于列更好,但不确定:hash_map<uint32, std::map<uint32, unint8>>(谷歌稀疏哈希映射调整为内存而不是速度,列映射将非常大,这可能使它不合适)< / p>

最后,您应该考虑将此信息保存在磁盘而不是内存中。实际上,您可以使用外部数据服务(如DB),每个节点都有一个表(NodeId,NumOfHits)和边缘表(NodeId,NodeId,NumOfHits){此表示占用更多空间}

我会尝试类似Cassandra的东西,它可以为您管理磁盘与内存缓存,并且可以轻松扩展到多台计算机。而且您不需要复杂交易模型的开销等。