I have a situation in which I must generate a random number, this number must be either zero or one
So, the code is something like this:
randomNumber = new Random().Next(0,1)
However, the business requirements state that there is just 10% probability that the generated number is zero and 90% probability that the generated number is 1
However can I include that probability in generating the random number please?
What I thought of is:
Generate array of integer that includes 10 zeros and 90 ones.
Generate a random index between 1 and 100
Take the value that corresponds to that index
But I don't know if this way is the correct way, plus, I think that C# should have something ready for it
You can implement it like that:
// Do not re-create Random! Create it once only
// The simplest implementation - not thread-save
private static Random s_Generator = new Random();
...
// you can easiliy update the margin if you want, say, 91.234%
const double margin = 90.0 / 100.0;
int result = s_Generator.NextDouble() <= margin ? 1 : 0;
to get true with a probability of 10%:
bool result = new Random().Next(1, 11) % 10 == 0;
to get true with a probability of 40%:
bool result = new Random().Next(1, 11) > 6;
First of all, you should save the reference to the random instance in order to get a proper random sequence of numbers:
Random randGen = new Random();
The second thing to know, is that the max of the random is exclusive, so to properly solve the issue you should do:
int eitherOneOrZero = randGen.Next(1, 11) % 10;
To generalize it to any variation of chances, you can do:
Random randGen = new Random();
var trueChance = 60;
int x = randGen.Next(0, 100) < trueChance ? 1 : 0;
Testing:
Random randGen = new Random();
var trueChance = 60;
var totalCount = 1000;
var trueCount = 0;
var falseCount = 0;
for (int i = 0; i < totalCount; i++)
{
int x = randGen.Next(0, 100) < trueChance ? 1 : 0;
if (x == 1)
{
trueCount++;
}
else
{
falseCount++;
}
}
Output:
True: 60.30 %
False: 39.70 %
Related
Hi guy i try to generate 50 number with 5 digit depend on user total summary. For example, User give 500000 and then i need to random number with 5 digit by 50 number equal 500000
i try this but it isn't 5 digit number
int balane = 500000;
int nums = 50;
int max = balane / nums;
Random rand = new Random();
int newNum = 0;
int[] ar = new int[nums];
for (int i = 0; i < nums - 1; i++)
{
newNum = rand.Next(0, max);
ar[i] = newNum;
balane -= newNum;
max = balane / (nums - i - 1);
ar[nums - 1] = balane;
}
int check = 0;
foreach (int x in ar)
{
check += x;
}
i tried already but value inside my array have negative value i want to get only
positive value
Please help me, how to solve this and thank for advance.
I once asked a similar question on codereview.stackexchange.com. I have modified my answer to produce a five digit sequence for you.
Furthermore, this code is fast enough to be used to create tens of thousands of codes in a single request. If you look at the initial question and answer (linked to below) you will find that it checks to see whether the code has been used or not prior to inserting it. Thus, the codes are unique.
void Main()
{
Console.WriteLine(GenerateCode(CodeLength));
}
private const int CodeLength = 10;
// since Random does not make any guarantees of thread-safety, use different Random instances per thread
private static readonly ThreadLocal<Random> _random = new ThreadLocal<Random>(() => new Random());
// Define other methods and classes here
private static string GenerateCode(int numberOfCharsToGenerate)
{
char[] chars = "0123456789".ToCharArray();
var sb = new StringBuilder();
for (int i = 0; i < numberOfCharsToGenerate; i++)
{
int num = _random.Value.Next(0, chars.Length);
sb.Append(chars[num]);
}
return sb.ToString();
}
Original question and answer: https://codereview.stackexchange.com/questions/142049/creating-a-random-code-and-saving-if-it-does-not-exist/142056#142056
Perhaps try this:
var rnd = new Random();
var numbers = Enumerable.Range(0, 50).Select(x => rnd.Next(500_000)).OrderBy(x => x).ToArray();
numbers = numbers.Skip(1).Zip(numbers, (x1, x0) => x1 - x0).ToArray();
numbers = numbers.Append(500_000 - numbers.Sum()).ToArray();
Console.WriteLine(numbers.Count());
Console.WriteLine(numbers.Sum());
This outputs:
50
500000
This works by generating 50 random numbers between 0 and 499,999 inclusively. It then sorts them ascendingly and then gets the difference between each successive pair. This by definition produces a set of 49 values that almost adds up to 500,000. It's then just a matter of adding the one missing number by doing 500_000 - numbers.Sum().
i want to generate random number between (1 to 6),is there any way to change the chance of geting number 6 more than other numbers?
for example for this code
private void pictureBox5_MouseClick(object sender, MouseEventArgs e)
{
Random u = new Random();
m = u.Next(1,6);
label2.Text = m.ToString();
}
Let p be probability of any 1..5 numbers and 1 - p is a probability of 6:
//DONE: do not recreate Random
private static Random s_Generator = new Random();
private void pictureBox5_MouseClick(object sender, MouseEventArgs e) {
const double p = 0.1; // each 1..5 has 0.1 probability, 6 - 0.5
// we have ranges [0..p); [p..2p); [2p..3p); [3p..4p); [4p..5p); [5p..1)
// all numbers 1..5 are equal, but the last one (6)
int value = (int) (s_Generator.NexDouble() / p) + 1;
if (value > 6)
value = 6;
label2.Text = value.ToString();
}
That wouldn't be random then. If you wanted to weight it so you would get 6 half the time, you could do this:
m = u.Next(1,2);
if(m == 2)
{
label2.Text = "6";
}
else
{
label2.Text = u.Next(1,5).ToString();
}
Based on what weighting you want you could change it-> 3 instead of 2 get a 33.33% weighting and so on. Otherwise, as the commenter said, you'd have to look into probability distributions for a more mathematically elegant solution.
Depends on how more likely. An easy way (but not very flexible) would be the following:
private void pictureBox5_MouseClick(object sender, MouseEventArgs e)
{
Random u = new Random();
m = u.Next(1,7);
if (m > 6) m = 6;
label2.Text = m.ToString();
}
If you want a totally random distribution of 1...5 and just a skwed 6, then Dmitry's seems best.
If you what to skew ALL the numbers, then try this:
Create a 100 element array.
Fill it with the number 1-6 in proportions based on how often you want the number to come up. (make 33 of them 6, if you want 6 to come up 1/3rd of the time. Four 4s means it'll only come up one in 25 rolls etc. 15 or 16 of each number will make it about evenly distributed, so adjust the counts from there)
Then pick a number from 0...99 and use the value in the element of the array.
You could define the possibility in a percentage of getting each of the numbers in an array:
/*static if applicable*/
int[] p = { (int)Math.Ceiling((double)100/6), (int)Math.Floor((double)100/6), (int)Math.Ceiling((double)100/6), (int)Math.Floor((double)100/6), (int)Math.Ceiling((double)100/6), (int)Math.Ceiling((double)100/6) };
////The array of probabilities for 1 through p.Length
Random rnd = new Random();
////The random number generator
int nextPercentIndex = rnd.Next() % 100; //I can't remember if it's length or count for arrays off the top of my head
////Convert the random number into a number between 0 and 100
int TempPercent = 0;
////A temporary container for comparisons between the percents
int returnVal = 0;
////The final value
for(int i = 0; i!= p.Length; i++){
TempPercent += p[i];
////Add the new percent to the temporary percent counter
if(nextPercentIndex <= TempPercent){
returnVal = i + 1;
////And... Here is your value
break;
}
}
Hope this helps.
i'm trying to get X number of random number (where X is a variable) between 0 and 100 and add them to a row in a DataGridView. I'm using the code below, but the problem is i need it to be impossible to have the same number twice. Is there a way make sure i get unique random numbers?
int X = 20;
Random random = new Random();
int randomrow = random.Next(0, 100);
for (int i = 0; i < X; i++)
{
int randomNumber = random.Next(0, 100);
data.Rows[randomrow][3] = randomNumber;
}
Thanks for the help!
Split your problem in two:
Create a list of X random, unique numbers. There are numerous ways to do that:
a. Create a list of all numbers 0-100 and then shuffle them. OR
b. Keep a hash set of all the numbers you already created (in addition to the list) and only add a new one if it has not been added before.
Afterwards, loop through the list and the data rows simultaneously and insert the values into the rows.
Here's the simple way to do it without creating a shuffle method for the List (though there are examples of that). Basically create a list of all possible integers, populate the list, then sort by new GUIDs.
int X = 20;
var RowNumbers = new List<int>();
for (int i = 0; i < X; i++)
RowNumbers.Add(i);
foreach (int i in RowNumbers.OrderBy(f => Guid.NewGuid()))
{
data.Rows[i][3] = i;
}
You would need to compare the numbers you have already used to the next one you get from random.Next. If you have already used it, pick another. I also like Heinzi's answer.
Here is algorithm without shuffling and previous result using:
var max = 100; // max available value
var count = 20; // number of random numbers
var random = new Random();
var rest = (double)max;
for (int i = 0; i < max; i++, rest--)
{
if (count / rest > random.NextDouble())
{
Console.WriteLine(i); // here is your random value
count--;
if (count == 0)
{
break;
}
}
}
How can i generate different random numbers in short time?
For example:
Number = 20;
if (Number > 0)
{
AddEffect(rand.Next(0,100);
Number--;
}
In this example, rand.Next gives me twenty times the same number. Is there any way to force a change?
I think you're trying to say:
var rand = new Random();
var Number = 20;
while (Number > 0)
{
// rand.Next(0,100); // this will give 20 different numbers btw
AddEffect(rand.Next(0,100));
Number--;
}
but otherwise, seems fine
int totalNumbers = 20;
Random rand = new Random();
for (int i = 0; i < totalNumbers; i++)
{
AddEffect(rand.Next(0, 101)); // a number between -1 and 101, min: 0, max: 100
}
Is this what you mean? This is an easy and clear way to generate some random numbers.
More info here: http://www.dotnetperls.com/for
Am I looking too far to see something as simple as pick a number: 0 or 1?
Random rand = new Random();
if (rand.NextDouble() == 0)
{
lnkEvents.CssClass = "selected";
}
else
{
lnkNews.CssClass = "selected";
}
Random rand = new Random();
if (rand.Next(0, 2) == 0)
lnkEvents.CssClass = "selected";
else
lnkNews.CssClass = "selected";
Random.Next picks a random integer between the lower bound (inclusive) and the upper bound (exclusive).
If you want 50/50 probability, I suggest:
Random rand = new Random();
if (rand.NextDouble() >= 0.5)
lnkEvents.CssClass = "selected";
else
lnkNews.CssClass = "selected";
It seems like what you're wanting to do (choose between two values) is more clearly expressed by using the Next method, instead of the NextDouble method.
const int ExclusiveUpperBound = 2;
if (new Random().Next(ExclusiveUpperBound) == 0)
The value produced is "greater than or equal to zero, and less than" ExclusiveUpperBound.
Random.NextDouble() will select any double number from 0 but less than 1.0. Most of these numbers are not zero, so your distribution will not be as even as you expect.
If not in a tight loop you could use
(DateTime.Now.Millisecond % 2) - double DateTime.Now.Millisecond % (double) 10) / 10
A very simple approach could be:
Random random = new Random();
bool result = random.Next(0, 2) != 0;
Then use result for your logic.