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

并行计算

开发平台:

Unix_Linux

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <malloc.h>
  4. #include <string.h>
  5. #include <math.h>
  6. #include "mpi.h"
  7. #define PiM 21
  8. /*初始化Fp矩阵*/
  9. int f[2][2][2]={{{1,0},{1,1}},{{1,1},{0,1}}};
  10. int g[2][2][2];
  11. int pdata[]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,67,71,79,83};
  12. /*生成字符串*/
  13. void gen_string(int stringlen,char *String,int seed)
  14. {
  15. int i,num;
  16. srand(seed*100);
  17. for(i=0;i<stringlen;i++){
  18.      num=rand()%2;
  19.      String[i]='0'+num;
  20.    }
  21.    String[stringlen]='';
  22. }
  23. /*从素数存放数组中随机选取一个素数*/
  24. int drawp(int seed){
  25. srand(seed*100);
  26. return pdata[rand()%PiM];
  27. }
  28. /*该算法中第一个参数n是正文串的长度,第二个参数m是模式串的长度。(约束0<m,n<=128)*/
  29. main(int argc,char *argv[]){
  30.    int groupsize,myrank,n,m,p,i,j,h,tmp;
  31. int textlen;
  32.    char *Text,*Pattern;
  33.    int *MATCH;
  34.    int B[128][2][2],C[128][2][2],D[128][2][2],L[128][2][2];
  35.    int fp_pattern[2][2];
  36. MPI_Status status;
  37.   
  38.   
  39.    MPI_Init(&argc,&argv);
  40.    MPI_Comm_size(MPI_COMM_WORLD,&groupsize);
  41.    MPI_Comm_rank(MPI_COMM_WORLD,&myrank);
  42.   
  43.    n=atoi(argv[1]);
  44.    m=atoi(argv[2]);
  45. textlen=n/groupsize;
  46. if(myrank==groupsize-1)
  47. textlen=n-textlen*(groupsize-1);
  48.    if((Text=(char *)malloc(textlen*sizeof(char)+1))==NULL){
  49.      printf("no enough memoryn");
  50.      exit(1);
  51.    }
  52.    if((Pattern=(char *)malloc(m*sizeof(char)+1))==NULL){
  53.      printf("no enough memoryn");
  54.      exit(1);
  55.    }
  56.   
  57.    if((MATCH=(int *)malloc(textlen*sizeof(int)+1))==NULL){
  58.      printf("no enough memoryn");
  59.      exit(1);
  60.    }
  61.    /*初始化Fp的逆矩阵Gp*/
  62.    g[0][0][0]=1;g[0][0][1]=0;g[0][1][0]=p-1;g[0][1][1]=1;
  63.    g[1][0][0]=1;g[1][0][1]=p-1;g[1][1][0]=0;g[1][1][1]=1;
  64.   
  65.    /*产生正文串和模式串*/
  66.    gen_string(textlen,Text,m*n*myrank);
  67. /*随机选择一个素数,对应算法14.9步骤(2)*/
  68. if(myrank==0) {
  69.    p=drawp(n/m);
  70.    gen_string(m,Pattern,p*m*n);
  71. }
  72.   
  73.    /*播送选中的素数与m给其余每个节点*/
  74. MPI_Bcast(&p,1,MPI_INT,0,MPI_COMM_WORLD);
  75.    MPI_Bcast(Pattern,m,MPI_CHAR,0,MPI_COMM_WORLD);
  76.   
  77.    printf("one node %d n=%d,m=%d,p=%dn",myrank,n,m,p);
  78.    printf("one node %d Text=%sn",myrank,Text);
  79.    printf("one node %d Pattern=%sn",myrank,Pattern);
  80.    MPI_Barrier(MPI_COMM_WORLD);
  81.     
  82. /*计算模式串的指纹函数值,对应算法14.9步骤(3)*/
  83. if(myrank==0) {
  84.    for(i=1;i<=m;i++) {
  85.      B[i][0][0]=f[Pattern[i-1]-'0'][0][0];
  86.      B[i][0][1]=f[Pattern[i-1]-'0'][0][1];
  87.      B[i][1][0]=f[Pattern[i-1]-'0'][1][0];
  88.      B[i][1][1]=f[Pattern[i-1]-'0'][1][1];
  89.    }
  90.        B[0][0][0]=(B[1][0][0]*B[2][0][0]+B[1][0][1]*B[2][1][0])%p;
  91.        B[0][0][1]=(B[1][0][0]*B[2][0][1]+B[1][0][1]*B[2][1][1])%p;
  92.        B[0][1][0]=(B[1][1][0]*B[2][0][0]+B[1][1][1]*B[2][1][0])%p;
  93.        B[0][1][1]=(B[1][1][0]*B[2][0][1]+B[1][1][1]*B[2][1][1])%p;
  94.      for(j=1;j<=m-2;j++){
  95.        B[j][0][0]=(B[j-1][0][0]*B[j+2][0][0]+B[j-1][0][1]*B[j+2][1][0])%p;
  96.        B[j][0][1]=(B[j-1][0][0]*B[j+2][0][1]+B[j-1][0][1]*B[j+2][1][1])%p;
  97.        B[j][1][0]=(B[j-1][1][0]*B[j+2][0][0]+B[j-1][1][1]*B[j+2][1][0])%p;
  98.        B[j][1][1]=(B[j-1][1][0]*B[j+2][0][1]+B[j-1][1][1]*B[j+2][1][1])%p;
  99.      }
  100.       fp_pattern[0][0]=B[m-2][0][0];
  101.       fp_pattern[0][1]=B[m-2][0][1];
  102.       fp_pattern[1][0]=B[m-2][1][0];
  103.       fp_pattern[1][1]=B[m-2][1][1];
  104.    }
  105.     
  106.    MPI_Bcast(fp_pattern,4,MPI_INT,0,MPI_COMM_WORLD);
  107.    MPI_Barrier(MPI_COMM_WORLD);
  108.     
  109.    /*计算Ni,存放在数组C中*/
  110.    for(i=1;i<=textlen;i++) {
  111.      B[i][0][0]=f[Text[i-1]-'0'][0][0];
  112.      B[i][0][1]=f[Text[i-1]-'0'][0][1];
  113.      B[i][1][0]=f[Text[i-1]-'0'][1][0];
  114.      B[i][1][1]=f[Text[i-1]-'0'][1][1];
  115.    }
  116.     C[1][0][0]=B[1][0][0];
  117.     C[1][0][1]=B[1][0][1];
  118.     C[1][1][0]=B[1][1][0];
  119.     C[1][1][1]=B[1][1][1];
  120. for(i=2;i<=textlen;i++) {
  121.        C[i][0][0]=(C[i-1][0][0]*B[i][0][0]+C[i-1][0][1]*B[i][1][0])%p;
  122.        C[i][0][1]=(C[i-1][0][0]*B[i][0][1]+C[i-1][0][1]*B[i][1][1])%p;
  123.        C[i][1][0]=(C[i-1][1][0]*B[i][0][0]+C[i-1][1][1]*B[i][1][0])%p;
  124.        C[i][1][1]=(C[i-1][1][0]*B[i][0][1]+C[i-1][1][1]*B[i][1][1])%p;
  125. }
  126. if(groupsize>1) {
  127.     if(myrank==0) {
  128. MPI_Send(&C[textlen],4,MPI_INT,myrank+1,myrank,MPI_COMM_WORLD);
  129. }
  130. else if(myrank==groupsize-1) {
  131. MPI_Recv(&C[0],4,MPI_INT,myrank-1,myrank-1,MPI_COMM_WORLD,&status);
  132. }
  133. else {
  134. MPI_Recv(&C[0],4,MPI_INT,myrank-1,myrank-1,MPI_COMM_WORLD,&status);
  135. i=textlen;
  136.        C[textlen+1][0][0]=(C[0][0][0]*C[i][0][0]+C[0][0][1]*C[i][1][0])%p;
  137.        C[textlen+1][0][1]=(C[0][0][0]*C[i][0][1]+C[0][0][1]*C[i][1][1])%p;
  138.        C[textlen+1][1][0]=(C[0][1][0]*C[i][0][0]+C[0][1][1]*C[i][1][0])%p;
  139.        C[textlen+1][1][1]=(C[0][1][0]*C[i][0][1]+C[0][1][1]*C[i][1][1])%p;
  140.     C[i][0][0]=C[textlen+1][0][0];
  141.     C[i][0][1]=C[textlen+1][0][1];
  142.     C[i][1][0]=C[textlen+1][1][0];
  143.     C[i][1][1]=C[textlen+1][1][1];
  144. MPI_Send(&C[textlen],4,MPI_INT,myrank+1,myrank,MPI_COMM_WORLD); 
  145. }
  146. }
  147.    MPI_Barrier(MPI_COMM_WORLD);
  148. if(myrank!=0) {
  149. for(i=1;i<textlen;i++) {
  150.        C[textlen+1][0][0]=(C[0][0][0]*C[i][0][0]+C[0][0][1]*C[i][1][0])%p;
  151.        C[textlen+1][0][1]=(C[0][0][0]*C[i][0][1]+C[0][0][1]*C[i][1][1])%p;
  152.        C[textlen+1][1][0]=(C[0][1][0]*C[i][0][0]+C[0][1][1]*C[i][1][0])%p;
  153.        C[textlen+1][1][1]=(C[0][1][0]*C[i][0][1]+C[0][1][1]*C[i][1][1])%p;
  154.     C[i][0][0]=C[textlen+1][0][0];
  155.     C[i][0][1]=C[textlen+1][0][1];
  156.     C[i][1][0]=C[textlen+1][1][0];
  157.     C[i][1][1]=C[textlen+1][1][1];
  158. }
  159.    MPI_Barrier(MPI_COMM_WORLD);
  160. if(groupsize>1) {
  161.     if(myrank==0) {
  162. MPI_Recv(&C[textlen+1],4*(m-1),MPI_INT,myrank+1,myrank,MPI_COMM_WORLD,&status);
  163. }
  164. else if(myrank==groupsize-1) {
  165. MPI_Send(&C[1],4*(m-1),MPI_INT,myrank-1,myrank-1,MPI_COMM_WORLD);
  166. }
  167. else {
  168. MPI_Recv(&C[textlen+1],4*(m-1),MPI_INT,myrank+1,myrank,MPI_COMM_WORLD,&status);
  169. MPI_Send(&C[1],4*(m-1),MPI_INT,myrank-1,myrank-1,MPI_COMM_WORLD); 
  170. }
  171. }
  172.    /*计算Ri,存放在数组D中*/
  173.    for(i=1;i<=textlen;i++) {
  174.      B[i][0][0]=g[Text[i-1]-'0'][0][0];
  175.      B[i][0][1]=g[Text[i-1]-'0'][0][1];
  176.      B[i][1][0]=g[Text[i-1]-'0'][1][0];
  177.      B[i][1][1]=g[Text[i-1]-'0'][1][1];
  178.    }
  179.     D[1][0][0]=B[1][0][0];
  180.     D[1][0][1]=B[1][0][1];
  181.     D[1][1][0]=B[1][1][0];
  182.     D[1][1][1]=B[1][1][1];
  183. for(i=2;i<=textlen;i++) {
  184.        D[i][0][0]=(B[i][0][0]*D[i-1][0][0]+B[i][0][1]*D[i-1][1][0])%p;
  185.        D[i][0][1]=(B[i][0][0]*D[i-1][0][1]+B[i][0][1]*D[i-1][1][1])%p;
  186.        D[i][1][0]=(B[i][1][0]*D[i-1][0][0]+B[i][1][1]*D[i-1][1][0])%p;
  187.        D[i][1][1]=(B[i][1][0]*D[i-1][0][1]+B[i][1][1]*D[i-1][1][1])%p;
  188. }
  189. if(groupsize>1) {
  190.     if(myrank==0) {
  191. MPI_Send(&D[textlen],4,MPI_INT,myrank+1,myrank,MPI_COMM_WORLD);
  192. }
  193. else if(myrank==groupsize-1) {
  194. MPI_Recv(&D[0],4,MPI_INT,myrank-1,myrank-1,MPI_COMM_WORLD,&status);
  195. }
  196. else {
  197. MPI_Recv(&D[0],4,MPI_INT,myrank-1,myrank-1,MPI_COMM_WORLD,&status);
  198. i=textlen;
  199.         D[textlen+1][0][0]=(D[i][0][0]*D[0][0][0]+D[i][0][1]*D[0][1][0])%p;
  200.         D[textlen+1][0][1]=(D[i][0][0]*D[0][0][1]+D[i][0][1]*D[0][1][1])%p;
  201.         D[textlen+1][1][0]=(D[i][1][0]*D[0][0][0]+D[i][1][1]*D[0][1][0])%p;
  202.         D[textlen+1][1][1]=(D[i][1][0]*D[0][0][1]+D[i][1][1]*D[0][1][1])%p;
  203.     D[i][0][0]=D[textlen+1][0][0];
  204.     D[i][0][1]=D[textlen+1][0][1];
  205.     D[i][1][0]=D[textlen+1][1][0];
  206.     D[i][1][1]=D[textlen+1][1][1];
  207. MPI_Send(&D[textlen],4,MPI_INT,myrank+1,myrank,MPI_COMM_WORLD); 
  208. }
  209. }
  210.    MPI_Barrier(MPI_COMM_WORLD);
  211. if(myrank==0) {
  212.     D[0][0][0]=1;
  213.     D[0][0][1]=0;
  214.     D[0][1][0]=0;
  215.     D[0][1][1]=1;
  216. }
  217. if(myrank!=0) {
  218. for(i=1;i<textlen;i++) {
  219.        D[textlen+1][0][0]=(D[i][0][0]*D[0][0][0]+D[i][0][1]*D[0][1][0])%p;
  220.        D[textlen+1][0][1]=(D[i][0][0]*D[0][0][1]+D[i][0][1]*D[0][1][1])%p;
  221.        D[textlen+1][1][0]=(D[i][1][0]*D[0][0][0]+D[i][1][1]*D[0][1][0])%p;
  222.        D[textlen+1][1][1]=(D[i][1][0]*D[0][0][1]+D[i][1][1]*D[0][1][1])%p;
  223.     D[i][0][0]=D[textlen+1][0][0];
  224.     D[i][0][1]=D[textlen+1][0][1];
  225.     D[i][1][0]=D[textlen+1][1][0];
  226.     D[i][1][1]=D[textlen+1][1][1];
  227. }
  228.   
  229.    MPI_Barrier(MPI_COMM_WORLD);
  230.   for(i=1;i<=textlen;i++)
  231.    MATCH[i]=0;
  232. /*各个处理器分别计算所分配的文本串的Li,并判别是否存在匹配位置,对应算法14.9的步骤(4)*/  
  233. if(myrank==groupsize-1) {
  234.    for(i=1;i<=textlen-m+1;i++){
  235.      L[i][0][0]=(D[i-1][0][0]*C[i+m-1][0][0]+D[i-1][0][1]*C[i+m-1][1][0])%p;      
  236.      L[i][0][1]=(D[i-1][0][0]*C[i+m-1][0][1]+D[i-1][0][1]*C[i+m-1][1][1])%p;      
  237.      L[i][1][0]=(D[i-1][1][0]*C[i+m-1][0][0]+D[i-1][1][1]*C[i+m-1][1][0])%p;      
  238.      L[i][1][1]=(D[i-1][1][0]*C[i+m-1][0][1]+D[i-1][1][1]*C[i+m-1][1][1])%p;      
  239.      if(((L[i][0][0]+p)%p==fp_pattern[0][0]) 
  240. && ((L[i][0][1]+p)%p==fp_pattern[0][1])
  241. && ((L[i][1][0]+p)%p==fp_pattern[1][0]) 
  242. && ((L[i][1][1]+p)%p==fp_pattern[1][1])) {
  243.        MATCH[i]=1;
  244. printf("on node %d match pos is %dn",myrank,i);
  245. }
  246. }
  247. }
  248. else {
  249.    for(i=1;i<=textlen;i++){
  250.      L[i][0][0]=(D[i-1][0][0]*C[i+m-1][0][0]+D[i-1][0][1]*C[i+m-1][1][0])%p;      
  251.      L[i][0][1]=(D[i-1][0][0]*C[i+m-1][0][1]+D[i-1][0][1]*C[i+m-1][1][1])%p;      
  252.      L[i][1][0]=(D[i-1][1][0]*C[i+m-1][0][0]+D[i-1][1][1]*C[i+m-1][1][0])%p;      
  253.      L[i][1][1]=(D[i-1][1][0]*C[i+m-1][0][1]+D[i-1][1][1]*C[i+m-1][1][1])%p;      
  254.      if(((L[i][0][0]+p)%p==fp_pattern[0][0]) 
  255. && ((L[i][0][1]+p)%p==fp_pattern[0][1])
  256. && ((L[i][1][0]+p)%p==fp_pattern[1][0]) 
  257. && ((L[i][1][1]+p)%p==fp_pattern[1][1])) {
  258.        MATCH[i]=1;
  259. printf("on node %d match pos is %dn",myrank,i);
  260. }
  261. }
  262. }
  263. MPI_Finalize();  
  264. }