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 }

 

posted @ 2017-05-10 23:39  SimonKly  阅读(422)  评论(0编辑  收藏  举报