简体   繁体   中英

using a random number as a parameter to generate a random number

Im not sure of this is an acceptable post, but out of curiosity would

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);

be more of a random number than just say

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

Your question presumes that there are degrees of randomness. That's incorrect, randomness is a binary state. If the outcome of a trial cannot be predicted with certainty, the trial is random . Otherwise we say it is deterministic . By analogy, would you ask the question which is more dead, somebody killed by a gun or somebody killed by electrocution? Dead is dead! (*)

We characterize randomness with distributions, which describe the relative likelihood of various outcomes. Examples would be the uniform, Gaussian, triangle, Poisson, or exponential distribution, to name a few. They all yield different likelihoods of having outcomes fall in various ranges, but no probabilist I know would say that the uniform distribution is more random than the Gaussian, or vice versa. Similarly, your two algorithms will produce different distributions of outcomes but since neither is predictable with certainty they both qualify as random.

If you want to capture the degree of predictability, you should probably be asking which algorithm has higher entropy rather than which is more random. A well-known result is that the uniform distribution has maximum entropy among the class of distributions with support on a bounded interval. Thus your complicated algorithm has lower entropy than the simple uniform distribution, and is more predictable.

(*) - Except in "The Princess Bride," where Wesley is only "mostly dead."

The first approach produces something more like a curved distribution rather than a linear distribution.

Try running the following command-line app and you'll see the difference:

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);
        }
    }
}

An easy test (a histogram ) will show you the actual distribution :

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}");

And you'll get something like

 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)

Nothing like uniformly distributed random values, far from it, but kind of bell-shaped curve

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM