Apriori算法的C++实现

来源:互联网 发布:nginx body filter 编辑:程序博客网 时间:2024/04/30 11:07
#include<bits/stdc++.h>using namespace std;/*1.若X为频繁项目集,则X的所有子集都是频繁项目集2.若X为非频繁项目集,则X的所有超集均为非频繁项目集*/int min_sup;//最小支持度vector<set<string> > item;//存储最开始的事务及其项map<set<string>, int> k_item;//频繁k项集map<set<string>, int> houxuan;//候选void pri_k_item(map<set<string>, int> k_i);//用户输入事务void getItem(){    int itemSize;    cout<<"请输入事务的数目"<<endl;    cin>>itemSize;    for(int i = 0; i < itemSize; i++){        cout<<"请输入第"<<i + 1<<"个事务(输入#表示事务输入结束)"<<endl;        string everyItem;        set<string> everyItems;        while(cin>>everyItem && everyItem != "#"){            everyItems.insert(everyItem);        }        item.push_back(everyItems);    }}//找出频繁1项集void find_frequent_1(){    map<string, int> zan;    map<string, int>::iterator it;    //候选1项集    for(int i = 0; i < item.size(); i++){        set<string>::iterator itemi = item[i].begin();        for(itemi = item[i].begin(); itemi != item[i].end(); itemi++){            if(zan.find(*itemi) != zan.end()){                zan[*itemi]++;            }else{                zan[*itemi] = 1;            }        }    }    //频繁1项集    for(it = zan.begin(); it != zan.end(); it++){        if(it->second >= min_sup){            set<string> e;            e.insert(it->first);            k_item[e] = it->second;        }    }}/*频繁项集**连接**得到候选项集合返回1得到k+1候选项返回0不能得到k+1候选项*/bool apriori_gen(int k){    houxuan.clear();    map<set<string>, int>::iterator i;    map<set<string>, int>::iterator j;    for(i = k_item.begin(); i != k_item.end(); i++){        set<string> A = i->first;        for(j = i; j != k_item.end(); j++){            set<string> B = j->first;            set<string> C;            set_union(A.begin(), A.end(), B.begin(), B.end(), inserter(C, C.begin()));            if(C.size() == k + 1){                houxuan[C] = 0;            }        }    }    return houxuan.size() > 0;}/*剪枝得到频繁项集返回1得到k+1候选项返回0不能得到k+1候选项*/bool has_infrequent_sub(int k){    map<set<string>, int>::iterator i;    map<set<string>, int>::iterator j;    map<set<string>, int> zank = houxuan;    //判断候选项的子集是否频繁    for(i = houxuan.begin(); i != houxuan.end(); i++){        set<string> A = i->first;        set<string>::iterator ii;        for(ii = A.begin(); ii != A.end(); ii++){            set<string> B = i->first;            B.erase(*ii);//B是A的k项子集            if(k_item.find(B) == k_item.end()){//子集非频繁,则剪枝                zank.erase(i->first);                break;            }        }    }    houxuan = zank;    zank.clear();    //扫描原数据,统计候选集的支持度    for(i = houxuan.begin(); i != houxuan.end(); i++){        set<string> A = i->first;        int sum = 0;        for(int j = 0; j < item.size(); j++){            set<string> B = item[j];            set<string> C;            set_difference(A.begin(), A.end(), B.begin(), B.end(), inserter(C, C.begin()));            if(C.size() == 0){                sum++;            }        }        if(sum >= min_sup){            zank[A] = sum;        }    }    if(zank.size() > 0){        k_item.clear();        k_item = zank;        return 1;    }    return 0;}//输出频繁K项集void pri_k_item(map<set<string>, int> k_i){    cout<<"**********************************"<<endl;    map<set<string>, int>::iterator it;    for(it = k_i.begin(); it != k_i.end(); it++){        set<string> e = it->first;        set<string>::iterator ite;        for(ite = e.begin(); ite != e.end(); ite++){            cout<<*ite<<" ";        }        cout<<it->second<<endl;    }    cout<<"**********************************"<<endl;}int main(){    cout<<"请输入最小支持度阈值"<<endl;    cin>>min_sup;    //输入事务    getItem();    //找1项频繁项集    find_frequent_1();    pri_k_item(k_item);    int k = 0;    while(true){        k++;        if(!apriori_gen(k)){            break;        }        cout<<"候选"<<endl;        pri_k_item(houxuan);        if(!has_infrequent_sub(k)){            break;        }        cout<<"频繁"<<endl;        pri_k_item(k_item);    }    cout<<"最终结果"<<endl;    pri_k_item(k_item);}

样例:

请输入最小支持度阈值
2
请输入事务的数目
4
请输入第1个事务(输入#表示事务输入结束)
A C D #
请输入第2个事务(输入#表示事务输入结束)
B C E #
请输入第3个事务(输入#表示事务输入结束)
A B C E #


运行结果
这里写图片描述

0 0
原创粉丝点击