【发布时间】:2013-08-29 00:10:12
【问题描述】:
我正在 C++ 中实现 Boruvka 的算法来找到图的最小生成树。该算法为每个超顶点找到一个最小权重边(一个超顶点是一个连通分量,它只是第一次迭代中的一个顶点)并将它们添加到 MST 中。添加边后,我们更新连通分量并重复查找最小边和合并超顶点过程,直到图中的所有顶点都在一个连通分量中。
由于每个超顶点的 find-min-edge 可以并行完成,我想使用 OpenMP 来执行此操作。这是我想用于并行查找最小值的omp for 循环。
int index[NUM_VERTICES];
#pragma omp parallel private(nthreads, tid, index, min) shared(minedgeindex, setcount, forest, EV, umark)
{
#pragma omp for
for(int k = 0; k < setcount; k++){ //iterate over supervertices, omp for here
min = 9999;
std::fill_n(index, NUM_VERTICES, -1);
/* Gets minimum edge for each supervertex */
for(int i = 0; i < NUM_VERTICES; i++) {
if(forest[i]->mark == umark[k]){ //find vertices with mark k
for(int j = 0; j < NUM_EDGES; j++) {
//check min edge for each vertex in the supervertex k
if(EV[j].v1==i){
if(Find(forest[EV[j].v1])!= Find(forest[EV[j].v2])){
if(EV[j].w <= min ){
min = EV[j].w;
index[k] = j;
break; //break looping over edges for current vertex i, go to next vertex i+1
}
}
}
}
}
} //end finding min disjoint-connecting edge for the supervertex with mark k
if(index[k] != -1){
minedgeindex.insert(minedgeindex.begin(), index[k]);
}
} //omp for end
}
由于我是 OpenMP 新手,我目前无法使其按预期工作。
让我简要解释一下我在这段代码中所做的事情:
setcount 是超顶点的数量。 EV 是一个包含所有边的向量(Edge 是我之前定义的结构,具有属性 v1, v2, w 对应于它连接的两个节点及其权重)。 minedgeindex 是一个向量,我希望每个线程找到每个连通分量的最小边,同时将最小边的索引(EV 中的索引 j)添加到向量 minedgeindex。所以我认为应该分享minedgeindex。 forest 是每个顶点的结构体,它有一个集合标记umark 指示它在哪个超顶点。我使用Union-Find 标记所有超顶点,但它与这块omp 代码无关。
此代码块的最终目标是为我提供正确的向量minedgeindex,其中包含每个超顶点的所有最小边。
为了更清楚并忽略图形背景,我只有一个很大的数字向量,我将它们分成一堆集合,然后我需要一些并行线程来找到每组数字的最小值并给我回来这些分钟的索引,将它们存储在向量minedgeindex。
如果您需要更多说明,请询问我。请帮我完成这项工作,我认为主要问题是私有和共享变量的声明,我不知道我是否做得对。
提前谢谢你!
【问题讨论】: