我只是想发布我的测试代码并解释一些事情。首先,这是我的代码:
using System;
using System.Diagnostics;
namespace ConsoleApplication1
{
public static class Program
{
public static long Success;
public static long Failure;
public static long TotalIterations;
public static long TotalCallsToRandom;
public static readonly int CurrentSeed = Environment.TickCount;
public static Random Random = new Random(CurrentSeed);
public static Stopwatch TotalSimulationTime = new Stopwatch();
public static Stopwatch ReportWatchTime = new Stopwatch();
public static bool IsRunning = true;
//
public const int TotalTestingIndices = 7;
public const int MaximumTestingValue = 31;
public const int TimeBetweenReports = 30000; // Report every 30 Seconds.
//
public static void Main(string[] args)
{
int[] array = new int[TotalTestingIndices];
TotalSimulationTime.Start();
ReportWatchTime.Start();
while (IsRunning)
{
if (ReportWatchTime.ElapsedMilliseconds >= TimeBetweenReports)
{
Report();
ReportWatchTime.Restart();
}
Fill(array);
if (IsPerfect(array))
{
Success++;
Console.WriteLine("A Perfect Array was found!");
PrintArray(array);
Report();
IsRunning = false;
}
else
{
Failure++;
}
TotalIterations++;
}
Console.Read();
}
public static void Report()
{
Console.WriteLine();
Console.WriteLine("## Report ##");
Console.WriteLine("Current Seed: " + CurrentSeed);
Console.WriteLine("Desired Perfect Number: " + MaximumTestingValue);
Console.WriteLine("Total Testing Indices: " + TotalTestingIndices);
Console.WriteLine("Total Simulation Time: " + TotalSimulationTime.Elapsed);
Console.WriteLine("Total Iterations: " + TotalIterations);
Console.WriteLine("Total Random.NextInt() Calls: " + TotalCallsToRandom);
Console.WriteLine("Success: " + Success);
Console.WriteLine("Failure: " + Failure);
Console.WriteLine("## End of Report ##");
Console.WriteLine();
}
public static void PrintArray(int[] array)
{
for (int i = 0; i < array.Length; i++)
{
Console.Write(array[i]);
if (i != array.Length - 1)
{
Console.Write(",");
}
}
}
/// <summary>
/// Optimized to terminate quickly.
/// </summary>
/// <param name="array"></param>
/// <returns></returns>
public static bool IsPerfect(int[] array)
{
for (int i = 0; i < array.Length; i++)
{
if (array[i] != MaximumTestingValue)
{
return false;
}
}
return true;
}
public static void Fill(int[] array)
{
for (int i = 0; i < array.Length; i++)
{
array[i] = Random.Next(MaximumTestingValue + 1);
TotalCallsToRandom++;
}
}
}
}
经过大约三个小时的测试,我有了一些认识。我相信有可能获得 8 个完美的 31 指数……但前提是你在第 10 亿个左右的 Random.Next() 调用中很幸运。我知道这似乎是一个主观的说法,但这是我通过这些测试所经历的。我从来没有得到 8-Perfect 31's,但我确实得到了 7-Perfect 31's。第一次是在 13 分钟后。这是打印出来的:
A Perfect Array was found!
31,31,31,31,31,31,31
## Report ##
Total Simulation Time: 00:13:32.4293323
Total Iterations: 7179003125
Success: 1
Failure: 7179003125
## End of Report ##
我当时没有将它编码打印出来,但打印出来意味着有 50,253,021,875 次单独调用 Random.NextInt();这意味着该决议一直坚持到 500 亿次调用。
而另一个 7-Perfect 仅在程序运行大约 30 秒后才运行。这意味着有“好种子”可以相当快地获得这种稀有性。我还对 7-Perfect 指数进行了 30 分钟的测试,但没有得到一个。是靠运气,但同时我也深深地感觉到好像有一道无形的门槛;如果你不尽快击中它,它根本不会发生。上面的一个海报说Random类的分辨率是“281,474,976,710,656”。但我的测试似乎得出结论,分辨率实际上可能远小于此。自己尝试一下,从 4-6 个指数开始(几秒钟内发生),然后向上移动到 7 和 8。这不仅仅是概率增加,而是有一个阈值......或者也许我错了。谁知道?