zoukankan      html  css  js  c++  java
  • Apriori算法-数组-C语言

    原文地址:http://blog.csdn.net/liema2000/article/details/6118423

    #include<stdio.h>
    typedef struct
    {
    int item[100]; //数据项
    } D_Node; //数据库D

    typedef struct
    {
    int item[100]; //数据项,用item[0]保存支持度
    } C_Node; //候选集

    typedef struct
    {
    int item[100]; //数据项,用item[0]保存支持度
    } L_Node;//频繁集

    C_Node C[100][100];
    L_Node L[100][100];
    D_Node D[100];

    int min_supp; //最小支持度

    void InPut()
    {
    int i,j,n,n1;//n是交易集的大小,n1是输入的记录个数,数据输入到D[100]中
    printf("请输入最小支持度:");
    scanf("%d",&min_supp);
    printf("请输入交易集的大小");
    scanf("%d",&D[0].item[0]);
    n=D[0].item[0];
    for(i=1;i<=n;i++) //for1
    {
    printf("请输入交易[%d]中记录的个数(n)",i);
    scanf("%d",&n1);
    D[i].item[0]=n1;
    for(j=1;j<=n1;j++) //for2
    {
    printf("请输入交易[%d]中记录项,直接输入数字:",i);
    scanf("%d",&D[i].item[j]);
    }//for2

    } //for1

    }//end of InPut

    void C1()
    {
    //功能:扫描数据集D生成1项候选集C1
    //输入:数据集D
    //输出1项候选集C1
    //初始条件 数据集D 非空
    /* 将D放入C中,D[0]item[0]是交易集个数,D[1]item[0]是第一个交易集的数据项个数,
    D[1]item[1]到D[1]item[个数]是第一个交易集合的数据。
    c不管交易集个数,只看数据项。C[n][k].item[0]是候选集Cn的第k项的支持度,
    c[1][1]item[1]数据项,c[1][1]item[0]此数据项的个数。c[1][0]item[0]中no是不同数据项的个数。
    */
    int i,j,k;
    int no=1,temp=0; //no是不重复的数据项的个数
    C[1][0].item[0]=0; //1 项集的个数,在本算法中,用C[n][k].item[0]来保存候选集Cn的第k项的支持度
    if(D[0].item[0]!=0)
    {
    C[1][1].item[1]=D[1].item[1];

    }

    for(i=1;i<=D[0].item[0];i++) //for1 交易集
    {

    for(j=1;j<=D[i].item[0];j++) //for2 某个交易集中的记录
    {
    temp=1;
    for(k=1;k<=no;k++) //for3
    {
    if(C[1][k].item[1]==D[i].item[j])
    {
    C[1][k].item[0]++; //支持度加1
    temp=0;

    } //if
    }//end for3


    if(temp)//生成新的项集
    {
    C[1][++no].item[1]=D[i].item[j];
    C[1][no].item[0]=1;
    }

    }//end for2

    } // end for1
    C[1][0].item[0]=no;//数据项的个数
    } //end of C1()

    void Cn( int n)
    {
    //用频繁集Ln-1为基础,通过连接得到n项候选集Cn
    int i,j,k,p,q,s,t,num;
    int no=0,temp=0,count;
    C[n][0].item[0]=0; //初始化
    num=L[n-1][0].item[0]; //num是Ln-1项集的数据个数
    for(i=1;i<=num;i++)

    for(j=i+1;j<=num;j++) //for2
    {

    temp=1; //测试是否满足联结条件
    if(n>2)//if 1 不是一项集连时,可能有重复项
    {
    for(k=1;k<n-1;k++) //for3
    {
    if(L[n-1][i].item[k]!=L[n-1][j].item[k])//相同位置有相同的项才可以连接
    {
    temp=0;
    break;
    }//if 1
    }//end for3
    }//end if1
    if(temp==1)//满足联结条件
    {
    no++;
    for(p=1;p<=n-1;p++)
    C[n][no].item[p]=L[n-1][i].item[p];
    C[n][no].item[p]=L[n-1][j].item[p-1]; //这行p是执行p++之后的,比上行p大1
    C[n][no].item[0]=0;
    for(q=1;q<=D[0].item[0];q++) //for5 测试其支持度
    {
    count=0; //count用来记数,当所测试的项存在时,count加1,当count=n时,则子集存在
    for(s=1;C[n][no].item[s]!=0;s++) //for6
    {
    for(t=1;t<=D[q].item[0];t++) //for7
    {
    if(C[n][no].item[s]==D[q].item[t])
    { count+=1;
    break;
    }
    }//end for7

    }//end for 6
    if(count==n) C[n][no].item[0]+=1;//子集存在,第no项的支持度加1

    }//end for5

    C[n][0].item[0]+=1;
    }//end if2
    }//end for2

    }//end of Cn()

    void Ln(int n)
    {
    int i,j,k;
    j=0;
    L[n][0].item[0]=0;
    for(i=1;i<=C[n][0].item[0];i++) //for 1
    {
    if(C[n][i].item[0]>=min_supp)
    {
    j+=1;
    for(k=1;k<=n;k++)
    L[n][j].item[k]=C[n][i].item[k];
    L[n][j].item[0]=C[n][i].item[0];
    } //end if

    }//end for1

    L[n][0].item[0]=j; //保存数据的个数
    }//end of Ln(int n)

    void OutPut(int n)
    {
    int i,j,k;
    printf("频繁项目集L%d如下: ",n);
    k=L[n][0].item[0];
    if(k!=0)
    {
    for(i=1;i<=k;i++)
    {
    printf("{");
    for(j=1;j<=n;j++)
    printf(" I%d ",L[n][i].item[j]);
    printf("} 支持度:%d ",L[n][i].item[0]);

    }//for

    }
    else
    printf("项目集为空 ");
    }

    void main()
    {
    int i;
    int n=1;
    InPut();
    C1();//初始化,生成1项候选集C1
    Ln(1);//得到1项频繁集L1
    while(L[n][0].item[0]!=0)
    {
    n+=1;
    Cn(n);
    Ln(n);
    }
    for(i=1;i<=n;i++)
    OutPut(i);
    }

    效果图:

     

    测试案例:(我的疑惑点)

    令交易4的记录为23,34则L2中是12,23两次 23,34三次。这种情况不会生成频繁三项集。

    如果12,23,34是频繁的,则12,23和12,24都是频繁的。所以如果判断得到相同位置项集相同才会连接。

  • 相关阅读:
    UVA 10462 Is There A Second Way Left?(次小生成树&Prim&Kruskal)题解
    POJ 1679 The Unique MST (次小生成树)题解
    POJ 2373 Dividing the Path (单调队列优化DP)题解
    BZOJ 2709 迷宫花园
    BZOJ 1270 雷涛的小猫
    BZOJ 2834 回家的路
    BZOJ 2506 calc
    BZOJ 3124 直径
    BZOJ 4416 阶乘字符串
    BZOJ 3930 选数
  • 原文地址:https://www.cnblogs.com/froid/p/4392627.html
Copyright © 2011-2022 走看看