最近我一直在使用单词组合来制作不同语言的“短语”,我注意到了一些我可以通过更专业的输入做的事情。
为此定义一些常量,
深度(n
)平均为6-7
输入集的长度约为160个唯一字。
n choose k
变大快类似这个公式factorial(n) / (factorial(depth) * (factorial(n-depth)))
,这意味着输入集会迅速变大。 我的问题是这样的。
考虑到我有一个函数f(x)
,它采用组合并应用具有成本的计算,例如
func f(x) {
if query_mysql("text search query").value > 15 {
return true
}
return false
}
如何在大量组合中有效地处理和执行此功能?
奖金问题,可以同时生成组合吗?
更新:我已经知道如何按常规生成它们,更多的是让它变得高效。
答案 0 :(得分:1)
一种方法是首先根据您获得的线程数计算您可以获得多少并行度。让线程数为T
,并按如下方式拆分工作:
d
的最小数字Choose(n,d) >= T
。d
的所有组合(通常远低于深度d
,并且可在一个核心上计算)。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))
答案 1 :(得分:0)
使用众多已知算法之一生成组合。 Chase的Twiddle算法是最着名的算法之一,非常适合。它捕获数组中的状态,因此如果愿意,可以重新启动或播种。
请参阅Algorithm to return all combinations of k elements from n了解更多信息。
您可以按照自己的节奏浏览列表,使用最少的内存和无磁盘IO。与计算的1秒左右相比,生成每个组合将花费一个微小的时间。
如果您具备必要的技能,此算法(以及许多其他算法)很容易适应并行执行。