问题的方法:哥德巴赫问题是这样一个陈述:任何以4开头的偶数都可以表示为两个质数之和。即6 = 3 + 3; 8 = 5 + 3 ...据我了解,解决问题的方法就是证明或驳斥这一说法。
我们需要做的第一件事是实现一种检查数字是否为质数的方法。质数是只能被其自身和一个整数整除的数字。
public static bool IsPrimeNumber(ulong n)
{
var result = true;
if (n > 1)
{
for (ulong i = 2; i < n; i++)
{
if (n % i == 0)
{
result = false;
break;
}
}
}
else
{
result = false;
}
return result;
}
现在我们需要收集直到ulong.MaxValue = 18446744073709551615(2 ^ 64-1)的所有素数的集合
public static IEnumerable<ulong> GetAllPrimeNumbers(ulong maxNumber)
{
List<ulong> primeNumbers = new List<ulong>();
for (ulong i=0; i < maxNumber; i++ )
{
if (IsPrimeNumber(i))
{
primeNumbers.Add(i);
}
}
return primeNumbers;
}
直觉表明计算它们将花费很长时间,因此我们将其数量减少到300,000
static void Main(string[] args)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
IEnumerable<ulong> primeNumbers = GetAllPrimeNumbers();
checkGoldbach(primeNumbers);
stopwatch.Stop();
Console.WriteLine(" " + stopwatch.Elapsed.TotalSeconds + " ");
foreach(var number in primeNumbers)
{
Console.Write(number + " ");
}
Console.ReadKey();
}
然后我想找到所有最高达2 ^ 64的质数(在我看来,几个小时的计算对于我来说就足够了)
运行程序两分钟后,我决定放置一个断点并检查为简化起见检查哪个数字:
两分钟的计算后进行411780次迭代。我决定稍微优化一下检查数字简单性的方法,因为不需要在数字的一半之后继续迭代,
因此,检查简单性所需的迭代次数减少了一半。在我看来,在2分钟内迭代次数应该增加一倍
但是在这里,我也是错的。生产率不是增加100%,而是增加了22%。正如我稍后所理解的,这是由于这样的事实,即像以前一样,将一半的支票除以2后被除掉,而没有被2除的所有数中有三分之一被除以3了,依此类推。在500,154个简单性测试中,发现了41549个素数。也就是说,for迭代
for (ulong i = 2; i <= n/2; i++)
{
if (n % i == 0)
{
result = false;
break;
}
}
执行到最后(不间断)仅41,549次。在其他情况下,它被更早地中断了...
500154而不是接近2 ^ 64,您需要计算将所有数字的简单性检查为2 ^ 64需要多长时间。
首先,让迭代次数从2 ^ 64减少到30000,并计算秒表方法的运行时间
进行迭代数字最多30,000,花了1秒
现在让我们创建一个具有其他迭代次数值的表
让我们在Excel中编写结果,并为坐标``时间迭代次数''和``每个范围的质数''构建点图
现在我们可以找到直至2 ^ 64,大约需要花费多长时间
如果在“每个范围的质数”图中添加“线性”趋势线,则Excel将为您提供公式y = 0.074x + 3004(我不知道该公式的准确性)。这意味着素数的最大数目可达ulong.MaxValue = 0.074 * 2 ^ 64 + 3004;
以相同的方式,将“多项式”趋势线添加到“随时间的迭代数”图表中,我们得到公式y = 7E-10x2 + 6E-05x。用我们的数字2 ^ 64代替x,您会发现要找到所有2 ^ 64以内的质数,我们大约需要2.38E + 29秒,即7553198149564240000000年。好吧,我不能指望那么多。
让我们尝试证明戈德巴赫的猜想对于不超过30万的所有偶数都是正确的。
public static void checkGoldbach(IEnumerable<ulong> primeNumbers)
{
ulong numbersCount = 300000;
for (ulong number = 4; number<numbersCount; number+=2)
{
bool isGoldbachResult = false;
foreach(ulong primeNumber1 in primeNumbers)
{
foreach(ulong primeNumber2 in primeNumbers)
{
if(primeNumber1+primeNumber2==number)
{
Console.WriteLine("{0} = {1} + {2}", number, primeNumber1, primeNumber2);
isGoldbachResult = true;
break;
}
if(primeNumber1+primeNumber2>number)
{
break;
}
}
if(isGoldbachResult|| primeNumber1>number)
{
break;
}
}
if(!isGoldbachResult)
{
Console.WriteLine(" " + number + " ");
break;
}
}
}
如果Goldbach的声明对于某个数字不正确,则该方法将停止以该数字进行计算。
经过9分钟的计算,我们可以说戈德巴赫的假设对小于30万的数字有效。
总
事实证明,一切都不像刚开始时那么简单,而且我知道我根本无法解决问题。
在我看来,为了简化起见,似乎有更好的选择来检查数字。比起简单的质数枚举,可以更合理地实施检查偶数数字以确认哥德巴赫陈述正确性的方法,但是我不再想在此花费太多时间...
解决哥德巴赫问题对人类没有任何帮助。到目前为止,已经证明该假设对4 * 10 ^ 18以下的数字是正确的,但是对所有数字进行证明有什么意义呢?数学家为此目的写书并通常花时间解决这些“问题”是为了什么?
我真的想问知识渊博的人,我的计算每个范围的素数数量的公式是否存在?
聚苯乙烯
最有可能的是,我不需要写我不太了解的文章。我没想到社区会做出这种反应。但是我没有假装我的解决方案是唯一正确的解决方案。我是这个领域的业余爱好者。
我写这篇文章是出于什么目的?
我花时间研究了这个问题,在我看来有些人可能喜欢它。这对我来说很有趣,因为这是一项有趣的任务。但是,为什么数学家会为此浪费时间呢?我真的不了解研究这些具体问题的真正好处。
PPS
阅读有关该文章的评论后,我决定下结论。
在我看来,很可能有更好的选择来检查数字以简化操作
根据用户的建议 dvserg 为什么 和 最好的确实是。例如,使用Eratosthenes筛子,可以更快地收集素数集合。这是您可以阅读有关该主题的文章:O(log N)中检查简单性的算法,维基百科,您可以阅读Srinivas Ramanujan Iyengor的著作
我计算每个范围的质数数量的公式是否存在?
没有
解决哥德巴赫问题不会给人类带来什么?
我认为一些数学问题没有用,这引起了大多数用户的强烈反对。用户数vvadzim 冰箱 布罗姆日 签入 冰箱 EimKR bfDeveloper 和 是的能够说服我 我把话说回来。
自古以来,数学家一直在寻找真理,而他们的寻找通常会为进步带来有益的后果。也许问题本身及其解决方案不会在此刻为世界提供任何帮助,但这是在寻求解决方案的过程中得出的结论,从长远来看可能是有用的。