FP-tree算法比Apriori算法更难实现,主要是其中用的一些特殊的数据结构,对我来说都不太熟,不像Apriori只用一些数组就能简单得实现。
失败的例子
和Apriori一样,我第一次实现的时候,也是想着用的vector的存储结构来实现树,定义了一个如下的结构体
struct TreeNode
{
int Id;
int Co;
TreeNode *Parent;
TreeNode *HeadNext;
vector<TreeNode*> Children;
};
int InitTree(TreeNode &T)
{
TreeNode temp;
temp.Id=0;
temp.Co=0;
temp.Parent=NULL;
temp.HeadNext=NULL;
temp.Children.clear();
T=temp;
return 0;
}
但是在扫描数据库建树的时候,效率极其低下,扫描8万行的数据集大概需要20个小时。可能是对树的构造还是不太熟,虽然这样子能够应该能够实现建成一棵FPTree,但是不实用,所以就没继续照着这个思路寻找条件模式基。
int AddTree(TreeNode &T,int a,int next,vector<vector<int> > sim)//sim为去除了非频繁一项集且排序好的全体数据集
{
if(next>=sim[a].size()) return next;
else{
int locate=0;
TreeNode *NewNode;
NewNode=new(TreeNode);
int to=-1;
if(T.Children.size()==0)
{
NewNode->Id=sim[a][next];
next++;
NewNode->Co=1;
NewNode->Parent=&T;
NewNode->Children.clear();
T.Children.push_back(NewNode);
locate=T.Children.size()-1;
//delete NewNode;
AddTree(*T.Children[locate],a,next,sim);
}
else{
for(int i=0;i<T.Children.size();i++)
{
if(T.Children[i]->Id==sim[a][next])
{
next++;
to=i;
T.Children[i]->Co++;
//delete NewNode;
AddTree(*T.Children[i],a,next,sim);
//break;
}
}
if(to==-1)
{
NewNode->Id=sim[a][next];
next++;
NewNode->Co=1;
NewNode->Parent=&T;
NewNode->Children.clear();
T.Children.push_back(NewNode);
locate=T.Children.size()-1;
//delete NewNode;
AddTree(*T.Children[locate],a,next,sim);
}
}
}
}
void CreateTree(TreeNode &T,vector<vector<int> > sim)
{
int i=0;
while(i<10)
{
if(AddTree(T,i,0,sim)>=sim[i].size())
{
i++;
}
//cout<<i<<endl;
}
}
第二次尝试
没办法只能去网上找找如何建FP-Tree,结果大部分都是用Python,Java实现,只找到了一篇数据挖掘作业——FP Tree算法之C++实现,不过里面出现了map、Tire树等我不会的结构,接下来打算参照该算法,然后使用我唯一会一点的vector来重新实现一遍。
占坑。