Click here to Skip to main content
15,881,588 members
Please Sign up or sign in to vote.
1.00/5 (8 votes)
How to get random unique numbers between any 2 numbers in c# without storing and checking the previous output?

Please see the below link for an example:-
https://adf.ly/msz2d[^]


Thanks in advance
Posted
Updated 14-May-14 0:14am
v3
Comments
phil.o 14-May-14 5:34am    
Unique amongst what?
CHill60 14-May-14 8:27am    
Perhaps if you explained what you are really trying to achieve it would help. You have to store some data *somewhere* to get the uniqueness if you want integers. And thanks a bunch for sending me off to a betting advertisement - not suitable for work environment!! The link was pointless anyway - you could have just put some numbers into your post.
What are you actually trying to achieve and why?

Hi Agen_Spock,

It seems you are not getting it (concluded from your variouse comments)...

If you don't store which numbers (of any set you wish your random numbers to come from e.g. 1-50) are already used, you can not know if the number is unique - Can you agree on that?

So your whole "requirenment" "without storing values and checking..." is wrong. It can't be done - this is a pure logical contradiction and has nothing to do with programming in general.

Yes there are algorithms which will make it very unlikely to produce the same number again (e.g. GUIDs).

So a valid solution could be: Pre-Generate a "set" of numbers - like playing cards and pick them randomly. If you try this you have to think about what happens if you "run out" of numbers/cards.

Another (may be inefficient) approach could be just to store all the generated numbers from past calls and check if the new number is contained - then retry if number was used - again what happens if there are no more "free" numbers in range...

So you see, just insisting on a "not so well thought" requirement won't solve your problem. Maybe you tell us what you want to achieve in the end and what is your real problem?

Kind regards

Johannes
 
Share this answer
 
As other as mentionned, it is essentially impossible to achieve that. Either, you have to use a know sequence that happen to be unique (in that case you still need to know where you are).

It would be possible to do it wihout storing previous values if you use a seed for the random generator and an index for the number of call so that you can regenerate old values and check if the new value is unique.

In that case, your performance would drop a lot for long sequences (thousand of items) but it will use less memory.

But you still have to check previous output.

Well, you can generate sequence that are not so random using permutations with fixed offset so that it is known that you will get all numbers but result won't be so random.

For example, if you want number betwen 0 and 50, you can do something like adding 7 at each step and remove 50 when it is above 50.

0, 7, 14, 21, 28, 35, 42, 49, 6, 13, 20...1, 8, 15, 22, 29, 36, 43, 50 and at that point, the sequence will start over at 7 (or 0 if you uses modulo when above 50 instead of substraction).

But in general term it is impossible to achive whant you ask.
 
Share this answer
 
Technically, there is a Next method on the Random class which allows you to specify bounds for your random number.
Here: Random.Next Method (Int32, Int32)[^]

Beware!

- The first parameter (minValue) is inclusive, whereas the second (maxValue) is exclusive.
It means that, if you want a number between 1 and 50, you would have to write:
C#
Random r = new Random();
int randomNumber = r.Next(1, 51);


There subsists an issue, though: this will give you a random number, but will not assure you its uniqueness in any way.
For that, there still have been answered to you that the Guid struct is much more appropriate.
More informations here: Guid Structure[^]

Hope this helps.
 
Share this answer
 
Comments
agent_kruger 14-May-14 6:07am    
sir, i told that unique number should only be shown. But your above example shows duplicate numbers too.
phil.o 14-May-14 6:13am    
If you do not hold informations about numbers that already have been drawn, you cannot be sure of uniqueness.<br>
So, re-reading your question: No, it is not possible without storing values that already have been drawn.
Guid creates random values but you can't set a range for them and they won't be numeric.

Not an efficient way, also causes extra memory consumption but it may be useful if your range is relatively narrow.

Create a list of int that starts with your small number till your big number.


C#
int rangeStart = 20;
int rangeEnd = 100;
var list = Enumerable.Range(rangeStart, rangeEnd - rangeStart + 1).ToList();

//u can shuffle list with an extension method

public static void Shuffle<t>(this IList<t> list)  
{  
    Random rng = new Random();  
    int n = list.Count;  
    while (n > 1) {  
        n--;  
        int k = rng.Next(n + 1);  
        T value = list[k];  
        list[k] = list[n];  
        list[n] = value;  
    }  
}
</t></t>


Then shuffle list and pull element from top when you need.
 
Share this answer
 
v2
Comments
agent_kruger 14-May-14 6:34am    
no sir, as mentioned in the question "without storing values and checking the previous outputs"
CHill60 14-May-14 13:20pm    
Not sure why the '1' vote was given - works within the constraints the OP said .. after all, you're not storing the previous results you're only storing the available population of numbers that can be used :-). Upvoted for balance.
Emre Ataseven 14-May-14 13:28pm    
thank you :)
Short answer: you cannot.
If you can, use a GUID for that.
 
Share this answer
 
Comments
agent_kruger 14-May-14 5:39am    
sir, can you explain what is GUID?
Prasad Avunoori 14-May-14 5:45am    
Use below line to get random number between 1 and 50
Console.WriteLine(r.Next(1,50));
Emre Ataseven 14-May-14 6:00am    
"without storing and checking the previous output?" this part is bold and probably important.
Prasad Avunoori 14-May-14 6:05am    
This is highly impossible, i think.
agent_kruger 14-May-14 6:08am    
sir, that is why i am asking here.
XML
namespace ConsoleEnum
{
    public class host
    {
        [STAThread]
        static void Main(string[] args)
        {
            List<int> getrandom1 = Enumerable.Range(0, 100).ToList<int>();
            for (int i =0;i<100;i++)
            Console.WriteLine("Unique Random Number - {0}",(int)GetRandom(ref getrandom1));
        }
    }
     public  static int GetRandom(ref List<int> x)
    {
        int RandomIndex = new Random().Next(0, x.Count - 1);
        int RandomValue = x[RandomIndex];
        x.RemoveAt(RandomIndex);
        return RandomValue;
    }
}
 
Share this answer
 
v4
Comments
CHill60 14-May-14 8:21am    
Does not guarantee uniqueness
 
Share this answer
 
Comments
agent_kruger 14-May-14 6:09am    
sir, i told that unique number should only be shown. But your above example shows duplicate numbers too.
C#
static void Main(string[] args)
  {

      var r = new Random();

      Console.WriteLine(r.Next(50));
      Console.ReadLine();
  }
 
Share this answer
 
v2
Comments
agent_kruger 14-May-14 6:09am    
sir, i told that unique number should only be shown. But your above example shows duplicate numbers too.
Depending on your definition of random, this could work. To make it more random instead of using a fixed group size it could be randomly evalutated each pass through the loop.

C#
int[] GenerateRandom(int minimum, int maximum, int count)
{
    int[] ret = new int[count];
    Random rand = new Random();
    double groupSize = ((maximum - minimum) / count);
    if (groupSize < 1) throw new ArgumentOutOfRangeException("count", "Count is too large for given range.");
    for (int i = 0; i < count; ++i)
    {
        ret[i] = rand.Next((int)(i * groupSize)+minimum, (int)((i + 1) * groupSize+minimum));
    }
    return ret;
}
 
Share this answer
 
Comments
agent_kruger 14-May-14 10:28am    
sir, can you explain what does this code actually do?
Member 10272815 14-May-14 10:35am    
Instead of taking a random value between min and max, it splits the range up and selects a number at random from the sub range. So if your min is 0, max is 10 and you want to select 2 numbers the first number will be a random value between 0 and 4 inclusive, and the second will be between 5 and 9 inclusive.

If you selected 10 numbers between 0 and 10, you'd get an array populated with every value from 0 to 9.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900