int** MOT_parallel(int **weights, int numVertices)
{
list<int> usedVectices;
usedVectices.push_back(0);
list<int>
unUsedVertices;
for (int i = 1; i < numVertices;
i++)
unUsedVertices.push_back(i);
int **resGraf = new
int*[numVertices];
for (int i = 0; i < numVertices;
i++)
resGraf[i] = new
int[numVertices];
for (int i = 0; i < numVertices;
i++)
for (int j = 0; j <
numVertices;
j++)
resGraf[i][j] = 0;
omp_set_num_threads(omp_get_num_procs());
while (!unUsedVertices.empty())
{
// считаем минимальное ребро от
каждой неиспользованной, до использованных
vector<edgeInf>
*dist = new
vector<edgeInf>[omp_get_num_procs()];
list<int>::iterator
j, k;
#pragma omp parallel private (j,
k)
for (j =
unUsedVertices.begin(); j != unUsedVertices.end(); ++j)
{
int min
= 999999;
int newVertIdx1 = -1, newVertIdx2 =
-1;
for (
k = usedVectices.begin(); k != usedVectices.end(); ++k)
{
if (weights[*j][*k] < min && weights[*j][*k] != 0)
{
newVertIdx1 =
*j;
newVertIdx2 =
*k;
min =
weights[*j][*k];
}
}
edgeInf
edge;
edge.v1 =
newVertIdx1;
edge.v2 =
newVertIdx2;
edge.dist =
min;
dist[omp_get_thread_num()].push_back(edge);
}
// выбираем самое
edgeInf *minEdge = new
edgeInf[omp_get_num_procs()];
for (int i = 0; i <
omp_get_num_procs(); ++i) {
minEdge[i].v1 = minEdge[i].v2 =
-1;
minEdge[i].dist = 999999999;
}
#pragma omp parallel for
for (int i = 0; i <
omp_get_num_procs(); i++) {
for (int j = 0; j <
dist[omp_get_thread_num()].size(); j++) {
if
(dist[omp_get_thread_num()][j].dist <
minEdge[omp_get_thread_num()].dist)
minEdge[omp_get_thread_num()]
= dist[omp_get_thread_num()][j];
}
}
// добавить
вершину
int min = 0;
for (int i = 1; i <
omp_get_num_procs(); ++i) {
if (minEdge[i].dist <
minEdge[min].dist)
min = i;
}
usedVectices.push_back(minEdge[min].v1);
unUsedVertices.remove(minEdge[min].v1);
resGraf[minEdge[min].v1][minEdge[min].v2]
=
resGraf[minEdge[min].v2][minEdge[min].v1] = minEdge[min].dist;
}
return
resGraf;
}