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都是频繁的。所以如果判断得到相同位置项集相同才会连接。

  • 相关阅读:
    Android 中文 SDK (47) —— Filter
    Android 中文API (65) —— BluetoothClass[蓝牙]
    Android 中文 API——android.widget合集(中)(50篇)(chm格式)
    android 中文 api (72) —— BluetoothSocket[蓝牙]
    Android 中文API (61) —— ViewSwitcher
    Android API 中文 (51) —— ZoomButtonsController
    Android API 中文 (55) —— ListAdapter
    Android SDK 中文 (56) —— ViewFlipper
    什么是 COM编程技术?
    怎么打出全角的小写英文字母?
  • 原文地址:https://www.cnblogs.com/froid/p/4392627.html
Copyright © 2011-2022 走看看