http://blog.youkuaiyun.com/zhuliting/article/details/6302767 去年4月份修改的代码,现在贴出来分享一下。毕业了,工作上可能会很忙,不能更新博客了。 #include "mpi.h" #include <stdio.h> #include <string.h> #include <sys/time.h> #include <math.h> #include <iostream> using namespace std; enum MSG_SIG { READY, ACCOMPLISHED, NEW_TASK, TERMINATE }; enum MSG_TAG { REQUEST_TAG, SEED_TAG, REPLY_TAG, NUM_SOLUTIONS_TAG, SOLUTIONS_TAG }; const int MAXN = 20; const int MAX_SOLUTIONS = 100; int chessboard[MAXN], b[MAXN][MAXN]; int solutions[MAX_SOLUTIONS][MAXN]; int n, m; int solution_count; void set_b() { memset(b, 0, sizeof(b)); for (int k = 1; k <= n; k++) { if( chessboard[k] != 0 ) { for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) { if(i == k || j == chessboard[k] || abs(i-k) == abs(j-chessboard[k])) b[i][j] = 1; } } } } int check_b() { int flag = 0; for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) if(b[i][j] == 0) { flag = 1; break; } return flag; } int is_safe(int i) { int flag = 0; for (int j = 1; j <= i - 1; j++) { if(chessboard[j] != 0 && chessboard[i]-chessboard[j] == 0 || chessboard[i] * chessboard[j] > 0 && abs(chessboard[i]-chessboard[j]) == i-j) { flag = 1; break; } } return flag; } int zeors(int array[]) { int cnt = 0; for (int i = 1; i <= n; i++) if(array[i] == 0) cnt++; return cnt; } void print() { for(int j = 1; j <= n; j++) printf("%d", chessboard[j]); printf(" "); /*if( solution_count % 5 == 0 )*/ printf("/n"); } void place_queens(int row) { int i = row; memset(chessboard, 0 ,sizeof(chessboard)); while (1) { int flag = is_safe(i); if (i == n && flag == 0) { if(zeors(chessboard) == n - m) { set_b(); if(check_b() == 0) { solution_count++; //print(); } } } if( i < n && flag == 0 ) { i++; chessboard[i] = 0; continue; } while (chessboard[i] == n && i > 1 ) i--; if( chessboard[i] == n && i <= 1 ) break; else chessboard[i] = chessboard[i]+1; } } void place_queens_parallel(int seed) { int i = 2; memset(chessboard, 0 ,sizeof(chessboard)); chessboard[1] = seed; while (1) { int flag = is_safe(i); if (i==n && flag == 0) { if(zeors(chessboard) == n - m) { set_b(); if(check_b() == 0) { solution_count++; //print(); } } } if( i < n && flag == 0 ) { i++; chessboard[i]=0; continue; } while (chessboard[i] == n && i > 1) i--; if (i <= 1) break; else chessboard[i] = chessboard[i]+1; } } void sequential_m_queens() { solution_count = 0; struct timeval start, end; long span = 0; gettimeofday(&start, NULL); place_queens(1); gettimeofday(&end, NULL); span = (end.tv_sec - start.tv_sec) * 1000 + (end.tv_usec - start.tv_usec) / 1000; printf("sequential:/n"); printf("count = %d/n",solution_count); printf("timecost: %ld ms/n", span); } void m_queens_master(int nodes) { MPI_Status status; int active_slaves = nodes - 1; int new_task = NEW_TASK; int terminate = TERMINATE; int reply; int child; int num_solutions; int seed = n; solution_count = 0; struct timeval start, end; long span = 0; gettimeofday(&start, NULL); while (active_slaves) { MPI_Recv(&reply, 1, MPI_INT, MPI_ANY_SOURCE, REPLY_TAG, MPI_COMM_WORLD, &status); child = status.MPI_SOURCE; if (reply == ACCOMPLISHED) { MPI_Recv(&num_solutions, 1, MPI_INT, child, NUM_SOLUTIONS_TAG, MPI_COMM_WORLD, &status); solution_count += num_solutions; } if (seed >= 0) { MPI_Send(&new_task, 1, MPI_INT, child, REQUEST_TAG, MPI_COMM_WORLD); MPI_Send(&seed, 1, MPI_INT, child, SEED_TAG, MPI_COMM_WORLD); seed--; } else { MPI_Send(&terminate, 1, MPI_INT, child, REQUEST_TAG, MPI_COMM_WORLD); active_slaves--; } } gettimeofday(&end, NULL); span = (end.tv_sec - start.tv_sec) * 1000 + (end.tv_usec - start.tv_usec) / 1000; printf("parallel:/n"); printf("timecost: %ld ms/n/n", span); } void m_queens_slave(int my_rank) { MPI_Status status; int ready = READY; int accomplished = ACCOMPLISHED; int finished = 0; int request; int seed = 0; MPI_Send(&ready, 1, MPI_INT, 0, REPLY_TAG, MPI_COMM_WORLD); while (! finished) { MPI_Recv(&request, 1, MPI_INT, 0, REQUEST_TAG, MPI_COMM_WORLD, &status); if (request == NEW_TASK) { MPI_Recv(&seed, 1, MPI_INT, 0, SEED_TAG, MPI_COMM_WORLD, &status); solution_count = 0; place_queens_parallel(seed); MPI_Send(&accomplished, 1, MPI_INT, 0, REPLY_TAG, MPI_COMM_WORLD); MPI_Send(&solution_count, 1, MPI_INT, 0, NUM_SOLUTIONS_TAG, MPI_COMM_WORLD); } else { finished = 1; } } } int main(int argc, char* argv[]) { //scanf("%d", &n); //scanf("%d", &m); n = atoi(argv[1]); m = atoi(argv[2]); int numprocs, my_rank; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &numprocs); MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); if (my_rank == 0) { printf("n = %d, m = %d/n", n, m); //printf("sequential:/n"); sequential_m_queens(); } if (numprocs >= 2) { if (! my_rank){ //printf("parallel:/n"); m_queens_master(numprocs); } else { m_queens_slave(my_rank); } } MPI_Finalize(); return 0; } /* [root@c0104 ~]# cat test.sh #!/bin/bash rm -f ans.txt mpicxx queen.cpp -o queen scp queen c0101:~/ scp queen c0102:~/ scp queen c0103:~/ scp queen c0105:~/ scp queen c0106:~/ scp queen c0107:~/ scp queen c0108:~/ scp queen c0109:~/ scp queen c0110:~/ for i in 7 8 9 10 11;do for j in 3 4 5 6 7;do if [[ $i -gt $j ]];then echo "$i,$j" mpiexec -n 10 ./queen $i $j >> ans.txt fi done done echo "Finished!" */