子集计数算法

时间:2011-08-14 11:43:09

标签: algorithm set tuples

我有一个我想要有效解决的问题。我得到了一组布尔值的k元组,我事先知道每个k元组中每个值的一部分是真的。例如,我可能有以下4元组,其中每个元组至少有60%的布尔值设置为true:

(1, 0, 1, 0)
(1, 1, 0, 1)
(0, 0, 1, 0)

我感兴趣的是找到具有特定属性的索引集:如果我在指示的索引处查看元组中的每个值,那么至少这些元组的给定部分具有相应的位集。例如,在上面的4元组中,我可以考虑集合{0},因为如果你看一下上面每个元组的第0个元素,其中三分之二是1,而2 / 3~ = 66%> 60%。出于同样的原因,我也可以考虑集合{2}。但是,我不能考虑{1},因为在索引1中,只有三分之一的元组有1和1/3小于60%。类似地,我不能使用{0,2}作为集合,因为至少有60%的元组都设置了0和2位。

我的目标是找到此属性所包含的所有集合。有没有人有一个很好的算法来解决这个问题?

谢谢。

2 个答案:

答案 0 :(得分:1)

制作一个整数的k向量,描述每个索引的传递次数。循环遍历你的集合,为每个元素递增传递的k向量。

然后找出你的集合的基数(在一个单独的循环中,或在上面的循环中)。然后循环遍历计数向量,并根据您的标准发出通过/失败向量。

答案 1 :(得分:1)

正如您所写,可以假设架构是x86_64并且您正在寻找实现性能,导致渐近复杂性(因为它不会在线性下 - 根据问题的定义;)),我建议如下算法( C ++,如伪代码):

/* N=16 -> int16; N=8 -> int8 etc. Select N according to input sizes. (maybe N=24 ;) ) */
count_occurences_intN(vector<intN> t, vector<long> &result_counters){
   intN counters[2^N]={};
   //first, count bit combinations
   for_each(v in t)
       ++counters[v];
   //second, count bit occurrences, using aggregated data 
   for(column=0; column<N; ++column){
      mask = 1 << column;
      long *result_counter_ptr = &(result_counters[column]);
      for(v=0; v<2^16; ++v)
         if( v & mask )
            ++(*result_counter_ptr);
   }
}

然后,将输入的k位向量分成N位向量,并应用上述函数。

根据输入的大小,您可以提高性能,您可以选择N = 8,N = 16,N = 24或应用天真的方法。

正如你所写,你不能在客户端假设任何东西,只需实现N = {8,16,24}和天真,并根据输入的大小从四个实现中选择一个。