【问题标题】:Combinations (n choose k) parallelisation and efficiency组合(n 选择 k)并行化和效率
【发布时间】:2014-02-10 09:17:39
【问题描述】:

最近我一直在使用单词组合来制作不同语言的“短语”,我注意到一些事情我可以通过更多专家的意见来做。

为此定义一些常量,

深度 (n) 平均为 6-7

输入集的长度约为 160 个唯一词。

  1. 内存 - 生成 160 个单词的 n 个排列会浪费大量空间。我可以通过将数据库写入磁盘来滥用数据库,但是由于我需要不断地等待 IO,因此我的性能受到了影响。另一个技巧是像生成器对象一样动态生成组合
  2. 时间 - 如果我没记错 n choose k 变大 fast 类似这个公式 factorial(n) / (factorial(depth) * (factorial(n-depth))) 这意味着输入集很快就会变大。

我的问题是这样的。

考虑到我有一个函数f(x),它采用组合并应用具有成本的计算,例如

func f(x) {
    if query_mysql("text search query").value > 15 {
        return true
    }
    return false 
}

如何在大量组合上有效地处理和执行此函数?

额外问题,可以同时生成组合吗?

更新:我已经知道如何以常规方式生成它们,更多的是提高效率。

【问题讨论】:

  • 在计算过程中“深度”是否保持不变。因此,对于算法的一次运行,您的输出是来自 160 长度输入的所有 depth=6 单词组合或 [1,6] 范围内的所有单词组合?
  • @MattiLyra 理想情况下,我希望深度从 [n..2] 开始,但现在让我专注于一个,为了清晰起见删除了行
  • 好吧,这将为您提供一种并行化组合的方法,并行运行每个 n=3, n=4 ... n=n,因为它们不相互依赖。
  • @MattiLyra 如果一组组合的结果总是在 enxt 中,可能会浪费计算
  • 我不知道是谁投票结束了这个问题。这个问题对 SO 来说非常好。

标签: performance algorithm math combinations


【解决方案1】:

一种方法是首先根据您拥有的线程数计算您可以获得多少并行度。设线程数为T,分工如下:

  • 根据某些总排序对元素进行排序。
  • 找到最小的数字d,使得Choose(n,d) >= T
  • 找到“深度”的所有组合(精确)d(通常远低于深度d,并且可在一个核心上计算)。
  • 现在,将工作分散到您的 T 核上,每个核都有一组“前缀”(每个前缀 c 是大小 d 的组合),对于每种情况,找到它们“最小”的所有后缀' 根据总排序,元素比max(c)“大”。

这种方法也可以很好地转化为map-reduce 范式。

map(words): //one mapper
   sort(words) //by some total ordering function
   generate all combiations of depth `d` exactly // NOT K!!!
   for each combination c produced:
       idx <- index in words of max(c) 
       emit(c,words[idx+1:end])
reduce(c1, words): //T reducers
   combinations <- generate all combinations of size k-d from words
   for each c2 in combinations:
      c <- concat(c1,c2)
      emit(c,f(c))

【讨论】:

    【解决方案2】:

    使用众多已知算法中的一种来生成组合。 Chase 的 Twiddle 算法是最著名且非常合适的算法之一。它在数组中捕获状态,因此可以根据需要重新启动或播种。

    请参阅Algorithm to return all combinations of k elements from n 了解更多信息。

    您可以按照自己的节奏浏览列表,使用最少的内存和无磁盘 IO。与您的 1 秒左右的计算相比,生成每个组合将花费微不足道的时间。

    如果您具备必要的技能,此算法(以及许多其他算法)很容易适应并行执行。

    【讨论】:

    • 这丝毫没有回答问题。
    • 那你应该问更好的问题。如果您想要一个解释如何使用 map reduce 或 Hadoop 的答案,那么请说出来。
    • 如果你学会阅读,我说我已经知道如何生成组合,我在将状态存储在数组中时也会耗尽内存。
    • 如果检查算法,需要的状态是 N+2 个整数。由于分配 162 个整数的内存不能用完,我必须假设您使用了错误的算法。有了正确的算法,剩下的就很容易了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多