C# Project Euler#12运行速度非常慢
我现在挣扎了大约3个小时来加快我的Euler#12项目代码。我节省了几秒钟的时间来处理数字超过130个除数的情况,我的第一个程序达到了2.33秒,现在它只需要1.169秒。然而,我从来没有耐心等待500个除数。我怎样才能固定我的密码?我试着从n和n+1中得到除数,但它只是让我的程序更慢了。。。这是我的密码C# Project Euler#12运行速度非常慢,c#,C#,我现在挣扎了大约3个小时来加快我的Euler#12项目代码。我节省了几秒钟的时间来处理数字超过130个除数的情况,我的第一个程序达到了2.33秒,现在它只需要1.169秒。然而,我从来没有耐心等待500个除数。我怎样才能固定我的密码?我试着从n和n+1中得到除数,但它只是让我的程序更慢了。。。这是我的密码 static bool isPrime(int num) { if (num % 2 == 0 && num != 2) return
static bool isPrime(int num) {
if (num % 2 == 0 && num != 2)
return false;
else
for (int i = num; i < Math.Sqrt(num) + 1; i++) {
if (num % i == 0)
return false;
}
return true;
}
static void Main(string[] args) {
Stopwatch time = new Stopwatch();
time.Start();
int trianglenumber = 0;
int divizori = 0;
for (int i = 3; i < Int32.MaxValue; i+=2) {
if (isPrime(i) != false) {
int tempnumber = 0;
tempnumber = (i * (1 + i)) / 2;
for (int k = 1; k < tempnumber + 1; k++) {
if (tempnumber % k == 0) {
divizori++;
}
}
if (500 < divizori) {
trianglenumber = tempnumber;
break;
}
divizori = 0;
}
}
time.Stop();
double timp = time.ElapsedMilliseconds ;
Console.WriteLine(trianglenumber);
Console.Write("Runtime: " + timp/1000 + " seconds");
Console.ReadKey();
}
static bool isPrime(int num){
如果(num%2==0&&num!=2)
返回false;
其他的
for(inti=num;i
你的isPrime()方法中有大减速
看一看通过素因子分解计算因子。你会发现用这种方法计算500个因子要快得多
另外,如何得到三角形数字应该简单得多
1, 3, 6, 10, 15, 21, 28, 36, 45, 55, ...
请注意每个连续的数字集之间的差异
1+2=3
3+3=6
6+4=10
10+5=15
15+6=21
等等…看看中间的数字
仅供参考,我使用素因式分解方法的版本大约需要6毫秒才能找到答案……相当快。围绕这个问题的一些Python函数。它使用,完美的 高级工具来实现这一点。希望这能帮助您找到关键的增强功能
from collections import Counter
def factors(n):
divisor=2
while divisor*divisor<=n:
if n%divisor==0:
return Counter({divisor:1})+factors(n//divisor)
divisor += 1
return Counter({n:1}) # prime number
def nbdiv(factors):
p=1
for factor in factors : p *= factors[factor]+1
return p
def nbdivtri(n):
a,b=n,n+1
if a%2==0 : a//=2
else: b//=2
return nbdiv(factors(a)+factors(b))
从集合导入计数器
def系数(n):
除数=2
除数*除数我用一个小于0.187ms的贪婪算法解决了这个问题
static void Main(string[] args)
{
// 76576500
long age = 10000;
double alpha = 1.5;
double betta = 0.1;
Random ran = new Random();
long mmm = long.MaxValue;
double RR = 0;
var a = DateTime.Now;
for (int i = 0; i < 5000; i++)
{
long N = age * (age + 1) / 2;
long count = 0;
for (int j = 2; N!=1; j++)
{
int c = 0;
while (N % j == 0)
{
N /= j;
c++;
}
count = (count + 1) * (c + 1) - 1;
}
double r = ran.Next() % 11;
r = 1 / (Math.Pow(r, alpha) + 1);
long R = (long)r + 1;
if (count >= 500)
{
alpha *= 1 + 0.001;
RR = RR * betta - (1-betta) * R;
N = age * (age + 1) / 2;
if (N < mmm)
{
mmm = N;
Console.WriteLine(mmm);
}
}
else
{
alpha *= 1 - 0.001;
RR = RR * betta + (1 - betta) * R;
}
age += (long)RR;
}
var b = DateTime.Now - a;
Console.WriteLine("R=" + mmm + " " + b);
string sss = Console.ReadLine();
}
static void Main(字符串[]args)
{
// 76576500
长寿=10000岁;
双α=1.5;
双贝塔=0.1;
Random ran=新的Random();
long mmm=long.MaxValue;
双RR=0;
var a=DateTime.Now;
对于(int i=0;i<5000;i++)
{
长N=年龄*(年龄+1)/2;
长计数=0;
对于(int j=2;N!=1;j++)
{
int c=0;
而(N%j==0)
{
N/=j;
C++;
}
计数=(计数+1)*(c+1)-1;
}
double r=ran.Next()%11;
r=1/(数学功率(r,α)+1);
长R=(长)R+1;
如果(计数>=500)
{
α*=1+0.001;
RR=RR*贝塔-(1-贝塔)*R;
N=年龄*(年龄+1)/2;
如果(N
行:if(isPrime(i)!=false)
,这简化为if(isPrime(i))
,这当然意味着没有任何除数?也许你可以使用一些存储的动态计算素数筛来代替对每个数重复相同的计算?我想你可以更改(inti=1;i
tofor(inti=3;i
跳过所有偶数(仍需注意2是素数)。您可以使用isPrime()方法严重损坏,无法返回正确的答案。请编写一个单元测试来验证其操作。@Velox,从逻辑上讲,该方法接受每个素数,这意味着它有2个除数,但我的工作与该方法配合得很好()