【发布时间】:2011-03-23 21:17:41
【问题描述】:
我再次从 Project Euler 挑战中获得乐趣,我注意到我的 12 号解决方案是我最慢的解决方案之一,每次运行时 ~593.275 ms。这是我在~1254.593 ms 每次运行时的第 10 号解决方案的第二个解决方案。我的所有其他答案在3 ms 下运行的时间都少于1 ms。
Problem 12 的我的 Java 解决方案:
main():
int index = 1;
long currTriangleNum = 1;
while (numDivisors(currTriangleNum) <= 500) {
index++;
currTriangleNum += index;
}
System.out.println(currTriangleNum);
numDivisors():
public static int numDivisors(long num) {
int numTotal = 0;
if (num > 1)
if (num % 2 == 0) {
for (long i = 1; i * i <= num; i++)
if (num % i == 0)
numTotal+=2;
} else {
// halves the time for odd numbers
for (long i = 1; i * i <= num; i+=2)
if (num % i == 0)
numTotal+=2;
}
else if (num == 0)
return 0;
else if (num == 1)
return 1;
else (num < 0)
return numDivisors(num *= -1);
return numTotal;
}
.
翻遍解决方案论坛,有人发现these formulas(n = (p^a)(q^b)(r^c)... & d(n) = (a+1)(b +1)(c+1)...) 为他们工作,但我个人不认为它会更快;手动速度可能更快,但不是在程序中。
.
基本思路如下:
我们要计算48中的除数个数。通过查看下面的因子树,我们可以得出结论48 = (2^4)(3^1) [n = (p^a)(q^b)(r^c)... ].
48
/ \
2 24
/ \
2 12
/ \
2 06
/ \
2 3
知道了这一点,我们构造公式d(48) = (4+1)(1+1) [d(n) = (a+1)(b+1)(c+1)...] 来确定 48 有 10 个因数。
d(n) = (a+1)(b+1)(c+1)...
d(48) = (4+1)(1+1)
d(48) = (5)(2)
d(48) = 10
.
如何优化我的代码?这些公式是最好的解决方案吗?我觉得找到所有主要因素,然后实施公式会比我已有的程序花费更长的时间。
非常感谢,
贾斯蒂安
编辑:
在任何人开始发布链接之前,我已经在 SO 中查看了类似的问题,但没有任何运气 - 我只是想不出他们的方法的实现会比我已有的方法运行得更快。
EDIT2:
我在 Eratosthenes 筛上的第二次尝试(针对第 10 题):
int p = 3, n = 2000000;
long total = 0;
boolean[] sieve = new boolean[n];
for (int i = 3; i < n; i += 2)
sieve[i] = true;
sieve[2] = true;
while (p * p < n) {
for (int i = p; i < n; i++)
if (sieve[i] && (i % p) == 0)
sieve[i] = false;
p++;
while (!sieve[p])
p++;
}
for (int i = 0; i < n; i++)
if (sieve[i])
total += i;
System.out.println(total);
在~985.399 ms 运行 - 没有比其他方法快太多,但尚未优化。但是,它可以工作。
【问题讨论】:
-
我想我帮不上什么忙……我天真的、蛮力的 PowerShell 解决方案几乎打破了一个小时! :) 虽然这是在 PowerShell v1 中运行的,其中函数调用非常慢。
-
stackoverflow.com/questions/571488/project-euler-12-in-python/…(在 Python 中为 60 毫秒)
-
埃拉托色尼筛算法不应使用除法。见rosettacode.org/wiki/Sieve_of_Eratosthenes#Java
-
@J.F. Sebastian:我尝试过这种方法,但结果证明它与我在埃拉托色尼筛法的第一次失败尝试太相似了。我没有等到它,但我估计它需要 10 分钟,有 2000000 个值,考虑到通过 LinkedList 运行了多少次,这是有道理的。
标签: java optimization primes mathematical-optimization