mst.c
上传用户:hhyinxing
上传日期:2013-09-10
资源大小:833k
文件大小:5k
源码类别:

并行计算

开发平台:

Unix_Linux

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <malloc.h>
  4. #include <math.h>
  5. #include <mpi.h>
  6. #define A(i,j) A[i*N+j]
  7. #define MST(i,j) MST[i*n*p+j]
  8. #define MAX 1000
  9. int N;
  10. int n;
  11. int p;
  12. int i,j,k;
  13. double l;
  14. int *D,*C,*W,*J;
  15. int *A;
  16. int *MST;
  17. int myid;
  18. MPI_Status status;
  19. /**输出结果MST**/
  20. void printM()
  21. {
  22. int i,j;
  23. if(myid==0){
  24. printf("the MST is:n");
  25. for(i=0;i<N;i++)
  26. {
  27. for(j=0;j<N;j++)
  28. printf("%d ",MST[i*n*p+j]);
  29. printf("n");
  30. }
  31. }
  32. }
  33. /**输出数组D内容**/
  34. void printD()
  35. {
  36. int i;
  37. if(myid==0){
  38. printf("the array D is:n");
  39. for(i=0;i<N;i++)
  40. {
  41. printf("%d ",D[i]);
  42. }
  43. printf("n");
  44. }
  45. }
  46. /**读入邻接矩阵**/
  47. int readA()
  48. {
  49. int i,j;
  50. int p1;
  51. p1=p;
  52. printf("Input the size of matrix:");
  53. scanf("%d",&N);
  54. n=N/p1;
  55. if(N%p1!=0) n++;
  56. A=(int*)malloc(sizeof(int)*(n*p1)*N);
  57. if(A==NULL){
  58. printf("Error when allocating memoryn");
  59. exit(0);
  60. }
  61. for(i=0;i<N;i++)
  62. for(j=0;j<N;j++)
  63. scanf("%d",&(A(i,j)));
  64. for(i=N;i<n*p1;i++)
  65. for(j=0;j<N;j++)
  66. A(i,j)=MAX-1;
  67. p=p1;
  68. return(0);
  69. }
  70. /**广播特定数组**/
  71. void bcast(int *P)
  72. {
  73.   MPI_Bcast(P,N,MPI_INT,0,MPI_COMM_WORLD);
  74. }
  75. /**求最小的数学函数**/
  76. int min(int a,int b)
  77. {
  78.   return(a<b?a:b);
  79. }
  80. /**检查MST是否已完成**/
  81. int connected()
  82. {
  83. int i;
  84. int flag;
  85. flag=1;
  86. for(i=1;i<N;i++)
  87. if(D[i]!=D[0])
  88. {
  89. flag=0;
  90. break;
  91. }
  92. return(flag);
  93. }
  94. /**为各顶点找出距离最近的树**/
  95. void D_to_C()
  96. {
  97. int i,j;
  98. for(i=0;i<n;i++){
  99. W[n*myid+i]=MAX;
  100. for(j=N-1;j>=0;j--)
  101. if((A(i,j)>0)&&(D[j]!=D[n*myid+i])&&(A(i,j)<=W[n*myid+i]))
  102. {
  103. C[n*myid+i]=D[j];
  104. W[n*myid+i]=A(i,j);
  105. J[n*myid+i]=j;
  106. }
  107. if(W[n*myid+i]==MAX) C[n*myid+i]=D[n*myid+i];
  108.   }
  109. }
  110. /**为各树找出外连最短边**/
  111. void C_to_C()
  112. {
  113. int tempw,tempj;
  114. for(i=0;i<n;i++){
  115. tempj=N+1;
  116. tempw=MAX;
  117. for(j=N-1;j>=0;j--)
  118. if((D[j]==n*myid+i)&&(C[j]!=n*myid+i)&&(W[j]<=tempw))
  119. {
  120. C[myid*n+i]=C[j];
  121. tempw=W[j];
  122. tempj=j;
  123. }
  124. if(myid==0)
  125. {
  126. if((tempj<N)&&(J[tempj]<N)) 
  127. MST(tempj,J[tempj])=MST(J[tempj],tempj)=tempw;
  128. for(j=1;j<p;j++)
  129. {
  130. MPI_Recv(&tempj,1,MPI_INT,j,j,MPI_COMM_WORLD,&status);
  131. MPI_Recv(&tempw,1,MPI_INT,j,0,MPI_COMM_WORLD,&status);
  132. if((tempj<N)&&(tempw <N))MST(tempj,tempw)=MST(tempw,tempj)=A(tempj,tempw);
  133. }
  134. }
  135. else
  136. {
  137. MPI_Send(&tempj,1,MPI_INT,0,myid,MPI_COMM_WORLD);
  138. MPI_Send(&J[tempj],1,MPI_INT,0,0,MPI_COMM_WORLD);
  139. }
  140. MPI_Barrier(MPI_COMM_WORLD);
  141. }
  142. }
  143. /**调整数组顶点的标识**/
  144. void CC_to_C()
  145. {
  146. for(i=0;i<n;i++)
  147.      C[myid*n+i]=C[C[myid*n+i]];
  148. }
  149. /**产生新树**/
  150. void CD_to_D()
  151. {
  152. for(i=0;i<n;i++)
  153. D[myid*n+i]=min(C[myid*n+i],D[C[myid*n+i]]);
  154. }
  155. /**释放动态内存**/
  156. void freeall()
  157. {
  158.   free(A);
  159.   free(D);
  160.   free(C);
  161. }
  162. /**主函数**/
  163. int main(int argc,char **argv)
  164. {
  165. int i,j,k;
  166. int group_size;
  167. MPI_Init(&argc,&argv);
  168. MPI_Comm_size(MPI_COMM_WORLD,&group_size);
  169. MPI_Comm_rank(MPI_COMM_WORLD,&myid);
  170. p=group_size;
  171. /**处理器0读入邻接矩阵**/
  172. if(myid==0)
  173. {
  174. readA();
  175. MST=(int*)malloc(sizeof(int)*n*p*n*p);
  176. }
  177. MPI_Bcast(&N,1,MPI_INT,0,MPI_COMM_WORLD);
  178. if(myid!=0){
  179. n=N/p;
  180. if(N%p!=0) n++;
  181. }
  182. D=(int*)malloc(sizeof(int)*(n*p));
  183. C=(int*)malloc(sizeof(int)*(n*p));
  184. W=(int*)malloc(sizeof(int)*(n*p));
  185. J=(int*)malloc(sizeof(int)*(n*p));
  186. if(myid!=0)
  187. A=(int*)malloc(sizeof(int)*n*N);
  188. /**数组D初始化,步骤(1)**/
  189. for(i=0;i<n;i++) D[myid*n+i]=myid*n+i;
  190. MPI_Gather(&D[myid*n],n,MPI_INT,D,n,MPI_INT,0,MPI_COMM_WORLD);
  191. bcast(D);
  192. /**处理器0向其它处理器发送必要信息**/
  193. if(myid==0)
  194. for(i=1;i<p;i++)
  195. MPI_Send(&A(i*n,0),n*N,MPI_INT,i,i,MPI_COMM_WORLD);
  196. else
  197. MPI_Recv(A,n*N,MPI_INT,0,myid,MPI_COMM_WORLD,&status);
  198. MPI_Barrier(MPI_COMM_WORLD);
  199. l=log(N)/log(2);
  200. i=1;
  201. /**主循环,步骤(2)**/
  202. while(!connected()){
  203. if(myid==0) printf("loop %d n",i);
  204. printD();
  205. printM();
  206. /**步骤(2.1)**/
  207. D_to_C();
  208. MPI_Barrier(MPI_COMM_WORLD);
  209. MPI_Gather(&C[n*myid],n,MPI_INT,C,n,MPI_INT,0,MPI_COMM_WORLD);
  210. MPI_Gather(&W[n*myid],n,MPI_INT,W,n,MPI_INT,0,MPI_COMM_WORLD);
  211. bcast(C);
  212. bcast(W);
  213. MPI_Barrier(MPI_COMM_WORLD);
  214. /**步骤(2.2)**/
  215. C_to_C();
  216. MPI_Barrier(MPI_COMM_WORLD);
  217. MPI_Gather(&C[n*myid],n,MPI_INT,C,n,MPI_INT,0,MPI_COMM_WORLD);
  218. MPI_Gather(&C[n*myid],n,MPI_INT,D,n,MPI_INT,0,MPI_COMM_WORLD);
  219. MPI_Barrier(MPI_COMM_WORLD);
  220. /**步骤(2.3)**/
  221. if(myid==0)
  222. for(j=0;j<n;j++) D[j]=C[j];
  223. /**步骤(2.4)**/
  224. for(k=0;k<l;k++){
  225. bcast(C);
  226. CC_to_C();
  227. MPI_Gather(&C[n*myid],n,MPI_INT,C,n,MPI_INT,0,MPI_COMM_WORLD);
  228. }
  229. bcast(C);
  230. bcast(D);
  231. /**步骤(2.5)**/
  232. CD_to_D();
  233. MPI_Gather(&D[n*myid],n,MPI_INT,D,n,MPI_INT,0,MPI_COMM_WORLD);
  234. bcast(D);
  235. i++;
  236. }
  237. if(myid==0)printf("loop %d n",i);
  238. printD();
  239. printM(); 
  240. freeall();
  241. MPI_Finalize();
  242. return(0);
  243. }