我一直在试图编写计算效率高的项目。考虑问题1:http://projecteuler.net/problem=1。我将范围从1000增加到了10,000,000,以突出低效率。在R中更快的模或平等检查(或矢量化的好方法)
这是我的解决方案:
system.time({
x <- 1:1E7
a <- sum(as.numeric(x[x%%3 ==0 | x%%5==0]))
})
user system elapsed
0.980 0.041 1.011
下面是一个朋友做同样的事情,写了一些C++代码。
#include <iostream>
using namespace std;
int main(int argc, char** argv)
{
long x = 0;
for (int i = 1; i < 10000000; i++)
{
if (i % 3 == 0)
x += i;
else if (i % 5 == 0)
x += i;
}
cout << x;
return 0;
}
cbaden$ time ./a.out
23333331666668
real 0m0.044s
user 0m0.042s
sys 0m0.001s
我知道C++应该是除了R快,但这更快? Rprof表示我用模运算符将近60%的时间花费在模运算符上,13%的时间用“==”运算。有没有更快的矢量化方法?
次要的问题是我将耗尽内存 - 随着范围变大,此方法的可扩展性不高。有没有一种好方法可以保持矢量化,但不会试图将子集保留在内存中?
哇,真是太疯狂了!我无法真正理解它在做什么。 n(n + 1)/ 2将是从1到n的总和,但我想我不明白为什么这会起作用。 – 2012-07-24 05:46:02
它可能无法帮助模,但是一个奇妙的优雅的解决方案! – mnel 2012-07-24 06:02:06
a是可以被3整除的值的数量,并且假设我们做出一系列(1,2,3,...,a)。乘以3得到(3,6,9,...,1E9),数字可以被3整除。使用这个捷径公式sum_ {i = 1}^ai = a(a + 1)/ 2只需要我们知道一个,而不是整个阵列。将所有可以被3整除的矢量1,...,a整除,将整个事物乘以3.对于5和15,同样的逻辑,但是我们减去15-可分的向量以避免重复计算。 即使在非常大的范围内,我的电脑也能立即运行。美丽。 – 2012-07-24 06:17:08