I'm using the System.Random function to create/generate a seed for random numbers, then using the Next() for following numbers, but much like in c++, the "rng" gets me the same results of random numbers every time. But in c++ that was solved by clearing the seed in c++ so I was wondering if that also possible in c#?
You most likely use a new instance of Random every time. You should not instantiate new Random(seed_here) repeatably.
Random r = new Random(); //Do this once - keep it as a (static if needed) class field
for (int i = 0; i < 10; i++) {
Console.WriteLine($"{r.Next()}");
}
Update
Here's a more sophisticated example:
class MyClass
{
//You should use a better seed, 1234 is here just for the example
Random r1 = new Random(1234); // You may even make it `static readonly`
public void BadMethod()
{
// new Random everytime we call the method = bad (in most cases)
Random r2 = new Random(1234);
for (int i = 0; i < 3; i++)
{
Console.WriteLine($"{i + 1}. {r2.Next()}");
}
}
public void GoodMethod()
{
for (int i = 0; i < 3; i++)
{
Console.WriteLine($"{i+1}. {r1.Next()}");
}
}
}
class Program
{
static void Main(string[] args)
{
var m = new MyClass();
m.BadMethod();
m.BadMethod();
m.GoodMethod();
m.GoodMethod();
}
}
Output
1. 857019877
2. 1923929452
3. 685483091
1. 857019877 <--- Repeats
2. 1923929452
3. 685483091
1. 857019877
2. 1923929452
3. 685483091
1. 2033103372 <--- Phew! It's a new number
2. 728933312
3. 2037485757
Related
I'm trying to use Random to generate random number for a text-based combat simulator but it keeps generating a very large and unusual number.
Here is the code:
internal class Program
{
static void Main(string[] args)
{
System.Console.WriteLine("Starting Simulator");
Actor FoxTail = new Actor();
FoxTail.HealthPoints = 15;
FoxTail.Strength = 2;
FoxTail.Defense = 12;
FoxTail.Spirit = 12;
FoxTail.Dexterity = 2;
FoxTail.Agility = 3;
FoxTail.Intelligence = 2;
FoxTail.Level = 0;
FoxTail.ExperiencePoints = 0;
Actor GreyWolf = new Actor();
GreyWolf.HealthPoints = 25;
GreyWolf.Strength = 2;
GreyWolf.Defense = 10;
GreyWolf.Spirit = 8;
GreyWolf.Dexterity = 5;
GreyWolf.Agility = 7;
GreyWolf.Intelligence = 2;
GreyWolf.Level = 1;
GreyWolf.ExperiencePoints = 5;
int FoxTailAttack = new Randomizer.RandomIntegerGenerator(1).GeneratePositiveValue();
if(FoxTailAttack >= GreyWolf.Defense)
{
int damage = new Randomizer.RandomIntegerGenerator(1).GeneratePositiveValue() + FoxTail.Strength;
GreyWolf.HealthPoints = GreyWolf.HealthPoints - damage;
Console.WriteLine("Grey Wolf is at " + GreyWolf.HealthPoints + " health!");
}
else
{
Console.WriteLine("Foxtail missed!");
}
Console.WriteLine("Press any key to continue...");
System.Console.ReadLine();
I'm assuming the '1' in the parathesis after RandomIntegerGenerator is where my problem lies, but I just don't know how to define a range for the random number to generate. I get a weird -534011695 number that gets outputted in my runtime window. I'd like to get it to generate a number beween 1 and 25 if possible.
You seem to be using some Randomizer class from somewhere else. You don't need that. C# comes with the Random class, that has everything you need.
Only create one instance of the Random class and use it throughout the whole application. This is important because the instance is initialized with the current time as a random seed value when the instance is created. If you created a new instance each time, you would often get sequences of the same random number.
internal class Program
{
public static Random Randomizer { get; private set; } = new Random();
You can then use the Next method to retrieve a random integer number in a given range:
static void Main(string[] args)
{
for(int i=0; i <= 10; i++)
{
// Create integers >= 1 and < 26.
// The result can be 1 and 25, but not 26
int number = Randomizer.Next(1, 26);
Console.WriteLine(number.ToString());
}
}
The call Randomizer.Next(1, 26); will return values from 1 to 25.
First of all, I'm new in C# (and in development overall). My question is quiet simple.
I've two different classes. A method of one of my class is returning an array. I'm trying to use this array in a method of the other class, here is the code:
The idea here is to retrieve those numbers stored in the array, and generate cards with related ID (stored in DB) in the for statement.
class c_random
{
int nbr_random_to_generate = 2; // number to generate
/*
* This function
* - execute the methods to counts nbr of cards in DB
* - Create an Array with id of cards to generate
* */
public int[] generate_random()
{
Random rnd = new Random();
c_ConnectionMySQL obj_sqlRes = new c_ConnectionMySQL(); // Create a connection to MySQL
obj_sqlRes.count_cards_DB(); // Execute the method to count the number of cards in DB
Console.WriteLine(obj_sqlRes.nbr_cards);
int[] array_random = new int[nbr_random_to_generate];
for (int i = 0; i < nbr_random_to_generate; i++)
{
array_random[i] = rnd.Next(obj_sqlRes.nbr_cards); // generate an array of x (nbr_random_to_generate), with the count of cards as limit
}
return array_random;
}
}
class c_Hand
{
// ATTRIBUTES
int nbr_in_hand;
// METHODS
public void HandGeneration(int a)
{
int a;
c_ConnectionMySQL countCards = new c_ConnectionMySQL();
countCards.count_cards_DB();
c_card hand = new c_card();
c_random rnd = new c_random();
rnd.generate_random();
for (int i = 0; i < 2; i++)
{
/*/
}
}
}
You can assign the return of generate_random() to a variable when it is called.
int[] array = rnd.generate_random();
I am looking for a function that will return a seed of C# Random class based on the first two int numbers produced by Random.Next(). I would like to avoid brute force (this is what I tried). Essentially, I am looking for a reverse function for this code, that is not based on brute force
using System;
public class Program
{
public static void Main()
{
int seed = 0;
Random rnd = new Random(seed);
Console.WriteLine($"Seed: {seed}");
Console.WriteLine($"Rnd1: {rnd.Next()}");
Console.WriteLine($"Rnd2: {rnd.Next()}");
}
}
Which prints out
Seed: 0
Rnd1: 1559595546
Rnd2: 1755192844
Is there a fast way to obtain Seed given Rnd1 and Rnd2?
Hi one possible to get the seed, but without rnd1 and rnd2 would be to do the following
var tickCount = Environment.TickCount;
var random = new Random();
var seededRandom = new Random(tickCount);
for (int i = 0; i < 100000000; i++)
{
// Does not enter the if case at any point.
if (random.Next() != seededRandom.Next())
{
Console.WriteLine("No match");
}
}
Source: http://referencesource.microsoft.com/#mscorlib/system/random.cs,53
I am currently working on a project for driver scheduling and it's at the initial stage.
I have decided to use GA to generate optimized schedule for a driver, and as most of GA project do, the population shall be represented in binary.
e.g. if a driver is assigned two hours of task and his working duration is 9 hours, the possible population for that specific day looks like 110000000, 011000000, 001100000 and so on.
As GA's initialization, I would like to produce possible gene like 000110000 dynamically with two parameters (working duration of driver, and duty duration).
I managed to get fully random binary code in boolean list (see below) but this is not what I want to represent as the initialization.
This is the partial code which generates random binary string (technically bunch of boolean values) in a list.
private Random Rnd = new Random();
//initial data
private List<bool[]> CreateInitialData()
{
//generate 4 random genes (might be more)
return Enumerable.Range(0, 1).Select(_ =>
{
var array = new bool[GeneLength];
for(int i = 0; i < GeneLength; i++)
{
array[i] = Rnd.Next(0, 2) == 1;
}
return array;
}).ToList();
}
How could I implement the initialization function to produce the binary code which meets the requirement (driver's working hours, estimated duty duration)?
If there is a better way to represent it other than boolean list, please do suggest as well.
Based on 1 hour tasks I came up with this:
private static void Main(string[] args)
{
var genes = GetGenes(9, 2);
}
private static List<bool[]> GetGenes(int workinghours, int estimateddutyduration)
{
// get the base representation
var hours = GetHours(workinghours, estimateddutyduration);
var list = new List<bool[]>();
for (int i = 0; i < (workinghours-estimateddutyduration)+1; i++)
{
// add
list.Add(hours);
// switch
hours = SwitchArray(hours);
}
return list;
}
private static bool[] SwitchArray(bool[] array)
{
// copy the array to a list
var temp = array.ToList();
// insert the last element at the front
temp.Insert(0, temp.Last());
// remove the last
temp.RemoveAt(temp.Count-1);
// return as array
return temp.ToArray();
}
private static bool[] GetHours(int totalhours, int taskduration)
{
// initialise the list
var hours = new List<bool>(totalhours);
// fill the list for the number of working hours
for (int i = 0; i < totalhours; i++)
{
hours.Add(false);
}
// iterate for the task duration and set the hours as working
for (int i = 0; i < taskduration; i++)
{
hours[i] = true;
}
// return as array
return hours.ToArray();
}
for 9, 2 returns
110000000
011000000
001100000
000110000
000011000
000000110
000000011
for 9, 9 returns
111111111
For 9, 4 returns
111100000
011110000
001111000
000111100
000011110
000001111
This code is quite verbose and I have no doubt it can be optimized. But it's the idea I want to convey more than anything.
EDIT: If you want to display the results on the console
private static void ShowGenes(List<bool[]> genes)
{
foreach (var gene in genes)
{
foreach (var bit in gene)
{
Console.Write(bit ? "1" : "0");
}
Console.Write("\n");
}
}
I made a lottery program : http://yadi.sk/d/bBKefn9g4OC7s
Here is the whole source code : http://yadi.sk/d/rnQMfrry4O8cu
Random rnd = new Random();
int[] loto;
loto = new int[7];
for (int f = 1; f <= 6; f++) {
loto[f] = rnd.Next(1, 50); // Generating random number between 1-49
for (int h = 1; h < f; h++) {
if (loto[f] == loto[h]) { // Check with other numbers for the case of duplicate
loto[f] = rnd.Next(1, 50); // If there is a duplicate create that number again
}
}
}
This section I'm generating random 6 different numbers between 1-49
Also I'm wondering in this example, are nested loops increase the spontaneity ?
I'm getting 3-4 max, this program wrong or am I so unlucky ?
( note that : that's my first program )
For all guys trying to help me : I'm really beginner on programming(c# yesterday | c++ 3 weeks i guess), and if you guys clarify what you mean in codes it'll be great.
And please not give me extreme hard coding examples( I don't wanna quit c# )
Your method looks unsafe, as get value from Random again in the inner loop does not guarantee that it will return unduplicated value. For low value as 1-49, you can use simple random-picking algorithm like this
var numbers = new List<int>();
for (int i = 1; i <= 49; i++) {
numbers.Add(i);
}
Random r = new Random();
var loto = new int[6];
for (int f = 0; f < 6; f++) {
int idx = r.Next(0, numbers.Count);
loto[f] = numbers[idx];
numbers.RemoveAt(idx);
}
Note that this is far from optimal solution in terms of performance, but if you will run it only once in a few seconds or more so it should be fine.
I think it's correct except for the for loop declaration: remember that arrays in C# are zero-based. Thus the loop should look like this:
for (int f = 0; f < 7; f++)
or even better:
for (int f = 0; f < loto.Length; f++)
Update: I cannot comment the other answers (too less reputation), thus I have to post it here:
#Dan: only one loop is not correct as it is not allowed to have the same number twice in Loto. In his inner loop, 1342 checks if the created random number already exists, so it is not correct to leave it out.
#James: As 1342 just started programming, it is not necessary to use a static field in my opinion. I guess that he or she has his whole code in the Main method so there is no benefit using a static variable.
There are a few issues here - you've got one too many loops for a start, and no comments.
See this (over-commented) example below:
// This is static so we don't recreate it every time.
private static Random _rnd;
static void Main(string[] args)
{
_rnd = new Random();
// You can declare and initialise a variable in one statement.
// In this case you want the array size to be 6, not 7!
Int32[] lotoNumbers = new Int32[6];
// Generate 10 sets of 6 random numbers
for (int i = 0; i < 10; i++)
{
// Use a meaningful name for your iteration variable
// In this case I used 'idx' as in 'index'
// Arrays in c# are 0-based, so your lotto array has
// 6 elements - [0] to [5]
for (Int32 idx = 0; idx < 6; idx++)
{
// Keep looping until we have a unique number
int proposedNumber;
do
{
proposedNumber = _rnd.Next(1, 50);
} while (lotoNumbers.Contains(proposedNumber));
// Assign the unique proposed number to your array
lotoNumbers[idx] = proposedNumber;
}
}
}
You should end up with a 6 element long array with 6 random numbers between 1 and 50 in it.
Hope that helps!
Edit:
It's also well worth taking note of James' answer - if you're doing the above in a loop, you'll get the same values every time from Random, due to how the seed is used. Using a static version of Random will give much better results.
You don't want to keep re-creating a new instance of Random each time, that's the likely cause of why you keep getting similar values each time. The better approach is to create a static instance of Random and use that across your entire app - this should give you more realistic results e.g.
using System.Collections.Generic;
using System.Linq;
...
static readonly Random rand = new Random();
...
List<int> lottoNumbers = new List<int>(6);
int drawnNumber = -1;
for (int i = 0; i < lottoNumbers.Count; i++) {
do
{
drawnNumber = rand.Next(1, 50); // generate random number
}
while (lottoNumbers.Contains(drawnNumber)) // keep generating random numbers until we get one which hasn't already been drawn
lottoNumbers[i] = drawnNumber; // set the lotto number
}
// print results
foreach (var n in lottoNumbers)
Console.WriteLine(n);
For easily testing it, I have left the console logs and static void main for you.
You do not need two iterations for this. Also - arrays are 0 based, so either f has to be equal to 0, or less than 7. I went with equal 0 below.
I have created a recursive method which creates a new value and checks if the array contains the value. If it does not contain it, it adds it. But if it does contain it, the method calls itself to find a new value. It will continue to do this until a new value is found.
Recursive methods are methods which call themselves. Don't try and fill an array with an index bigger than 50 with this, as you will get an endless loop.
private static readonly Random Rnd = new Random();
static void Main(string[] args)
{
var loto = new int[7];
for (int f = 0; f <= 6; f++)
{
var randomValue = GetRandomNumberNotInArr(loto);
Console.WriteLine(randomValue);
loto[f] = randomValue;
}
Console.Read();
}
/// <summary>
/// Finds a new random value to insert into arr. If arr already contains this another
///random value will be found.
/// </summary>
/// <param name="arr">arr with already found values</param>
/// <returns></returns>
private static int GetRandomNumberNotInArr(int[] arr)
{
var next = Rnd.Next(1, 50);
return !arr.Contains(next) ? next : GetRandomNumberNotInArr(arr);
}
I can see that you are trying to simulate drawing 6 lottery numbers between 1 and 50.
Your code has some logic errors, but rather than fixing it I'm going to suggest doing it a different way.
There are several ways to approach this; a common one is this:
Create an empty collection of numbers.
while there aren't enough numbers in the collection
let randomNumber = new random number in the appropriate range
if (randomNumber isn't already in the collection)
add randomNumber to the collection
But there's another approach which scales nicely, so I'll demonstrate this one (someone else will probably already have written about the other approach):
Add to a collection all the numbers you want to choose from
Randomly rearrange (shuffle) the numbers in the collection
Draw the required number of items from the collection
This is pretty much what happens in a real-life lottery.
To shuffle a collection we can use the Fisher-Yates Shuffle. Here's an implementation:
/// <summary>Used to shuffle collections.</summary>
public class Shuffler
{
/// <summary>Shuffles the specified array.</summary>
/// <typeparam name="T">The type of the array elements.</typeparam>
/// <param name="array">The array to shuffle.</param>
public void Shuffle<T>(IList<T> array)
{
for (int n = array.Count; n > 1;)
{
int k = _rng.Next(n);
--n;
T temp = array[n];
array[n] = array[k];
array[k] = temp;
}
}
private readonly Random _rng = new Random();
}
Here's a full compilable example. I've avoided using Linq in this example because I don't want to confuse you!
using System;
using System.Collections.Generic;
namespace Demo
{
public static class Program
{
private static void Main()
{
int[] lotoDraw = createDraw();
Shuffler shuffler = new Shuffler();
shuffler.Shuffle(lotoDraw); // Now they are randomly ordered.
// We want 6 numbers, so we just draw the first 6:
int[] loto = draw(lotoDraw, 6);
// Print them out;
foreach (int ball in loto)
Console.WriteLine(ball);
}
private static int[] draw(int[] bag, int n) // Draws the first n items
{ // from the bag
int[] result = new int[n];
for (int i = 0; i < n; ++i)
result[i] = bag[i];
return result;
}
private static int[] createDraw() // Creates a collection of numbers
{ // from 1..50 to draw from.
int[] result = new int[50];
for (int i = 0; i < 50; ++i)
result[i] = i + 1;
return result;
}
}
public class Shuffler
{
public void Shuffle<T>(IList<T> list)
{
for (int n = list.Count; n > 1; )
{
int k = _rng.Next(n);
--n;
T temp = list[n];
list[n] = list[k];
list[k] = temp;
}
}
private readonly Random _rng = new Random();
}
}