论坛首页 编程语言技术论坛

教你用Ruby算命!

浏览 14022 次
精华帖 (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的区别还是很大的。


  • 大小: 50.3 KB
0 请登录后投票
   发表时间: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
}
}
0 请登录后投票
   发表时间:2009-04-09  
等你计算的时候,你把你要计算的那个区间所用到的最大递归数打印出来看看啊,看看那个深度需要多少次递归,这样就可以知道要消耗多少内存了。
0 请登录后投票
   发表时间:2009-04-09   最后修改:2009-04-09
CharlesCui 写道
等你计算的时候,你把你要计算的那个区间所用到的最大递归数打印出来看看啊,看看那个深度需要多少次递归,这样就可以知道要消耗多少内存了。


你不可能无限制增大stack的,这是算法的问题,不是程序的问题。必须改掉递归,否则用哪一种程序都无法搞定的。

层数也很好算,每层才减少1,算到m33的位置859433,就有859432层的递归调用
0 请登录后投票
   发表时间:2009-04-09   最后修改:2009-04-09
CharlesCui 写道
M(1279)没问题啊,你看我之前写的,已经算出来了,M(1279)下一个就有问题了,你算算。


在我的超级老爷本上跑了老半天(真的是老半天!)之后。。。。。

终于艰难地吐出了M(4423),再继续就是stack level too deep (SystemStackError)。。。


不过我觉得咱也够无聊的,拿Ruby算这个。。
0 请登录后投票
   发表时间:2009-04-09  
ray_linn 写道
CharlesCui 写道
等你计算的时候,你把你要计算的那个区间所用到的最大递归数打印出来看看啊,看看那个深度需要多少次递归,这样就可以知道要消耗多少内存了。


你不可能无限制增大stack的,这是算法的问题,不是程序的问题。必须改掉递归,否则用哪一种程序都无法搞定的。


呵呵,跑半个小时,haskell 占用内存稳定在 3M 以下。pure 函数的优化能力太强悍了。
0 请登录后投票
   发表时间:2009-04-09  
night_stalker 写道
ray_linn 写道
CharlesCui 写道
等你计算的时候,你把你要计算的那个区间所用到的最大递归数打印出来看看啊,看看那个深度需要多少次递归,这样就可以知道要消耗多少内存了。


你不可能无限制增大stack的,这是算法的问题,不是程序的问题。必须改掉递归,否则用哪一种程序都无法搞定的。


呵呵,跑半个小时,haskell 占用内存稳定在 3M 以下。pure 函数的优化能力太强悍了。


你弄错了吧? 你算的是什么? 我算的是20996011到20996015....这个区间。
0 请登录后投票
   发表时间:2009-04-09   最后修改:2009-04-10
ray_linn 写道


你弄错了吧? 你算的是什么? 我算的是20996011到20996015....这个区间。


我算的是 [1..] ,我按ctrl+c两次才会停

有点弄错了,继续算……

只有20996011 有机会,果然也吃了很大的栈空间,指定了700M的栈似乎不太够……

0 请登录后投票
   发表时间:2009-04-10   最后修改:2009-04-10
night_stalker 写道
ray_linn 写道


你弄错了吧? 你算的是什么? 我算的是20996011到20996015....这个区间。


我算的是 [1..] ,我按ctrl+c两次才会停

有点弄错了,继续算……




我的问题不是bigint容量不够~而是你给的算法的递归导致了stack overflow了,如何改成尾递归??这俺不想去弄明白。。。。

我开了双线程,stack怎么改也不够。
0 请登录后投票
   发表时间: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计算,而不是传函数。直接用变量保存计算结果,而不需要用函数。这算么?
0 请登录后投票
论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics