Random.Next() 在发生环绕之前迭代多少次? [英] Random.Next() How many iterations before a wrap around occurs?

查看:33
本文介绍了Random.Next() 在发生环绕之前迭代多少次?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很确定这永远不会成为问题.但是,我仍然很好奇,任何给定的种子在其范围完全耗尽并返回以再次生成相同的数字之前,究竟可以进行多少次迭代?

I'm pretty sure that this will never be an issue. However, I'm still curious, exactly how many iterations can any given seed generate a random number before its scope is fully exhausted and it wraps back around to generating the same numbers again?

举个例子:

假设您有一个由八个整数索引组成的数组;在给定的迭代中,random.Next 将用 0-31 的值填充每个索引.并且该测试试图查看生成所有 31 个的完美数组需要多长时间.

Suppose you have an array consisting of eight integer indices; during a given iteration the random.Next would fill each indice with a value of 0-31. And the test is attempting to see how long it would take to generate a perfect array of all 31's.

从数学上讲,每次迭代产生所有 31 个完美数组的几率大约为 1,099,511,627,776 分之一.然而,这是假设 C# 随机数生成器甚至可以达到 1 万亿次迭代的预计范围,而不会自我回绕.

Mathematically, the odds are roughly 1 in 1,099,511,627,776 per iteration to yield a perfect array of all 31's. However, this is assuming that the C# Random number generator could even make it to the projected range of 1 trillion iterations without wrapping back around on itself.

那么,总结一下我的实际问题,Random 类能否完成我提出的测试?或者它是否会到达中途标记并且无论它经过多少次迭代都注定失败? 在达到随机数生成器结束之前的迭代次数究竟是多少?我还想提一下,成功生成 6 个完美 31 的数组只需要大约 20 分钟.这是经过我测试和验证的.

So, to sum up my actual question, could the Random class achieve the test that I have presented? Or would it reach a half-way mark and just doom itself to failure regardless of how many iterations it goes through? What exactly is the number of iterations before the end of the random number generator will be reached? I wanted to also mention that it only takes about 20 minutes to successfully generate an array of 6 perfect 31's. This was tested by me and verified.

我还应该提到,我目前正在运行一个试图实现这一目标的测试机制.到目前为止,这是当前的报告,每分钟显示一次:

I should also mention that I am currently running a testing mechanism that is trying to achieve this. So far, this is the current report, which is displayed every minute:

##### Report #####
Elapsed Simulation Time: 00:49:00.1759559
Total Iterations: 20784834152
Perfect Eight Success: 0
Failure: 20784834152
##### End Report #####

我估计找到 1 个完美的 31 数组所需的时间大约为 47 小时 56 分钟,以接近找到 1 个完美的 31 组的范围.那是我的计算机每分钟填充我的阵列 383,500,572.看起来这个测试需要的时间比我原先预计的要长得多.

I have estimated the required time to find 1 perfect array of 31's to be roughly 47 Hours and 56 Minutes to get close to the range of finding even 1 perfect set of 31's. That's with my computer filling my array 383,500,572 every minute. Looks like this test will take far longer than I originally projected.

2 小时更新

##### Report #####
Elapsed Simulation Time: 02:00:00.4483950
Total Iterations: 55655726300
Success: 0
Failure: 55655726300
##### End Report #####

我有点希望我能把这个穿出来……可能可以把时间减少一半……

I kind of wish I would have threaded this...probably could have cut the time in half...

推荐答案

我只是想发布我的测试代码并解释一些事情.首先,这是我的代码:

I just wanted to post my testing code and explain a few things. First, here is my code:

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 指数……但前提是你在对 Random.Next() 的前十亿次左右的调用中很幸运.我知道这似乎是一个主观的说法,但这是我通过这些测试所经历的.我从来没有得到过 8-Perfect 31,但我确实得到了 7-Perfect 31.第一次是在 13 分钟之后.这是打印出来的:

After about three hours of testing I have come to a few realizations. I believe it may be possible to get eight perfect indices of 31...but only if you get lucky within the first billion or so calls to Random.Next(). I know this may seem like a subjective thing to say, but it's what I have experienced through these tests. I never once got 8-Perfect 31's, but I did get 7-Perfect 31's. The first time it was after 13 minutes. Here is the print out:

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 亿次调用.

I didnt have it coded in at the time to print it out, but that print out would mean there were 50,253,021,875 individual calls to Random.NextInt(); This means that the resolution held up all the way to 50 Billion calls.

另一个 7-Perfect 仅在程序运行约 30 秒后才出现.这意味着有好种子"可以相当快地获得这种稀有性.我还对 7-Perfect 指数进行了 30 分钟的测试,但没有得到一个.它是靠运气,但同时我也深深地感觉到好像有一个无形的门槛;如果你不尽快击中它,它根本不会发生.上面的一张海报说 Random 类的分辨率是281,474,976,710,656".但我的测试似乎得出结论,分辨率实际上可能远小于此.自己尝试一下,从 4-6 个索引开始(在几秒钟内发生)并上升到 7 和 8.这不仅仅是概率增加,而是有一个阈值......或者我可能只是错了.谁知道?

And the other 7-Perfect was only after about 30 seconds of the program running. That means there are "Good Seeds" for getting this kind of rarity fairly quickly. I also ran the test for 7-Perfect indices for thirty minutes and didn't get a single one. It's based on luck, but at the same time I heavily feel as though there is an invisible threshold; if you don't hit it soon it won't happen at all. A poster above said that the resolution of the Random class is "281,474,976,710,656". But my tests seem to conclude that the resolution may actually be far smaller than that. Try it yourself, start from 4-6 indices(Happens within a matter of seconds) and move up to 7 and 8. It's not just that the probability increases, it's that there is a threshold...or maybe I am just wrong. Who knows?

这篇关于Random.Next() 在发生环绕之前迭代多少次?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆