使用随机数作为参数生成随机数

本文关键字:随机数 参数 | 更新日期: 2023-09-27 18:16:36

我不确定这是一个可以接受的帖子,但出于好奇,

Random rnd = new Random();
        int random1 = rnd.Next(1, 24);
        int random2 = rnd.Next(25, 49);
        int random3 = rnd.Next(random1, random2);
        int random4 = rnd.Next(50, 74);
        int random5 = rnd.Next(75, 100);
        int random6 = rnd.Next(random4, random5);
        int random7 = rnd.Next(random3, random6);
        Console.WriteLine(random7);

更像是一个随机数而不是仅仅说

Random rnd = new Random();
int random1 = rnd.Next(1, 100);
Console.WriteLine(random1);

使用随机数作为参数生成随机数

你的问题假设存在不同程度的随机性。这是不正确的,随机性是一种二元状态。如果一项试验的结果不能确定地预测,则该试验是随机的。否则我们说它是确定性的。以此类推,你会问谁死得更多,是被枪打死还是被电刑打死?(*)

我们用分布来描述随机性,分布描述了各种结果的相对可能性。例如均匀分布、高斯分布、三角形分布、泊松分布或指数分布等等。结果落在不同范围内的概率各不相同,但我认识的概率学家都不会说均匀分布比高斯分布更随机,反之亦然。同样,你的两种算法将产生不同的结果分布,但由于它们都不是确定的可预测的,它们都符合随机。

如果你想捕获可预测性的程度,你可能应该问哪个算法具有更高的熵,而不是哪个更随机。一个众所周知的结果是,在有界区间上具有支持的一类分布中,均匀分布具有最大的熵。因此,你的复杂算法比简单的均匀分布具有更低的熵,并且更可预测。

(*) -除了在"公主新娘"中,韦斯利只是"几乎死了"。

第一种方法产生的结果更像是曲线分布,而不是线性分布。

尝试运行以下命令行应用程序,您将看到差异:

using System;
namespace Demo
{
    class Program
    {
        const int N = 1000000;
        static void Main()
        {
            var result1 = testRandom(randomA);
            var result2 = testRandom(randomB);
            Console.WriteLine("Results for randomA():'n");
            printResults(result1);
            Console.WriteLine("'nResults for randomB():'n");
            printResults(result2);
        }
        static void printResults(int[] results)
        {
            for (int i = 0; i < results.Length; ++i)
            {
                Console.WriteLine(i + ": " + new string('*', (int)(results[i]*2000L/N)));
            }
        }
        static int[] testRandom(Func<Random, int> gen)
        {
            Random rng = new Random(12345);
            int[] result = new int[100];
            for (int i = 0; i < N; ++i)
                ++result[gen(rng)];
            return result;
        }
        static int randomA(Random rng)
        {
            return rng.Next(1, 100);
        }
        static int randomB(Random rnd)
        {
            int random1 = rnd.Next(1, 24);
            int random2 = rnd.Next(25, 49);
            int random3 = rnd.Next(random1, random2);
            int random4 = rnd.Next(50, 74);
            int random5 = rnd.Next(75, 100);
            int random6 = rnd.Next(random4, random5);
            return rnd.Next(random3, random6);
        }
    }
}

一个简单的测试 (直方图)将显示的实际分布:

private static Random rnd = new Random();
private static int[] Hist() {
  int[] freqs = new int[100];
  // 100 buckets, 1000000 samples; we might expect about 10000 values in each bucket
  int n = 1000000;
  for (int i = 0; i < n; ++i) {
    int random1 = rnd.Next(1, 24);
    int random2 = rnd.Next(25, 49);
    int random3 = rnd.Next(random1, random2);
    int random4 = rnd.Next(50, 74);
    int random5 = rnd.Next(75, 100);
    int random6 = rnd.Next(random4, random5);
    int random7 = rnd.Next(random3, random6);
    freqs[random7] = freqs[random7] + 1;
  }
  return freqs;
}
...
Console.Write(string
 .Join(Environment.NewLine, Hist()
   .Select((v, i) => $"{i,2}: {v,5}");

你会得到像

这样的东西
 0:      0 <- OK, zero can't appear
 1:     21 <- too few (about 10000 expected)
 2:     56 <- too few (about 10000 expected)
 3:    125 ...
 4:    171
 5:    292
 6:    392
 7:    560
 8:    747 ...
 9:    931 <- too few (about 10000 expected)
 ...
 45: 21528 <- too many (about 10000 expected)
 46: 21549 ...
 47: 21676
 48: 21699
 49: 21432
 50: 21692
 51: 21785
 52: 21559
 53: 21047
 54: 20985 ...
 55: 20820 <- too many (about 10000 expected)
 ...
 90:   623 <- too few (about 10000 expected)
 91:   492 ...
 92:   350
 93:   231
 94:   173
 95:    88
 96:    52
 97:    13
 98:     0 ...
 99:     0 <- too few (about 10000 expected)

不像均匀分布的随机值,远非如此,而是一种钟形曲线