Optimization 类型球拍的优化。。。这是不是太过分了?
关于打字/拍子的问题。我目前正在努力学习如何更好地学习球拍。有些是非常缓慢的,特别是在处理素数和因子时。所以对于一些问题,我试着制作一个打字版/拍子版,但我发现速度没有提高,恰恰相反。(我试图通过使用非常大的数字来最小化开销的影响,计算时间大约为10秒。) 我从Racket文档中知道最好的优化会发生。所以是的,我试着把处理整数的问题写成浮点形式。例如,使用整数和人工将整数变为浮点数。我必须使用技巧:检查两个数字之间的相等实际上意味着检查它们是否“足够接近”,就像在这个函数中检查x是否可以除以y:Optimization 类型球拍的优化。。。这是不是太过分了?,optimization,integer,racket,typed-racket,Optimization,Integer,Racket,Typed Racket,关于打字/拍子的问题。我目前正在努力学习如何更好地学习球拍。有些是非常缓慢的,特别是在处理素数和因子时。所以对于一些问题,我试着制作一个打字版/拍子版,但我发现速度没有提高,恰恰相反。(我试图通过使用非常大的数字来最小化开销的影响,计算时间大约为10秒。) 我从Racket文档中知道最好的优化会发生。所以是的,我试着把处理整数的问题写成浮点形式。例如,使用整数和人工将整数变为浮点数。我必须使用技巧:检查两个数字之间的相等实际上意味着检查它们是否“足够接近”,就像在这个函数中检查x是否可以除以y:
(: divide? (-> Flonum Flonum Boolean))
(define (divide? x y)
(let ([r (/ x y)])
(< (- r (floor r)) 1e-6)))
(:除?(>Flonum-Flonum-Boolean))
(定义(除以?x y)
(让([r(/x y)])
(<(-r(楼层r))1e-6)
它工作(嗯…解决方案是正确的),我有30%-40%的速度提高
这是否可以接受?人们在现实生活中真的这么做了吗?如果不是,那么在使用整数时,优化类型化解决方案的最佳方法是什么?或者,在处理整数时,是否应该完全放弃类型化/racket,而保留用于浮点计算的问题?在大多数情况下,解决方案是使用更好的算法,而不是转换为类型化racket 由于Project Euler中的大多数问题都与整数有关,以下是一些提示和技巧:
/
需要计算分母和分子之间的最大公除法,以抵消公因数。如果您只想知道一个数字是否除以另一个数字,那么这就使得/
成为一个错误的选择。使用(=(余数n m)0)
检查m
是否除以n
。另外:当您知道除法的余数为零时,请使用商
比/
随机数a=m^2-n^2
,b=2mn
,以及c=m^2+n^2
。这将比在a、b和c上循环快,跳过a^2+b^2=c^2不正确的三元组数学/数论
的源代码中寻找技巧和窍门我不想成为一个真正的答案,因为我不能提供任何一般性的提示,苏加德还没有发布,但因为我最近做了“友好的数字” “问题21”,我想还是把我的解决方案留在这里吧(遗憾的是,在Euler上发布的Lisp解决方案不多…)
当处理除数时,通常可以停在n的平方根处,就像这里的
divSum
一样。当你找到一对友好的组合时,你也可以同时将这两个组合加到和中,这样你就不用在我的代码中计算(divSum b)
。注意:对于平方根,请考虑使用整数sqrt
而不是sqrt
。
(define (divSum n)
(define (aux i sum)
(if (> (sqr i) n)
(if (= (sqr (sub1 i)) n) ; final check if n is a perfect square
(- sum (sub1 i))
sum)
(aux (add1 i) (if (= (modulo n i) 0)
(+ sum i (/ n i))
sum))))
(aux 2 1))
(define (amicableSum n)
(define (aux a sum)
(if (>= a n)
sum
(let ([b (divSum a)])
(aux (add1 a)
(if (and (> b a) (= (divSum b) a))
(+ sum a b)
sum)))))
(aux 2 0))
> (time (amicableSum 10000))
cpu time: 47 real time: 46 gc time: 0