FM算法组合估计
1 #include <stdio.h> 2 #include <math.h> 3 #include <stdlib.h> 4 #include <time.h> 5 6 #define NUM (int)pow(2.0,25)+1 7 8 int length=0;//计算长度 9 int data[350000];//存放数据流 10 11 struct node 12 { 13 int data; 14 struct node* next; 15 }; 16 struct node* creat()//创建链表 17 { 18 int x; 19 struct node *tail,*p,*head; 20 head=(struct node *)malloc(sizeof(struct node)); 21 head->next=NULL; 22 tail=head; 23 //FILE *fp=fopen("./stream_for_fm.txt","r"); 24 FILE *fp=fopen("./stream_sample_fm.txt","r");//样本 25 if(fp==NULL) 26 { 27 printf("file open failed!\n"); 28 exit(0); 29 } 30 while(!feof(fp)) 31 { 32 fscanf(fp,"%d",&x); 33 p=(struct node *)malloc(sizeof(struct node)); 34 p->data=x; 35 tail->next=p; 36 p->next=NULL; 37 tail=p; 38 data[length++]=x; 39 } 40 printf("链表创建成功!\n"); 41 return head; 42 } 43 /*排序链表*/ 44 struct node *sort(struct node *head) 45 { 46 struct node *p,*q; 47 for(p=head->next;p!=NULL;p=p->next) 48 { 49 for(q=p->next;q!=NULL;q=q->next) 50 { 51 if(p->data > q->data) 52 { 53 int tmp=p->data; 54 p->data=q->data; 55 q->data=tmp; 56 } 57 } 58 } 59 printf("链表排序完成!\n"); 60 return head; 61 } 62 63 /*计算有多少不同元素*/ 64 int different_node_count(struct node *head) 65 { 66 struct node *p,*q,*tmp; 67 int count_equal=0,count_total=0; 68 tmp=NULL; 69 70 for(p=head->next;p!=NULL;p=p->next) 71 { 72 for(q=p->next;q!=NULL;q=q->next) 73 { 74 if(p->data == q->data) 75 { 76 count_equal++;//相同元素加 77 tmp=q;//记录最后一个相同的元素位置 78 } 79 else 80 { 81 break; 82 } 83 } 84 if(tmp!=NULL) 85 { 86 p=tmp; 87 tmp=NULL; 88 } 89 //count_total++;//统计全部节点的个数 90 } 91 printf("不同节点的个数%d\n节点总数:%d\n",length-count_equal,length); 92 return length-count_equal; 93 } 94 //计算尾数 95 int get_tailnum(long long a) 96 { 97 int i=0,count =0; 98 while(a!=0) 99 { 100 if(0 == a%2) 101 { 102 count++; 103 } 104 else 105 { 106 break; 107 } 108 a=a/2; 109 i++; 110 } 111 return count; 112 } 113 114 int main() 115 { 116 struct node *head; 117 int only_value; 118 int M=4,L=4; 119 int i,j,k,x; 120 int circle=20; 121 long long h,a,b; 122 int R[20][20];//尾数 123 int max_tailnum=0,tmp;//最大尾长 124 double ave_tail[20]={0};//最大尾数的平均数 125 int mid_tail;//平均尾数的中位数 126 int estimate[30];//存入估计值 127 double error;//误差 128 long long sum=0; 129 130 head=creat(); 131 head=sort(head); 132 only_value=different_node_count(head); 133 srand(time(0)); 134 for(x=0;x<circle;x++) 135 { 136 for(i=0;i<M;i++)//分组M 137 { 138 for(j=0;j<L;j++)//每组L个hash 139 { 140 a=rand()%NUM; 141 b=rand()%NUM; 142 max_tailnum=0; 143 for(k=0;k<length;k++) 144 { 145 tmp=get_tailnum(a*data[k]+b); 146 if(max_tailnum<tmp) 147 { 148 max_tailnum=tmp; 149 } 150 } 151 R[i][j]=max_tailnum; 152 } 153 for(j=0;j<L;j++) 154 { 155 ave_tail[i]+=R[i][j]; 156 } 157 ave_tail[i]/=L;//每组的平均值 158 } 159 160 if(M%2==0) 161 { 162 mid_tail=(ave_tail[M/2]+ave_tail[M/2+1])/2; 163 } 164 else 165 { 166 mid_tail=ave_tail[M/2]; 167 } 168 169 estimate[x]=(int)pow(2.0,mid_tail); 170 171 //ave_tail尾长的平均值清零 172 for(int i=0 ;i < 20 ;i ++) 173 { 174 ave_tail[i]=0; 175 } 176 } 177 int temp=0; 178 printf("估计元素个数"); 179 for(i=0;i<circle;i++) 180 { 181 temp+=estimate[i]; 182 //printf("%8d",estimate[i]); 183 sum+=(estimate[i]-only_value)*(estimate[i]-only_value); 184 } 185 printf("%lf",temp/(double)circle); 186 putchar('\n'); 187 error=sqrt(sum/(double)only_value); 188 printf("误差(方差):%lf\n",error); 189 system("pause"); 190 return 0; 191 }