生成素数是我经常尝试的玩具问题,尤其是在尝试使用新的编程语言,平台或风格时。
我正在考虑尝试使用Hadoop(Map Reduce)编写素数生成算法或素数测试算法。
我想我会发布这个问题,以获得提示,参考,算法,方法。
虽然我的主要兴趣是基于Map Reduce的算法,但我不介意查看新的Hadoop编程模型,或者例如查看使用PiCloud
我在Prime数字生成方面似乎有一些有趣的问题:here,here和here,但没有任何与Parallel方法相关的问题引起了我的注意。
提前致谢。
答案 0 :(得分:12)
这是基于映射和缩减(an algorithm)构建的folding。它表达sieve of Eratosthenes
P = {3,5,7,...} \ U {{ p 2 ,p 2 + 2p,p 2 + 4p, ...} | P }
中的 p对于奇数素数(即没有2)。折叠树无限深化,如下所示:
其中每个素数标记该素数的奇数倍的流,例如对于 7 : 49,49 + 14,49 + 28, ...,它们都被合并以获取所有复合数字,然后 primes 在复合数字之间的间隙中找到。它位于Haskell中,因此时间由惰性评估机制隐式处理(以及算法调整,其中每个比较节点始终通过左侧的第一个号码而不需要数字从右边开始,因为无论如何它都保证更大)。
可以使用赔率代替奇数素数作为多次生成的种子,以简化事情(具有明显的性能影响)。
这项工作当然可以分为连续素数的正方形之间的片段。 Haskell代码如下,但我们可以将它视为可执行的伪代码(其中:
是列表节点惰性构造函数,函数调用f(x)
写成f x
,括号是仅用于分组):
primes = 2 : g []
where
g ps = 3 : minus [5,7..] (_U [[p*p, p*p+2*p..] | p <- g ps])
_U ((x:xs):t) = x : union xs (_U (pairs t))
pairs ((x:xs):ys:t) = (x : union xs ys) : pairs t
union (x:xs) (y:ys) = case compare x y of
LT -> x : union xs (y:ys)
EQ -> x : union xs ys
GT -> y : union (x:xs) ys
minus (x:xs) (y:ys) = case compare x y of
LT -> x : minus xs (y:ys)
EQ -> minus xs ys
GT -> minus (x:xs) ys
讨论是here。更复杂,更懒惰的调度是here。另外this SO answer显示了(相关的)Haskell代码在生成器方面的近似转换; Python中的this one。