How can I get two random strings from two arrays in C# - c#

how can I get two strings from two arrays randomly. I have something, but It doesn't pick randomly.
string[] firstNames = { "John", "Michael", "Victor", "Mark", "Alex", "Steven", "Zack", "Howard", "Xzavier", "Brendan", "Dustin", "Carl" };
string[] lastNames = { "Adams", "McGregor", "Piasta", "Semmel", "Laris", "Sever", "Bourque", "Percy", "Shanabarger", "Bobak", "Adair" };
string[] shuffled = firstNames.OrderBy(n => Guid.NewGuid()).ToArray();
string[] shuffled2 = firstNames.OrderBy(n => Guid.NewGuid()).ToArray();
Random firstn = new Random();
Random lastn = new Random();
int index = firstn.Next(firstNames.Length);
int index2 = lastn.Next(lastNames.Length);
Console.WriteLine($"The random name is {firstNames[index]}" + $" {lastNames[index2]}");
I am trying to make a random full name generator. I have tried this code multiple times and the results were: John Adams, Victor Piasta, and so on! And as you can see they are not random.

Looks pretty random to me..
With 150 iterations you still get a performance of roughly 90 of 132 possible combinations.
Testing code:
HashSet<string> names = new HashSet<string>(150);
Random rndm = new Random();
for (int i = 0; i < 150; i++)
{
names.Add($"{firstNames[rndm.Next(firstNames.Length)]} " +
$"{lastNames[rndm.Next(lastNames.Length)]}");
}
Console.WriteLine($"{names.Count} / {firstNames.Length * lastNames.Length}");
Console.ReadKey();
Don't forget that true random is not possible to simulate... so you will always have some kind of repetitive distribution with higher numbers.

Random works slightly different in .NET-Framework to .NET-Core
In .NET Framework, the default seed value is time-dependent. In .NET Core, the default seed value is produced by the thread-static, pseudo-random number generator.
From: https://learn.microsoft.com/en-us/dotnet/api/system.random?view=netcore-3.1#Instantiate
In the .NET-Framework only, on most Windows systems, Random objects created within 15 milliseconds of one another are likely to have identical seed values.
Use a single Random-instance on .NET-Framework to avoid this behaviour.

Just change to below so that you are using the same Random instance for both
int index2 = firstn.Next(lastNames.Length);

Random does not actually generate random numbers, but pseudo-random numbers. That means, you need a starting value, the so-called seed. From that value the first number is calculated. From that, one could calculate another number, and so on. These numbers look like random, but actually they are determined by the seed. If you have the same seed, you always get the same sequence of numbers.
Your Random class has actually a constructor where you can deliver a seed. You can try it out here: https://dotnetfiddle.net/0bHDNg For the same seed, you will always get the same sequence of numbers.
If you use the constructor without a parameter, the current time is taken as the seed. This has the big advantage, that you always get a different sequence of numbers when you restart the program. But in your example, you have a problem: If the time between creating the two instances of Random has not changed, because the computer is so fast, they will have both the same seed and thus both the same sequence of numbers. That's why index and index2 both have the same value. Just use the same instance of Random for generating both indices, and they don't have necessarily the same value:
Random random = new Random();
int index = random .Next(firstNames.Length);
int index2 = random .Next(lastNames.Length);
Console.WriteLine($"The random name is {firstNames[index]}" + $" {lastNames[index2]}");

Related

C# Random number unique first number

If I create a Random() with a different starting seed every time will the first number in the generator be unique every time, or is there a point in which the first number will start repeating?
Example:
var random1 = new Random(1);
var value1 = random1.Next();
var random2 = new Random(2);
var value2 = random2.Next();
var random3 = new Random(x);
var value3 = random3.Next();
where value1 != value2 != value3;
EDIT: Fixed variable names
I have tested seeds of 0-80,000,000, I am just wondering if they are unique from 0-int.Max, or if the first 80,000,000 are unique by accident
Generally, I don't think there is any requirement that pseudorandom generators should generate unique numbers given unique seeds.
The only think it happens is that, given a seed, the generator will always generate the same number sequence (obtained by calling multiple times the next method) and the sequence will repeat at some point.
However, the C# Random class uses a subtractive generation algorithm, where the next random number is generated basing on previous numbers of the sequence. Hence, there may be some kind of dependency between the number and the seed, which makes the random number generator to generate unique numbers every time the seed is changed.
If you want to be sure, either try it yourself with seeds from int.MinValue to int.MaxValue, or check the C# implementation here
https://referencesource.microsoft.com/#mscorlib/system/random.cs

Random Values for an Array?

I'm looking for some help with my array. to put it in context im trying to create a console application that randomly generates a 4-digit code for the user to guess.
to do this I need an array of [3] and they need to have random numbers assigned to it.
int[] secretCode = new int[3];
secretCode[0] =
secretCode[1] =
secretCode[2] =
secretCode[3] =
My concern is what would i put here to make them generate random numbers?
thank you for your help in advance.
You can use Linq and the Random class
Random rnd = new Random();
int[] secretCode =
Enumerable.Repeat(0, 4).Select(i => rnd.Next(1000, 10000)).ToArray();
or more traditionally
int SIZE = 4;
Random rnd = new Random();
int[] secretCode = new int[SIZE];
for (int i = 0; i < SIZE; i++)
{
secretCode[i] = rnd.Next(1000, 10000);
}
Note that there is a possibility of creating the same code more than once. The solution assumes you want something in the range 1000..9999 (10000 is an exclusive upper bound) since the code is to be 4 digits. If you would also allow smaller numbers, just adjust the Select portion.
As a side note, do not create a new instance of Random inside the select, as it would likely be reseeded to the same seed, based on the system time, resulting in the same "random" number over and over. Also Random is fast, but not cryptographically strong. If you need cryptographically valid randomness use RNGCryptoServiceProvider in place of Random.

System.Random not so random, why does this occur? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Random number generator only generating one random number
I've distilled the behavior observed in a larger system into this code sequence:
for (int i = 0; i < 100; i++)
{
Random globalRand = new Random(0x3039 + i);
globalRand.Next();
globalRand.Next();
int newSeed = globalRand.Next();
Random rand = new Random(newSeed);
int value = rand.Next(1, 511);
Console.WriteLine(value);
}
Running this from Visual Studio 2012 targeting .NET 4.5 will output either 316 or 315. Extending this beyond 100 iterations and you'll see the value slowly decrement (314, 313...) but it still isn't what I'd imagine anyone would consider "random".
EDIT
I am aware that there are several questions on StackOverflow already that ask why their random numbers aren't random. However, those questions have issues regarding one of a) not passing in a seed (or passing in the same seed) to their Random object instance or b) doing something like NextInt(0, 1) and not realizing that the second parameter is an exclusive bound. Neither of those issues are true for this question.
It's a pseudo random generator which basically creates a long (infinite) list of numbers. The list is deterministic but the order can in most practical scenarios be treated as random. The order is however determined by the seed.
The most random behaviour you can achieve (without fancy pants tricks that are hard to get right all the time) is to reuse the same object over and over.
If you change your code to the below you have a more random behaviour
Random globalRand = new Random();
for (int i = 0; i < 100; i++)
{
globalRand.Next();
globalRand.Next();
int newSeed = globalRand.Next();
Random rand = new Random(newSeed);
int value = rand.Next(1, 511);
Console.WriteLine(value);
}
The reason is the math behind pseudo random generators basically just creates an infinite list of numbers.
The distribution of these numbers are almost random but the order in which they come are not. Computers are deterministic and as such incapable of producing true random numbers (without aid) so to circumvent this math geniuses have produced functions capable of producing these lists of numbers, that have a lot of radnomness about them but where the seed is determining the order.
Given the same seed the function always produces the same order. Given two seeds close to each order (where close can be a property of which function is used) the list will be almost the same for the first several numbers in the list but will eventually be very different.
Using the first random number to generate the second. Doesnt make it any more "Random". As suggested try this.
Also as suggested no need to generate the random object inside the loop.
Random globalRand = new Random();
for (int i = 0; i < 100; i++)
{
int value = globalRand.Next(1, 511);
Console.WriteLine(value);
}
I believe the Random() is time based so if your process is running really fast you will get the same answer if you keep creating new instances of your Random() in your loop. Try creatining the Random() outside of the loop and just use the .Next() to get your answer like:
Random rand = new Random();
for (int i = 0; i < 100; i++)
{
int value = rand.Next();
Console.WriteLine(value);
}
Without parameters Random c'tor takes the current date and time as the seed - and you can generally execute a fair amount of code before the internal timer works out that the current date and time has changed. Therefore you are using the same seed repeatedly - and getting the same results repeatedly.
Source : http://csharpindepth.com/Articles/Chapter12/Random.aspx

Will this generate a random prize drawing

Ive taken over some prize drawing code.
I can see the person is using a Random number to order them by but is this actually going to be random as i cant see any place where he has done oRand.Next(); Does the default Random generate an actual random number.
Random oRand = new Random();
var res = (from l in listNew.AsQueryable<Participant>() //entities.Participant
where l.Status != 0
select l).AsEnumerable().OrderBy(p=>oRand);
Does the default Random generate an
actual random number.
In the example code you are ordering by the "RandomNumberMaker" (i.e. the same value for all values), not by random numbers.
This is quickly tested by comparing this code in LINQPad (which yields the numbers 1 to 1000 in natural order).
void Main()
{
Random oRand = new Random();
var res = Enumerable.Range(1, 1000).OrderBy(p=>oRand);
res.Dump();
}
with this code (which orders the numbers 1 to 1000 in pseudorandom order):
void Main()
{
Random oRand = new Random();
var res =Enumerable.Range(1, 1000).OrderBy(p=>oRand.Next());
res.Dump();
}
For an intro to how random .NET random really is, check out this article which has the advantage of starting with this great comic:
(source: csharpcity.com)
I think you need oRand.Next() to get random numbers. This looks like it would end up ordering them by the Random object. I don't see how using oRand by itself would result in the lambda expression calling Next().
In any case, when you use oRand = new Random(); oRand.Next();, you get pseudorandom numbers using time as a seed. This means that there is a sequence of numbers that is the same every time, and the one you start with depends on the time -- this is usually done with a function that you pass the last random number to get the next one and it has a very long period and the numbers have a random feel (so it's not just f(x) => x+1 or something like that).
This may not be good enough, but it is "random" for some definition of random.

Array 2 method random generated number

For a part of a program i need the following 2 methods.
The first method listed will generated a random number.
where the 2nd method will "call" this method to fill the array.
The array has a max. number of elements defefined on 100 (and all the random generated numbers should be between 1-100).
The problem is i never get random numbers generated. (either i get 100 x the same value, 3 random numbers divided over the 100 max. elements of the array, or the same value 100 times all over again).
The problem should be in the first method, but i cannot seem to figure out the problem.
Been staring at this for quite some time now...
The problem should be with the return, cause it DOES create random generated numbers. But how do i return the generated value every time? (the int method has to be called with the 3 parameters).
private int ValidNumber(int[] T, int X, int Range)
{
for (byte I = 0; I < T.Lenght; I++)
{
Random RndInt = new Random();
X = RndInt.Next(1, Range+1);
}
return X;
}/*ValidNumber*/
public void FillArray(int[] T, int Range)
{
for (byte I = 0; I < T.Length; I++)
{
T[I] = ValidNumber(T, I, Range);
}
}/*FillArray*/
Console code:
public void ExecuteProgram()
{
ClsBereken Ber = new ClsBereken();
//const byte Range = 100;
const int Max = 100;
int[] T = new int[Max];
Ber.FillArray(T, Max);
DisplayArray(T);
}/*ExecuteProgram*/
private void DisplayArray(int[] T)
{
for (byte i = 0; i < T.Length; i++)
{
Console.Write("{0,4} ", T[i]);
}
Console.WriteLine();
}/*DisplayArray*/
Any help alot appreciated.
Kind Regards.
Re-use the Random instance. NOTE I've edited this to show passing the Random instance down, but I'm really not sure what ValidNumber is trying to do - it looks like it is juts burning up CPU cycles? I would suggest you can remove ValidNumber completely (and just use the next value from the Random in FillArray), but presumably you are trying to do something here - I'm just not sure what!
private int ValidNumber(int[] T, int X, int Range, Random random)
{
for (byte I = 0; I < T.Lenght; I++)
{
X = random.Next(1, Range+1);
}
return X;
}/*ValidNumber*/
public void FillArray(int[] T, int Range)
{
Random random = new Random();
for (byte I = 0; I < T.Length; I++)
{
T[I] = ValidNumber(T, I, Range, random);
}
}/*FillArray*/
When you create a Random, it is "seeded" using the system clock, but this is rounded heavily. If you create lots of Random in a tight loop, they all get the same "seed", so they all create the same next number.
If necessary you could move the Random further out (if you have other loops), or make it static (but if you do that you need to worry about synchronization too).
The problem is that you are reinitializing rndint over and over.
take the line:
Random RndInt = new Random();
and move it in front of the loop and see if that fixes it.
When you initialize a random object, it is assigned a seed (probably based on the time), and that seed is used to generate a series of seemingly random values. However, if you plug in the same seed to two random objects, you will get the same series of random numbers.
So, what is happening in your code is you are initializing a new random object with a seed, and then asking for the first random number in its series. Then, you are initializing another random object (even though it is assigned to the same name, it is a new object) and it is getting the same seed, and you are again asking for the first random number in the series. So naturally, you are getting the same random number over and over.
You are continuously creating an new Random object. I'm afraid this is seeded (randomized) by the timestamp of creation. Since this is really fast and happens multiple times, the seed is the same, and so is the result of the call RndInt.Next(1, Range+1);.
By the way, even though not incorrect, it's not a common practice in c#.net to start with a capital letter on names of local variables and parameters.
Any random number generation algorithm* is not truly random; it is simply a deterministic algorithm that has been specifically designed to output numbers that resemble randomness. (See Pseudorandom number generator.) Since the algorithm is deterministic, its output is completely dependent upon a starting "seed" value.
The Random class in .NET has two constructors: one which takes an integer seed, and another which takes no parameters. This one bases its seed off the current time.
From this information perhaps you can guess why creating a new Random instance for every value in your array results in the entire array being filled with the same number: every time you construct a Random object within a very small time frame, it will have the same seed value, which means it will generate identical output to another Random object constructed within the same time frame.
As Marc Gravell has already indicated, you should be using only a single Random instance to generate a sequence of random numbers.
*Well, almost any. I believe there are hardware implementations of random number generators that factor in random noise (taken from the surrounding environment) and may therefore be considered "truly" random. Whether you believe these are actually random
depends on your personal definition of "random" and whether or not you believe that we live in a deterministic universe.
You can pass Random() a seed but if you send it the same seed number you will get the same results. The way you are using it
Random rnd = new Random();
Is using an auto-generated seed based on time. But you may not get seemingly random results if you don't at least sleep for a second. (Source http://msdn.microsoft.com/en-us/library/system.random(VS.71).aspx)
As everyone has mentioned here already your biggest issue is the fact you keep recreating the random object each iteration.

Categories