锁定老帖子 主题:教你用Ruby算命!
精华帖 (0) :: 良好帖 (1) :: 新手帖 (0) :: 隐藏帖 (3)
|
|
---|---|
作者 | 正文 |
发表时间:2009-04-09
最后修改:2009-04-09
CharlesCui 写道 ray_linn 写道 CharlesCui 写道 看我主贴那个图片,
编号#前面如果有星号*,说明它和上下一个N之间可能存在一个梅森数,这说明发现带星号的梅森数的家伙是跳着计算的。 如果你那个真的很快,你试试在*星号的两个N之间计算一下,找到一个可以和基金会要钱的!你就出名了。 内存花费到1.8G后会报内存不足,这个基本和我预期一样。一个32bit Windows Application大概可用内存只有1.5-1.8G左右,明天改成用64bit的机器算。 我先把双线程取消掉来释放更多的内存。 你现在内存多大啊?系统是xp的? 问题不是内存,是递归太消耗栈空间。因此基本用什么都是一样的。改改算法才能算。 ps: 不管你内存多大,在32bit操作系统(linux,windows或者mac)只能寻址到4GB,其中这4GB一定有一部分被操纵系统保留,linux程序实际只有2GB内存,windows更改配置可以到2.5GB。 拿掉PLINQ之后,CPU的区别还是很大的。 |
|
返回顶楼 | |
发表时间:2009-04-09
我刚测试了一下。
1M stack大概可以支持住20000层的递归,10M stack可以支持得住80000层的递归。 class App { private static long _Depth = 0; private static void GoDeep() { if ((++_Depth % 10000) == 0) System.Console.WriteLine("Depth is " + _Depth.ToString()); GoDeep(); return; } public static void Main() { try { GoDeep(); } finally { } return } } |
|
返回顶楼 | |
发表时间:2009-04-09
等你计算的时候,你把你要计算的那个区间所用到的最大递归数打印出来看看啊,看看那个深度需要多少次递归,这样就可以知道要消耗多少内存了。
|
|
返回顶楼 | |
发表时间:2009-04-09
最后修改:2009-04-09
CharlesCui 写道 等你计算的时候,你把你要计算的那个区间所用到的最大递归数打印出来看看啊,看看那个深度需要多少次递归,这样就可以知道要消耗多少内存了。
你不可能无限制增大stack的,这是算法的问题,不是程序的问题。必须改掉递归,否则用哪一种程序都无法搞定的。 层数也很好算,每层才减少1,算到m33的位置859433,就有859432层的递归调用 |
|
返回顶楼 | |
发表时间:2009-04-09
最后修改:2009-04-09
CharlesCui 写道 M(1279)没问题啊,你看我之前写的,已经算出来了,M(1279)下一个就有问题了,你算算。
在我的超级老爷本上跑了老半天(真的是老半天!)之后。。。。。 终于艰难地吐出了M(4423),再继续就是stack level too deep (SystemStackError)。。。 不过我觉得咱也够无聊的,拿Ruby算这个。。 |
|
返回顶楼 | |
发表时间:2009-04-09
ray_linn 写道 CharlesCui 写道 等你计算的时候,你把你要计算的那个区间所用到的最大递归数打印出来看看啊,看看那个深度需要多少次递归,这样就可以知道要消耗多少内存了。
你不可能无限制增大stack的,这是算法的问题,不是程序的问题。必须改掉递归,否则用哪一种程序都无法搞定的。 呵呵,跑半个小时,haskell 占用内存稳定在 3M 以下。pure 函数的优化能力太强悍了。 |
|
返回顶楼 | |
发表时间:2009-04-09
night_stalker 写道 ray_linn 写道 CharlesCui 写道 等你计算的时候,你把你要计算的那个区间所用到的最大递归数打印出来看看啊,看看那个深度需要多少次递归,这样就可以知道要消耗多少内存了。
你不可能无限制增大stack的,这是算法的问题,不是程序的问题。必须改掉递归,否则用哪一种程序都无法搞定的。 呵呵,跑半个小时,haskell 占用内存稳定在 3M 以下。pure 函数的优化能力太强悍了。 你弄错了吧? 你算的是什么? 我算的是20996011到20996015....这个区间。 |
|
返回顶楼 | |
发表时间:2009-04-09
最后修改:2009-04-10
ray_linn 写道 你弄错了吧? 你算的是什么? 我算的是20996011到20996015....这个区间。 我算的是 [1..] ,我按ctrl+c两次才会停 有点弄错了,继续算…… 只有20996011 有机会,果然也吃了很大的栈空间,指定了700M的栈似乎不太够…… |
|
返回顶楼 | |
发表时间:2009-04-10
最后修改:2009-04-10
night_stalker 写道 ray_linn 写道 你弄错了吧? 你算的是什么? 我算的是20996011到20996015....这个区间。 我算的是 [1..] ,我按ctrl+c两次才会停 有点弄错了,继续算…… 我的问题不是bigint容量不够~而是你给的算法的递归导致了stack overflow了,如何改成尾递归??这俺不想去弄明白。。。。 我开了双线程,stack怎么改也不够。 |
|
返回顶楼 | |
发表时间:2009-04-10
ray_linn 写道 night_stalker 写道 ray_linn 写道 你弄错了吧? 你算的是什么? 我算的是20996011到20996015....这个区间。 我算的是 [1..] ,我按ctrl+c两次才会停 有点弄错了,继续算…… 我的问题不是bigint容量不够~而是你给的算法的递归导致了stack overflow了,如何改成尾递归??这俺不想去弄明白。。。。 我开了双线程,stack怎么改也不够。 尾递归是吧,看这个ruby版的两个算法: 开始版本: def lucasLehmer_sequence(n) n>=0?(n==0?4:lucasLehmer_sequence(n-1)**2-2):(raise ArgumentError,"lucasLehmer seq must larger than 0.") end def lucasLehmer_test(n) lucasLehmer_sequence(n-2)%mersenne(n)==0 end 修改后版本: def lucasLehmer_sequence n, m raise(ArgumentError, "lucasLehmer seq must larger than 0.") if n < 0 (n == 0 ? 4 : (lucasLehmer_sequence(n - 1, m) ** 2 - 2)) % m # 注意这里 end def lucasLehmer_test n m = mersenne n lucasLehmer_sequence(n - 2, m) == 0 end 这个修改后的版本就是尾递归了吧?修改了mersenne(n)变成了m = mersenne n ,然后把值传给lucasLehmer_sequence计算,而不是传函数。直接用变量保存计算结果,而不需要用函数。这算么? |
|
返回顶楼 | |