apriori算法
#include<cstdio> #include<algorithm> using namespace std; int n,k=1,maxi; double mins;//最小支持度 int d[15][15];//交易数据集 struct item//项集类型 { int cnt;//元素的个数 int a[15];//项集内的元素 double s;//支持度 }; struct tab//列表类型 { int cnt;//项集的个数 item it[1005]; }c[15],l[15]; int sia(int di,int x)//在第di个事务中寻找项集的一个单元素子集 { for(int i=1;i<=d[di][0];i++) { if(d[di][i]==x) return 1; } return 0; } double si(item x)//在d中寻找任意一个项集出现的次数 { double s=0; for(int i=1;i<=n;i++) { int flg=1; for(int j=1;j<=x.cnt;j++) { if(!sia(i,x.a[j])) flg=0; } if(flg) s=s+1; } return s; } item link(item x,item y)//连接两个项集生成一个新的项集 { item re; re.cnt=x.cnt+y.cnt; for(int i=1;i<=x.cnt;i++) re.a[i]=x.a[i]; for(int i=1+x.cnt;i<=x.cnt+y.cnt;i++) re.a[i]=y.a[i-x.cnt]; sort(re.a+1,re.a+x.cnt+y.cnt+1);//通过排序去除重复的元素 for(int i=1;i<re.cnt;i++) { if(re.a[i]==re.a[i+1]) { for(int j=i+1;j<re.cnt;j++) re.a[j]=re.a[j+1]; re.cnt--; } } re.s=si(re)/n; return re; } void cre(int x)//c[k]->l[k] { for(int i=1;i<=c[x].cnt;i++) { if(c[x].it[i].s>=mins) { l[x].cnt++; l[x].it[l[x].cnt]=c[x].it[i]; } } if(!l[x].cnt ) return; printf("第%d次迭代产生%d个频繁集:\n",k,l[x].cnt); for(int i=1;i<=l[x].cnt;i++) { for(int j=1;j<=l[x].it[i].cnt;j++) printf("%d ",l[x].it[i].a[j]); printf("\n"); } printf("\n"); return; } int ex(item t)//项集是否存在 { int flg=0;//是否有重复的项集 for(int i=1;i<=c[k].cnt;i++) { int tf=1;//和第i个项集是否不同 for(int j=1;j<=t.cnt;j++) { if(t.a[j]!=c[k].it[i].a[j]) tf=0;//两个项集每一位都相同 } if(tf) flg=1;//有重复的项集 } return flg; } int main() { scanf("%lf",&mins); scanf("%d",&n); for(int i=1;i<=n;i++) { int cnt=0,x; while(1) { scanf("%d",&x); if(x==-1) break;//输入-1代表事务结束 d[i][0]++;//d[i][0]表示第i个事务的商品数 d[i][d[i][0]]=x; if(x>maxi) maxi=x;//maxi表示不同的元素种类 } } for(int i=1;i<=maxi;i++)//生成初始的候选集c[1] { double cnt=0; for(int j=1;j<=n;j++) { for(int p=1;p<=d[j][0];p++) { if(d[j][p]==i) cnt=cnt+1; } } c[1].it[i].s=0; c[1].it[i].a[1]=i; c[1].it[i].cnt=1; c[1].it[i].s=cnt/n; c[1].cnt++; } cre(1); while(k)//l[k-1]->c[k] { ++k; for(int i=1;i<l[k-1].cnt;i++) { for(int j=i+1;j<=l[k-1].cnt;j++) { item t=link(l[k-1].it[i],l[k-1].it[j]); if(t.cnt==k) { if(ex(t)) continue;//去重 c[k].cnt++; c[k].it[c[k].cnt]=t; } } } cre(k); if(!l[k].cnt) break; } return 0; } /* 样例数据 0.2 9 1 2 5 -1 2 4 -1 2 3 -1 1 2 4 -1 1 3 -1 2 3 -1 1 3 -1 1 2 3 5 -1 1 2 3 -1 */