#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 #
运行结果