【问题标题】:Subset counting algorithm子集计数算法
【发布时间】:2011-08-14 11:43:09
【问题描述】:

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

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

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

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

谢谢。

【问题讨论】:

  • 不,这是一个非常重要的问题。但是,似乎没有经过深思熟虑。求解 {Pass, Fail} 值的单个向量然后扩展到这些值的集合可能更容易;这是扩展部分的表述不当。
  • 对我来说问题描述很清楚:)。
  • Sergey - 对架构有什么要求吗?我觉得解决单个 cpu 的问题可能与 GPGPU 解决方案不同。
  • @templatetypedef 哇!感谢您重新格式化问题。难以置信!!!

标签: algorithm set tuples


【解决方案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} 并根据输入的大小从四个实现中选择一个。

【讨论】:

    【解决方案2】:

    制作一个整数的 k 向量,描述每个索引有多少遍。循环遍历你的集合,每个元素增加通道的 k 向量。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-14
      • 1970-01-01
      • 2013-01-26
      • 1970-01-01
      • 2011-06-02
      • 1970-01-01
      • 2013-09-27
      • 1970-01-01
      相关资源
      最近更新 更多