【发布时间】:2018-08-25 21:05:53
【问题描述】:
我正在努力理解http://wyattgorman.com/?p=25。到目前为止,我所做的不超过clang-format:
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define SIZE 20
int m_row = SIZE, m_column = SIZE, zed = 30, matrix[SIZE][SIZE], visited[SIZE], best_path[SIZE];
int best_cost = 9999999, size = SIZE;
void dfs(int city, int visited_in[], int path_in[], int path_i_in, int cost_in) {
if (cost_in < best_cost) {
int* visited = calloc(sizeof(int), size + 1);
int* path = calloc(sizeof(int), size + 1);
int path_i = path_i_in, cost = cost_in, i;
for (i = 0; i < size; i++) {
visited[i] = visited_in[i];
path[i] = path_in[i];
}
visited[city] = 1;
path[path_i] = city;
path_i++;
int leaf = 0;
for (i = 0; i < size; i++) {
if (visited[i] == 0) {
leaf++;
dfs(i, visited.get(), path.get(), path_i, cost + matrix[city][i]);
}
}
if (leaf == 0) {
cost += matrix[city][0];
path[path_i] = 0;
path_i++;
if (cost < best_cost) {
// printf("Found new best cost: %i\n", cost);
best_cost = cost;
for (i = 0; i < size; i++)
best_path[i] = path[i];
}
}
free(visited);
free(path);
}
}
int main(int argc, char *argv[]) {
int rank, p;
// , source, dest;
// int tag = 0;
MPI_Status status;
MPI_Init(0, NULL);
MPI_Comm_size(MPI_COMM_WORLD, &p);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
srand(time(NULL));
if (rank == 0) {
int i, j;
for (i = 0; i < m_row; i++)
for (j = 0; j < m_column; j++)
matrix[i][j] = 0;
for (i = 0; i < m_row; i++) {
for (j = 0; j < i; j++) {
if (i != j) {
int temp = (rand() % zed) + 1;
matrix[i][j] = temp;
matrix[j][i] = temp;
}
}
}
for (i = 1; i < p; i++)
MPI_Send(&matrix[0][0], size * size, MPI_LONG, i, 0, MPI_COMM_WORLD);
printf("Matrix, %ix %i, Max Int : %i\n", m_row, m_column, zed);
for (i = 0; i < m_row; i++) {
for (j = 0; j < m_column; j++)
printf("%i\t", matrix[i][j]);
printf("\n");
fflush(NULL);
}
printf("\n");
int winner;
int node_array[p - 1];
int node_array_i = 0;
for (i = 0; i < p - 1; i++)
node_array[i] = i + 1;
for (i = 1; i < size; i++) {
int temp_best_cost, node;
node = node_array[node_array_i];
if (node_array_i < p - 2)
node_array_i++;
else
node_array_i = 0;
int* temp_best_path = calloc(sizeof(int), size + 1);
MPI_Recv(&temp_best_cost, 1, MPI_INT, node, 0, MPI_COMM_WORLD,&status);
MPI_Recv(&temp_best_path[0], size + 1, MPI_INT, node, 0, MPI_COMM_WORLD, &status);
if (temp_best_cost < best_cost) {
winner = node;
best_cost = temp_best_cost;
for (j = 0; j < size + 1; j++)
best_path[j] = temp_best_path[j];
}
MPI_Send(&best_cost, 1, MPI_INT, node, 0, MPI_COMM_WORLD);
}
printf("Best Path Found by node % i :\n", winner);
printf("% i", best_path[0]);
for (i = 1; i < size + 1; i++)
printf(" –> % i", best_path[i]);
printf("\nBest Cost Found : % i\n", best_cost);
} else {
MPI_Recv(&(matrix[0][0]), m_row * m_column, MPI_LONG, 0, 0, MPI_COMM_WORLD, &status);
int i;
for (i = rank; i < size; i += (p - 1)) {
int* visited = calloc(sizeof(int), size + 1);
int* path = calloc(sizeof(int), size + 1);
int cost = matrix[0][i], path_i = 1;
path[0] = 0;
visited[0] = 1;
dfs(i, visited.get(), path.get(), path_i, cost);
MPI_Send(&best_cost, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
MPI_Send(&best_path[0], size + 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
MPI_Recv(&best_cost, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &status);
free(visited);
free(path);
}
}
MPI_Finalize();
return 0;
}
在我看来,它看起来像来自visited[]
int m_row = SIZE, m_column = SIZE, zed = 30, matrix[SIZE][SIZE], visited[SIZE], best_path[SIZE];
被覆盖
int* visited = calloc(sizeof(int), size + 1);
那么,这样可以吗?
此外,在排名中,在
MPI_Recv(&(matrix[0][0]), m_row * m_column, MPI_LONG, 0, 0, MPI_COMM_WORLD, &status);
destination matrix 看起来与 origin matrix 相同(这有意义吗?),排名为 0,位于:
MPI_Send(&matrix[0][0], size * size, MPI_LONG, i, 0, MPI_COMM_WORLD);
既然matrix是所有等级共享的,对吧?
int m_row = SIZE, m_column = SIZE, zed = 30, matrix[SIZE][SIZE], visited[SIZE], best_path[SIZE];
另外,我猜best_path[](在开头)应该是best_path[SIZE+1],而不是best_path[SIZE]。因为循环转到size+1,对吧?
for (j = 0; j < size + 1; j++)
best_path[j] = temp_best_path[j];
【问题讨论】:
-
我赞成保留 C++ 标签,如果你允许我,我会说这个问题提到它被移植到 C++。那里已经有 C++ 的东西了。
-
这个
int node_array[p - 1];不是有效的 C++,using std::make_unique;不是有效的 C - 决定你使用哪种语言 -
编辑您的问题和代码以反映您所询问的语言。
-
gcc/g++ 实现了一些扩展。这是其中之一。对于
visited,vfs中的声明是全局声明shadowing,直到声明本地版本的范围结束。这被认为是不好的做法(因为它要求读者在使用名称时记住他们得到的是哪一个)但被允许。 -
@NeilButterworth:我希望您已经知道,尽管使用了可变长度自动数组,但 GCC 很乐意将这样的代码编译为 C++。如果这使 GCC 成为“不兼容的 C++ 编译器”,那很好,但事实是它可能是现有最广泛使用的编译器,所以如果 OP 的代码在编写时无法使用,那就有点过分了。
标签: c algorithm mpi graph-algorithm