【发布时间】:2017-10-15 12:25:06
【问题描述】:
我有一个静态图(拓扑不会随时间变化,并且在编译时已知),图中的每个节点都可以具有三种状态之一。然后我模拟一个动态,其中一个节点有可能随时间改变其状态,而这个概率取决于其邻居的状态。随着图表变大,模拟开始变得非常缓慢,但经过一些分析后,我发现大部分计算时间都花在了遍历邻居列表上。
我能够通过更改用于访问图中邻居的数据结构来提高模拟速度,但我想知道是否有更好(更快)的方法来做到这一点。 我目前的实现是这样的:
对于具有从0 到N-1 标记的N 节点和K 的平均邻居数的图,我将每个状态作为整数存储在std::vector<int> states 中以及每个节点的邻居数在std::vector<int> number_of_neighbors.
为了存储邻居信息,我创建了另外两个向量:std::vector<int> neighbor_lists,它依次存储与节点0、节点1、...、节点N 相邻的节点和一个索引向量std::vector<int> index,它为每个节点存储其第一个邻居在neighbor_lists中的索引。
所以我总共有四个向量:
printf( states.size() ); // N
printf( number_of_neighbors.size() ); // N
printf( neighbor_lists.size() ); // N * k
printf( index.size() ); // N
更新节点 i 时,我会像这样访问它的邻居:
// access neighbors of node i:
for ( int s=0; s<number_of_neighbors[i]; s++ ) {
int neighbor_node = neighbor_lists[index[i] + s];
int state_of_neighbor = states[neighbor_node];
// use neighbor state for stuff...
}
那么总结一下我的问题:是否有更快的实现来访问固定图结构中的相邻节点?
目前,我已经在相当长的模拟时间内达到了 N = 5000,但如果可能的话,我的目标是 N ~ 15.000。
【问题讨论】:
-
只是为了知道...
N的数量级是...? -
一些 GPU 函数的迭代速度比 CPU 快。但我从来没有看过如何在 C++ 中做到这一点。我刚刚在课程中看到使用 pragma 是可能的。
-
用 N (~1.5e4) 的大小更新了问题。我有 32GB 的可用内存,所以我可以估计我可以声明的数组有多大。谢谢。
-
节点多久改变一次状态?一个节点有多少个邻居(平均和最大)?如果更改很少,您可以存储有关邻居的统计信息并在节点更改时更新所有邻居,而不是遍历它们来获取这些统计信息。
标签: c++ c++11 optimization graph neighbours