我在 C++ 中实现 Boruvka 的算法来找到图的最小生成树。该算法为每个超顶点找到一个最小权重边(一个超顶点是一个连通分量,它只是第一次迭代中的一个顶点)并将它们添加到 MST 中。一旦添加了一条边,我们更新连接的组件并重复 find-min-edge 和 merge-supervertices 过程,直到图中的所有顶点都在一个连接的组件中。
由于每个超顶点的 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
是一个向量,我希望每个线程为每个连通分量找到最小边,同时将最小边的索引(索引 j in EV
)添加到向量minedgeindex
中。所以我觉得minedgeindex
应该分享。forest
是每个顶点的结构,它有一个设置标记umark
,指示它所在的超顶点。我Union-Find
用来标记所有超顶点,但它与这块 omp 代码无关。
我需要这个代码块的最终目标是给我一个正确的向量minedgeindex
,其中包含每个超顶点的所有最小边。
为了更清楚并忽略图形背景,我只有一个大的数字向量,我将它们分成一堆集合,然后我需要一些并行线程来找到每组数字的最小值并将索引返回给我那些分钟,将它们存储在一个向量minedgeindex
中。
如果您需要更多说明,请询问我。请帮我完成这项工作,我认为主要问题是私有和共享变量的声明,我不知道我是否做得对。
先感谢您!