I've searched for a while and been struggling to find this, I'm trying to generate several random, unique numbers is C#. I'm using System.Random
, and I'm using a DateTime.Now.Ticks
seed:
public Random a = new Random(DateTime.Now.Ticks.GetHashCode());
private void NewNumber()
{
MyNumber = a.Next(0, 10);
}
I'm calling NewNumber()
regularly, but the problem is I often get repeated numbers. Some people suggested because I was declaring the random every time I did it, it would not produce a random number, so I put the declaration outside my function. Any suggestions or better ways than using System.Random
? Thank you
It's may be a little bit late, but here is more suitable code, for example when you need to use loops:
List<int> genered = new List<int>();
Random rnd = new Random();
for(int x = 0; x < files.Length; x++)
{
int value = rnd.Next(0, files.Length - 1);
while (genered.Contains(value))
{
value = rnd.Next(0, files.Length - 1);
}
genered.Add(value);
returnFiles[x] = files[value];
}
This is a unity only answer:
Check this ready-to-use method: Give in a range & count of number you want to get.
public static int[] getUniqueRandomArray(int min, int max, int count) {
int[] result = new int[count];
List<int> numbersInOrder = new List<int>();
for (var x = min; x < max; x++) {
numbersInOrder.Add(x);
}
for (var x = 0; x < count; x++) {
var randomIndex = UnityEngine.Random.Range(0, numbersInOrder.Count);
result[x] = numbersInOrder[randomIndex];
numbersInOrder.RemoveAt(randomIndex);
}
return result;
}
You can use basic Random Functions of C#
Random ran = new Random();
int randomno = ran.Next(0,100);
you can now use the value in the randomno in anything you want but keep in mind that this will generate a random number between 0
and 100
Only and you can extend that to any figure.
Try this:
private void NewNumber()
{
Random a = new Random(Guid.newGuid().GetHashCode());
MyNumber = a.Next(0, 10);
}
Some Explnations:
Guid
: base on here : Represents a globally unique identifier (GUID)
Guid.newGuid()
produces a unique identifier like "936DA01F-9ABD-4d9d-80C7-02AF85C822A8"
and it will be unique in all over the universe base on here
Hash code here produce a unique integer from our unique identifier
so Guid.newGuid().GetHashCode()
gives us a unique number and the random class will produce real random numbers throw this
Sample: https://rextester.com/ODOXS63244
generated ten random numbers with this approach with result of:
-1541116401
7
-1936409663
3
-804754459
8
1403945863
3
1287118327
1
2112146189
1
1461188435
9
-752742620
4
-175247185
4
1666734552
7
we got two 1
s next to each other, but the hash codes do not same.
unique random number from 0 to 9
int sum = 0;
int[] hue = new int[10];
for (int i = 0; i < 10; i++)
{
int m;
do
{
m = rand.Next(0, 10);
} while (hue.Contains(m) && sum != 45);
if (!hue.Contains(m))
{
hue[i] = m;
sum = sum + m;
}
}
This console app will let you shuffle the alphabet five times with different orders.
using System;
using System.Linq;
namespace Shuffle
{
class Program
{
static Random rnd = new Random();
static void Main(string[] args)
{
var alphabet = new string[] { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" };
Console.WriteLine("Alphabet : {0}", string.Join(",", alphabet));
for (int i = 0; i < 5; i++)
{
var shuffledAlphabet = GetShuffledAlphabet(alphabet);
Console.WriteLine("SHUFFLE {0}: {1}", i, string.Join(",", shuffledAlphabet));
}
}
static string[] GetShuffledAlphabet(string[] arr)
{
int?[] uniqueNumbers = new int?[arr.Length];
string[] shuffledAlphabet = new string[arr.Length];
for (int i = 0; i < arr.Length; i++)
{
int uniqueNumber = GenerateUniqueNumber(uniqueNumberArrays);
uniqueNumberArrays[i] = uniqueNumber;
newArray[i] = arr[uniqueNumber];
}
return shuffledAlphabet;
}
static int GenerateUniqueNumber(int?[] uniqueNumbers)
{
int number = rnd.Next(uniqueNumbers.Length);
if (!uniqueNumbers.Any(r => r == number))
{
return number;
}
return GenerateUniqueNumber(uniqueNumbers);
}
}
}
I'm posting a correct implementation of a shuffle algorithm, since the other one posted here doesn't produce a uniform shuffle.
As the other answer states, for small numbers of values to be randomized, you can simply fill an array with those values, shuffle the array, and then use however many of the values that you want.
The following is an implementation of the Fisher-Yates Shuffle (aka the Knuth Shuffle). (Read the "implementation errors" section of that link (search for "always selecting j from the entire range of valid array indices on every iteration") to see some discussion about what is wrong with the other implementation posted here.)
using System;
using System.Collections.Generic;
namespace ConsoleApplication2
{
static class Program
{
static void Main(string[] args)
{
Shuffler shuffler = new Shuffler();
List<int> list = new List<int>{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };
shuffler.Shuffle(list);
foreach (int value in list)
{
Console.WriteLine(value);
}
}
}
/// <summary>Used to shuffle collections.</summary>
public class Shuffler
{
/// <summary>Creates the shuffler with a <see cref="MersenneTwister"/> as the random number generator.</summary>
public Shuffler()
{
_rng = new Random();
}
/// <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 System.Random _rng;
}
}
I noted that the accepted answer keeps adding int to the list and keeps checking them with if (!randomList.Contains(MyNumber))
and I think this doesn't scale well, especially if you keep asking for new numbers.
I would do the opposite.
This would require a slightly bit more time at startup, but will scale much much better.
public class RandomIntGenerator
{
public Random a = new Random();
private List<int> _validNumbers;
private RandomIntGenerator(int desiredAmount, int start = 0)
{
_validNumbers = new List<int>();
for (int i = 0; i < desiredAmount; i++)
_validNumbers.Add(i + start);
}
private int GetRandomInt()
{
if (_validNumbers.Count == 0)
{
//you could throw an exception here
return -1;
}
else
{
var nextIndex = a.Next(0, _validNumbers.Count - 1);
var number = _validNumbers[nextIndex];
_validNumbers.RemoveAt(nextIndex);
return number;
}
}
}
You might try shuffling an array of possible ints if your range is only 0 through 9. This adds the benefit of avoiding any conflicts in the number generation.
var nums = Enumerable.Range(0, 10).ToArray();
var rnd = new Random();
// Shuffle the array
for (int i = 0;i < nums.Length;++i)
{
int randomIndex = rnd.Next(nums.Length);
int temp = nums[randomIndex];
nums[randomIndex] = nums[i];
nums[i] = temp;
}
// Now your array is randomized and you can simply print them in order
for (int i = 0;i < nums.Length;++i)
Console.WriteLine(nums[i]);
You could also use a dataTable storing each random value, then simply perform the random method while != values in the dataColumn
hi here i posted one video ,and it explains how to generate unique random number
public List<int> random_generator(){
Random random = new Random();
List<int> random_container = new List<int>;
do{
int random_number = random.next(10);
if(!random_container.contains(random_number){
random_container.add(random_number)
}
}
while(random_container.count!=10);
return random_container;
}
here ,,, in random container you will get non repeated 10 numbers starts from 0 to 9(10 numbers) as random.. thank you........
Depending on what you are really after you can do something like this:
using System;
using System.Collections.Generic;
using System.Linq;
namespace SO14473321
{
class Program
{
static void Main()
{
UniqueRandom u = new UniqueRandom(Enumerable.Range(1,10));
for (int i = 0; i < 10; i++)
{
Console.Write("{0} ",u.Next());
}
}
}
class UniqueRandom
{
private readonly List<int> _currentList;
private readonly Random _random = new Random();
public UniqueRandom(IEnumerable<int> seed)
{
_currentList = new List<int>(seed);
}
public int Next()
{
if (_currentList.Count == 0)
{
throw new ApplicationException("No more numbers");
}
int i = _random.Next(_currentList.Count);
int result = _currentList[i];
_currentList.RemoveAt(i);
return result;
}
}
}
randomNumber function return unqiue integer value between 0 to 100000
bool check[] = new bool[100001]; Random r = new Random(); public int randomNumber() { int num = r.Next(0,100000); while(check[num] == true) { num = r.Next(0,100000); } check[num] = true; return num; }
And here my version of finding N random unique numbers using HashSet. Looks pretty simple, since HashSet can contain only different items. It's interesting - would it be faster then using List or Shuffler?
using System;
using System.Collections.Generic;
namespace ConsoleApplication1
{
class RnDHash
{
static void Main()
{
HashSet<int> rndIndexes = new HashSet<int>();
Random rng = new Random();
int maxNumber;
Console.Write("Please input Max number: ");
maxNumber = int.Parse(Console.ReadLine());
int iter = 0;
while (rndIndexes.Count != maxNumber)
{
int index = rng.Next(maxNumber);
rndIndexes.Add(index);
iter++;
}
Console.WriteLine("Random numbers were found in {0} iterations: ", iter);
foreach (int num in rndIndexes)
{
Console.WriteLine(num);
}
Console.ReadKey();
}
}
}
Same as @Habib's answer, but as a function:
List<int> randomList = new List<int>();
int UniqueRandomInt(int min, int max)
{
var rand = new Random();
int myNumber;
do
{
myNumber = rand.Next(min, max);
} while (randomList.Contains(myNumber));
return myNumber;
}
If randomList is a class property, UniqueRandomInt will return unique integers in the context of the same instance of that class. If you want it to be unique globally, you will need to make randomList static.
NOTE, I dont recommend this :). Here's a "oneliner" as well:
//This code generates numbers between 1 - 100 and then takes 10 of them.
var result = Enumerable.Range(1,101).OrderBy(g => Guid.NewGuid()).Take(10).ToArray();
Source: Stackoverflow.com