提高图连通性计算的性能

时间:2011-04-15 06:52:21

标签: c++ performance graph simulation


我正在编写一个程序来生成图表并检查它是否已连接。下面是代码。这里有一些解释:我在飞机上随机产生了许多点。然后我连接节点,不仅仅基于接近度。我的意思是说节点更可能连接到更近的节点,这是由我在代码(h_sq)中使用的随机变量和距离决定的。因此,我生成所有链接(对称,即,如果我可以与j交谈,反之亦然),然后检查BFS以查看图表是否已连接。
我的问题是代码似乎正常工作。但是,当节点数量大于~2000时,速度非常慢,我需要多次运行此功能以进行仿真。我甚至尝试将其他库用于图形,但性能是相同的。 有谁知道我怎么可能加速一切?

谢谢,

int Graph::gen_links() {
    if( save == true ) { // in case I want to store the structure of the graph
        links.clear();
        links.resize(xy.size());
    }

    double h_sq, d;
    vector< vector<luint> > neighbors(xy.size());

    // generate links
    double tmp = snr_lin / gamma_0_lin;
    // xy is a std vector of pairs containing the nodes' locations
    for(luint i = 0; i < xy.size(); i++) {
        for(luint j = i+1; j < xy.size(); j++) {
            // generate |h|^2
            d = distance(i, j);
            if( d < d_crit ) // for sim purposes
                d = 1.0;
            h_sq = pow(mrand.randNorm(0, 1), 2.0) + pow(mrand.randNorm(0, 1), 2.0);
            if( h_sq * tmp  >= pow(d, alpha) ) {
                // there exists a link between i and j
                neighbors[i].push_back(j);
                neighbors[j].push_back(i);
                // options
                if( save == true )
                    links.push_back( make_pair(i, j) );
            }
        }
        if( neighbors[i].empty() && save == false  ) {
        // graph not connected. since save=false i dont need to store the structure, 
        // hence I exit
            connected = 0; 
            return 1;  
        }
    }

    // here I do BFS to check whether the graph is connected or not, using neighbors
    // BFS code...
    return 1;
}

更新: 主要问题似乎是内部for循环中的push_back调用。在这种情况下,大部分时间都是这个部分。我应该使用reserve()来提高效率吗?

2 个答案:

答案 0 :(得分:0)

您确定缓慢是由生成引起的,而不是由您的搜索算法引起的吗?

图表生成是O(n ^ 2),你不能做太多。但是,如果点位置至少在某些实验中是固定的,那么显然可以在某些时候交换使用内存。

首先,所有节点对的距离和pow(d,alpha)都可以预先计算并保存到内存中,这样您就不需要一次又一次地计算它们。 10000个节点的额外内存成本为双倍大约800mb,浮动大小为400mb。

另外,如果我没记错的话,正常变量的平方和是卡方分布。如果准确度允许,你可以进行一些预先计算的表查找吗?

最后,如果两个节点连接的概率如果距离超过某个值那么小,那么你不需要O(n ^ 2),可能你只能计算那些距离较小的节点对比某些限制?

答案 1 :(得分:0)

作为第一步,您应该尝试对内部和外部向量使用保留。

如果这不能使性能达到您的预期,我相信这是因为内存分配仍在发生。

我在类似的情况下使用了一个方便的课程,llvm :: SmallVector(在Google中找到它)。它提供了一个预分配项很少的向量,因此每个向量可以减少一个分配数。 当预分配空间中的项目用完时,它仍然可以增长。

所以: 1)在跑步过程中平均检查你的向量中的项目数量(我在谈论内部和外部向量) 2)放入llvm :: SmallVector并预先分配这样的大小(因为在堆栈上分配了向量,您可能需要增加堆栈大小,或者如果限制可用堆栈内存则减少预分配)。

关于SmallVector的另一个好处是它具有与std :: vector几乎相同的接口(可以轻松放入而不是它)