用于压缩集合尝试的算法

时间:2012-02-22 23:30:01

标签: algorithm language-agnostic compression trie

我有一组我想放在trie中的套装。

正常尝试由元素串组成 - 也就是说,元素的顺序很重要。设置缺少定义的顺序,因此可能会有更大的压缩。

例如,给定字符串"abc""bc""c",我会创建特里:

(*,3) -> ('a',1) -> ('b',1) -> ('c',1)
      -> ('b',1) -> ('c',1)
      -> ('c',1)

但是考虑到集{ 'a', 'b', 'c' }{ 'b', 'c' }{ 'c' },我可以创建上面的trie,或者其中任何一个:

(*,3) -> ('a',1) -> ('b',1) -> ('c',1)
      -> ('c',2) -> ('a',1)

(*,3) -> ('a',1) -> ('c',1) -> ('b',1)
      -> ('b',1) -> ('c',1)
      -> ('c',1)

(*,3) -> ('a',1) -> ('c',1) -> ('b',1)
      -> ('c',2) -> ('a',1)

(*,3) -> ('b',2) -> ('a',1) -> ('c',1)
                 -> ('c',1)
      -> ('c',1)

(*,3) -> ('b',1) -> ('a',1) -> ('c',1)
      -> ('c',2) -> ('b',1)

(*,3) -> ('b',2) -> ('c',2) -> ('a',1)
      -> ('c',1)

(*,3) -> ('b',1) -> ('c',1) -> ('a',1)
      -> ('c',2) -> ('b',1)

(*,3) -> ('c',2) -> ('a',1) -> ('b',1)
      -> ('b',1) -> ('c',1)

(*,3) -> ('c',2) -> ('a',1) -> ('b',1)
                 -> ('b',1)

(*,3) -> ('c',2) -> ('b',1) -> ('a',1)
      -> ('b',1) -> ('c',1)

(*,3) -> ('c',3) -> ('b',2) -> ('a',1)

因此显然有压缩空间(7个节点到4个)。

怀疑在每个节点上定义一个本地订单,取决于其孩子的相对频率会这样做,但我不确定,而且可能过于昂贵。

所以在我点击白板之前,开始破解我自己的压缩算法,是否有现有的?这有多贵?它是一个批量过程,还是可以按插入/删除进行?

3 个答案:

答案 0 :(得分:1)

我认为你应该根据项目频率对一组进行排序,这可以得到一个很好的启发式,因为你怀疑。在FP-growth(频繁模式挖掘)中使用相同的方法以紧凑的方式表示项集。

答案 1 :(得分:0)

基本上你应该构建一个依赖图。如果元素y仅在x出现时出现,则从x到y绘制一条边(如果相等,则按字典顺序排序)。结果图是DAG。现在,对此图进行拓扑排序以获得具有扭曲的元素的顺序。每当您可以选择两个(或更多元素)中的一个时,请选择出现次数较多的那个。

答案 2 :(得分:0)

我怀疑最大压缩会使最常见的元素保持在顶部(如上例所示)。

压缩算法将从整个集合集和顶部节点开始,并为包含最常见元素的每个子集递归创建节点

Compress(collection, node):
    while NOT collection.isEmpty? 
      e = collection.find_most_common_element
      c2 = collection.find_all_containing(e)
      collection = collection - c2
      if e==NIL //empty sets only
         node[END_OF_SET]=node
      else
        c2.each{set.remove(e)}
        node[e]=new Node
        Compress(c2,node[e])
      end
    end

生成的树将具有特殊的End-of-set标记,以表示完整集合在该节点处结束。对于你的例子,它将是

 *->(C,3)->(B,2)->(A,1)->EOS
                ->EOS
          ->EOS

删除集合很简单,只需删除它的EOS标记(以及任何变空的父节点)。您可以动态插入 - 在每个节点上,下降到具有最多子节点的匹配元素,直到没有匹配,然后使用上面的算法 - 但保持最大压缩将是棘手的。当元素B比元素A获得更多的孩子时,你必须移动包含A& A的所有集合。 B进入B节点,这将涉及全部搜索所有A的孩子。但是如果你不对它进行压缩,则包含搜索不再与设置的大小成线性关系。