How to generate Random numbers without repeating any numbers in the given target like(1-5000) there should be no reparation and I should be able to get 5000 randomized numbers. I should be able to run the randomized as many times as the user wants,How to do with C#
For Sample Target is (1-10) No of times to run =2
First run: 5,4,6,8,3,1,2,0,7,10
second run 6,3,5,8,4,2,0,1,10,7
Like this I should be able to get the results as many times as I run..
Answer
As others have pointed out, what you're looking for is effectively a shuffled deck of cards. Every card (in this case, a unique number) is present exactly once, in a randomized order. By drawing cards from the deck one at a time, you create a psuedorandom number string with no repeats.
(Obviously, once you've exhausted the deck, you'll need to either reuse it or reshuffle it to generate the next number)
A fast way to do this is with a Fisher-Yates shuffle, also commonly called a Knuth Shuffle:
// Prepare a deck of sequential numbers from min to max:
int count = max - min + 1
int[] deck = new int[count];
for(int i = 0; i < count; i++)
{
deck[i] = min + i;
}
// Shuffle it:
for(int i = count - 1; i > 1; i--)
{
// Pick an entry no later in the deck, or i itself.
int j = Random.Range(0, i + 1);
// Swap the order of the two entries.
int swap = deck[i];
deck[i] = deck[j];
deck[j] = swap;
}
// Now deck[] contains all numbers from min to max
// in a random order with no duplicates.
This can also be combined into one pass:
int count = max - min + 1;
int[] deck = new int[count];
for(int i = 0; i < count; i++)
{
int j = Random.Range(0, i + 1);
deck[i] = deck[j];
deck[j] = min + i;
}
One neat trick is that you don't even have to shuffle all at once for this. You can randomize as you go, at a constant cost per card drawn:
[System.Serializable]
public class Deck {
[SerializeField]
T[] deck;
// Tracks a partition between the deck & discard pile.
// All entries at i < remaining are in the undrawn deck,
// remaining <= i < deck.Length are in the discard pile.
int remaining = 0;
public T Draw() {
// If we ran out of cards, shuffle the discards to make a new deck.
if(remaining == 0)
remaining = deck.Length;
// Pick a card at random from the remaining deck.
int chosenIndex = Random.Range(0, remaining);
T chosenItem = deck[chosenIndex];
// Remove the card from the remaining deck and place it at the
// top of the growing discard pile.
remaining--;
deck[chosenIndex] = deck[remaining];
deck[remaining] = chosenItem;
return chosenItem;
}
}
No comments:
Post a Comment