数据挖掘实验:Apriori算法实现C++

来源:互联网 发布:网络流行词大全 编辑:程序博客网 时间:2024/04/28 05:31

说起来数据挖掘这门课我还是蛮喜欢的,所以实验内容也都是自己实现的,第一个Apriori算法,思想很简单,什么都没有就是暴力,我加了一个Hash,总共也才写了100来行,具体内容代码注释中很清楚我就不多说了。以下附上主要函数的代码(省去部分)。


主要的东西呢就是把所有的事务映射成一个数字然后直接用string存储。好吧我承认我在偷懒,这个方法是有问题的,事务多了之后会出现歧义。会有错误。但是我不想改了hhhh让我当一条咸鱼吧。

#include <cstdio>#include <iostream>#include <set>#include <map>#include <algorithm>using namespace std;const int maxn = 105;///最大记录条数int n;///记录条数int min_sup;///最小支持度bool flag;///产生新集的标记map<string, int> m;///将项名Hash后存储map<int, string> mp;///逆Hashset<int> D[maxn];///事务数据库set<string> fre;///频繁项集的集合(每个string存储一个频繁项集)set<string> cand;///候选项集的集合(每个string存储一个候选项集)char name[maxn];string t;int cnt, x;///利用先验性质的剪枝bool check(){    string s;///获取候选项的子集    for(int i = 0;i < t.size();i ++){        s = t;        s.erase(i, 1);        if(!fre.count(s)) return false;///验证失败    }    return true;///验证成功}///获取候选项集void get_cand(int num){    cand.clear();    for(set<string>::iterator i = fre.begin();i != fre.end();i ++)        for(set<string>::iterator j = fre.begin();j != fre.end();j ++){            t = *i;            ///去重合并            for(int k = 0;k < (*j).size();k ++)                if(t.find((*j)[k]) == string::npos) t += (*j)[k];            sort(t.begin(), t.end());            if(t.size() != num) continue;            if(check()) cand.insert(t);///剪枝        }    return;}///支持度计数,获取频繁项集bool get_fre(int num){    set<string> tfre;    for(set<string>::iterator i = cand.begin();i != cand.end();i ++){        t = *i;        int sum = 0;        for(int j = 0;j < n;j ++){            bool f1 = true;            ///判断是否所有项都存在            for(int k = 0;k < t.size();k ++)            if(!D[j].count(t[k] - 48)) {                f1 = false;                break;            }            if(f1) sum ++;///计数+        }        if(sum >= min_sup) tfre.insert(t);///满足最小支持度    }    if(tfre.size() == 0) return false;    fre = tfre;    return true;}int main(){    //freopen("ap.txt", "r", stdin);    printf("记录条数:");    while(~scanf("%d", &n)){        m.clear();        cnt = 0;        for(int i = 0;i < n;i ++){            scanf("%d", &x);            while(x --){                scanf("%s", name);                t = name;                //利用Map的Hash部分和插入事务数据库部分省略...            }        }        printf("最小支持度:");        scanf("%d", &min_sup);        ///获得频繁1项集        for(int i = 0;i < cnt;i ++){            int sum = 0;            for(int j = 0;j < n;j ++)                if(D[j].count(i)) sum ++;            if(sum >= min_sup) {///计数完毕,满足最小支持度                t = i + 48;                fre.insert(t);            }        }        flag = true;        int num = 1;///候选项数        while(flag){            flag = false;            get_cand(++ num);///获取候选项集            if(get_fre(num))///获取频繁项集,空集返回false                flag = true;        }        printf("最大项数:%d\n", num - 1);        for(set<string>::iterator i = fre.begin();i != fre.end();i ++){            printf("{");            for(int j = 0;j < (*i).size();j ++)                printf("%s%c", mp[(*i)[j] - 48].c_str(), j + 1 == (*i).size()?'}':',');            printf("\n");        }    }    return 0;}


原创粉丝点击