最近在学FP树,学了之后就有一个疑惑,发现以下一个性质
- 一个点的父亲肯定计数不小于他的儿子
然后就错误的感觉最后的结果是包含根的一颗树,并且所有的顶点的计数都 ≥ \ge ≥最小支持度计数,那么也就只需要不断地往上删掉叶子,并且同时清除叶子对祖先的贡献(到一个叶子必定会经过祖先,贡献就是叶子的计数),最后就可以得到答案,复杂度是 O ( 节 点 数 ) O(节点数) O(节点数)的。
开始还以为自己十分正确,为什么它还要每个项单独做,还要递归那么麻烦。看来搞ACM给我带来了不少蜜汁自信。网上百度也没有百度到正面回答,所以我就写一下,也许会有跟我一样的人吧。
最简单的先举一个反例,如果有两个I5,位于不同的叶子结点,最小支持度计数是2,如果按照上述做法删除叶子节点,I5可能就不会出现在结果里面,同理,这样会漏掉很多FP。换言之,最后结果并不是包含根的一颗树。(如果你跟我这个想法一样,你可能还会觉得最后FP树是单个路径的时候,所谓的“每个组合”必须要是到根的一条路径,这个也是不对的,因为实际上每个事务是一个集合,并没有先后关系)
那么算法里面每个项单独进行是什么意思呢?其实是从第一项开始,逐渐构建FP,递归操作,其实就是在已经有的项上(可以想象为一个虚拟集合),往后继续加项。比如说从I5开始构建新FP树(此时虚拟集合只有I5),递归下去,又对I3构建新FP树(此时虚拟集合有I5,I3)这样就能逐渐构造出所有的FP。
不过说实话,这个看起来是真的难写。