我为我的算法生成了一组相当大的数组排列:
argeArray.permutation(permSize) do |perm|
# Do something with perm
end
现在我正在努力更新应用程序,以便能够在停止的索引处继续。
经过一番调查后,我没有找到具有起始索引的permutation
替代方法(能够跳过0..startIndex
)。
接下来,我发现drop()
method能够切断排列枚举器中的第一个元素数量:
startIndex = 3000000000 # skip first 3 billion combinations
argeArray.permutation(permSize).drop(startIndex) do |perm|
# Do something with perm
end
但实验表明,这会创建完整的组合,但由于需要 lot 和 lot 的内存,因此效率不高。 ..即使它只需要跳过前30亿个组合......
另一种解决方案是跳过算法,直到达到startIndex
:
startIndex = 3000000000 # skip first 3 billion combinations
argeArray.permutation(permSize).with_index() do |perm, index|
next if index < startIndex # Skip until startIndex is reached
# Do something with perm
end
缺点是在算法(最终)开始工作之前测试了30亿个组合(并浪费地检查是否达到startIndex
)
这个问题还有其他(更有效的)解决方案吗?以某种方式能够告诉permutation()
跳过初始数量的组合? (假设它总是使用相同的顺序)
答案 0 :(得分:1)
Ruby 2.0引入了Enumerator::Lazy
。也许调查可能对你有所帮助。
module Enumerable
def filter_map(&block)
map(&block).compact
end
end
class Enumerator::Lazy
def filter_map
Lazy.new(self) do |yielder, *values|
result = yield *values
yielder << result if result
end
end
end
(1..Float::INFINITY).lazy.filter_map{|i| i*i if i.even?}.first(5)
# => [4, 16, 36, 64, 100]
您可以将您的排列设置为Enumerator::Lazy
的实例,并使用drop
跳转到某个位置。