Algorithm Eratosthenes的真筛——素数生成算法
今天我读了一篇论文: O'Neill,Melissa E.,《自然科学杂志》 函数式编程,已出版 剑桥大学出版社在线 2008年10月9日 内政部:10.1017/S0956796808007004 描述了一种利用优先级队列生成素数的算法:Algorithm Eratosthenes的真筛——素数生成算法,algorithm,haskell,Algorithm,Haskell,今天我读了一篇论文: O'Neill,Melissa E.,《自然科学杂志》 函数式编程,已出版 剑桥大学出版社在线 2008年10月9日 内政部:10.1017/S0956796808007004 描述了一种利用优先级队列生成素数的算法: sieve [] = [] sieve (x:xs) = x : sieve' xs (insertprime x xs PQ.empty) where insertprime p xs table = PQ.insert (p*p)
sieve [] = []
sieve (x:xs) = x : sieve' xs (insertprime x xs PQ.empty)
where
insertprime p xs table = PQ.insert (p*p) (map (* p) xs) table
sieve' [] table = []
sieve' (x:xs) table
| nextComposite <= x = sieve' xs (adjust table)
| otherwise = x : sieve' xs (insertprime x xs table)
where
nextComposite = PQ.minKey table
adjust table
| n <= x = adjust (PQ.deleteMinAndInsert n' ns table)
| otherwise = table
where
(n, n':ns) = PQ.minKeyValue table
primes = sieve [2 .. ]
sieve[]=[]
筛子(x:xs)=x:sieve'xs(插入素数x xs PQ.empty)
哪里
insertprime p xs table=PQ.insert(p*p)(map(*p)xs)table
筛'[]表=[]
筛(x:xs)表
|nextComposite这篇文章是关于正在使用的优先级队列的:
考虑到这些需求,需要一个优先级队列
是一个很有吸引力的选择,特别是因为此数据结构本身支持多个
具有相同优先级的项目(按任意顺序排队)
由于重复条目在算法中并不真正有用,因此必须对其进行特殊处理
删除最小组合的adjust
函数不断调整优先级队列,直到可以确保删除最小元素的所有重复项:
adjust table
| n <= x = adjust (PQ.deleteMinAndInsert n_ ns table)
| otherwise = table
where ...
调整表
|顺便说一句,这是一篇非常漂亮的论文。世界需要更多这样的东西。这很有趣。作者花了很大的篇幅来说明为什么一个算法不是埃拉托斯尼的真正筛子,然后又产生了另一个不是的算法。有很多关于数据结构的胡言乱语,而实际上是“正确的”“实现使用一个简单的数组。实际算法的输出就是这个数组——一个简单的表,所有的合成都被划掉了。任何其他数据结构都可能有一些优点,人们可能会称之为“改进的埃拉托什尼筛子”之类的东西,但这不是真正的交易。@phkahler:使用优先级队列的唯一“优点”是它可以在Haskell中表达一个合理有效的解决方案。通过在任何命令式语言中使用可扩展数组,您都可以轻松恢复可扩展性的好处,如F#所做的: