Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

10 random numbers from 0 to 20

0 views
Skip to first unread message

Luigi

unread,
Jun 15, 2010, 6:10:16 AM6/15/10
to
Hello,
how can I write a method that returns me 10 random numbers from 0 to 20
(included), without repetitions?

Thanks a lot.

Luigi

Soren 'theDiver' Reinke

unread,
Jun 15, 2010, 7:18:53 AM6/15/10
to
On 15-06-2010 12:10, Luigi wrote:
> Hello,
> how can I write a method that returns me 10 random numbers from 0 to 20
> (included), without repetitions?

If you don't want repetitions they are not real random numbers.

You could get the number '15' 10 times in a row, it is possible, but
highly unlikely.


--
Med venlig hilsen / Best regards
Søren Reinke, IDCS #505926, TDI Trimix
www.Dykkeren.dk
Dive blog with a large gallery

Luigi

unread,
Jun 15, 2010, 9:03:53 AM6/15/10
to
I'm trying in this way:

int[] result = new int[10];
Random random = new Random();
int adding;

for (var i = 0; i < 10; i++)
{
adding = random.Next(1, 20);
if (!result.Contains(adding))
result[i] = adding;
}

but it seems that give me also the number zero.

Luigi

Luigi

unread,
Jun 15, 2010, 9:03:47 AM6/15/10
to
Maybe this one is correct:

int[] result = new int[10];
Random random = new Random();
int adding;

for (var i = 0; i < 10; i++)
{
adding = random.Next(1, 20);

if (!result.Contains(adding) || !result.Contains(0))
result[i] = adding;
else
{
i--;
continue;
}
}

Luigi

Matt

unread,
Jun 15, 2010, 10:33:46 AM6/15/10
to

The easiest way to do what you are trying to accomplish is to create
an array
of 20 elements, then select a random number in that range. Remove the
item
(i.e. shift them down one, so that you now have 19 elements). Find a
random
number in that range, remove it and so forth until you have the number
you want.

Matt

AA2e72E

unread,
Jun 15, 2010, 11:14:21 AM6/15/10
to

I could say 10?20 but that would more than likely mean nothing to you.
Perhaps
http://stackoverflow.com/questions/254844/random-array-using-linq-and-c might
provide another insight.

Peter Duniho

unread,
Jun 15, 2010, 11:23:27 AM6/15/10
to

Your original post states you want to also include the number zero. Do
you or don't you want zero in the output?

The correct (most efficient) way to accomplish what you want to do is to
initialize an array of numbers that is exactly the range of numbers you
want. For example, if you really do want the numbers "from 0 to 20
inclusive", then you need 21 elements, initialized starting at 0 and
ending with 20.

Whatever the range, then the next step is to "shuffle" the array. There
have been a number of discussions in this newsgroup already, which you
can review using Google Groups, or you can just look up "shuffle"
algorithms on Wikipedia. The basic idea is to select a random element
from the array to swap into the current position of the array, starting
with the first element; with each iteration, increment the current
position, and select a random element only from the range of that
position through to the end of the array.

Pete

Peter Duniho

unread,
Jun 15, 2010, 11:25:12 AM6/15/10
to
Peter Duniho wrote:
> [...]

> Whatever the range, then the next step is to "shuffle" the array. There
> have been a number of discussions in this newsgroup already, which you
> can review using Google Groups, or you can just look up "shuffle"
> algorithms on Wikipedia. The basic idea is to select a random element
> from the array to swap into the current position of the array, starting
> with the first element; with each iteration, increment the current
> position, and select a random element only from the range of that
> position through to the end of the array.

Oh, and it should go without saying, but just in case:

If you only want 10 numbers from that range, then you simply choose the
first 10 from the shuffled array.

Pete

Fred Mellender

unread,
Jun 15, 2010, 11:41:37 AM6/15/10
to
Put the integers 0-20 in a list. Shuffle it. Take the first 10 from the
list. To shuffle a list (not tested):

public static List<T> shuffledList(List<T> listToShuffle, Random rand)
{
/*
* Make a new list of elements picked from listToShuffle
* in a random order.
*/

List<T> randList = new List<T>(listToShuffle);
for (int k = randList.Count-1; k >= 0; k--)
{
int randIndx = rand.Next(k);
T temp = randList[k];
randList[k] = randList[randIndx];
randList[randIndx] = temp;
}

return randList;
}

"Luigi" <Lu...@discussions.microsoft.com> wrote in message
news:FCD10C7D-3A0B-4909...@microsoft.com...

rossum

unread,
Jun 15, 2010, 12:55:52 PM6/15/10
to

As others have said, put the numbers you want into some container or
array and shuffle.

The standard shuffling algorithm is in Knuth, Algorithm 3.4.2 P. It
is covered on Wikipedia:


http://en.wikipedia.org/wiki/Fisher–Yates_shuffle#The_modern_algorithm

The article contains Java code which should be easily convertible to
C#.

rossum

Harlan Messinger

unread,
Jun 15, 2010, 3:27:54 PM6/15/10
to
Soren 'theDiver' Reinke wrote:
> On 15-06-2010 12:10, Luigi wrote:
>> Hello,
>> how can I write a method that returns me 10 random numbers from 0 to 20
>> (included), without repetitions?
>
> If you don't want repetitions they are not real random numbers.

It isn't a set of 10 *mutually independent* random selections. It *is*
one random selection of 10, just as when you randomly select 10 people
out of an audience, you aren't selecting the same person twice.

kndg

unread,
Jun 15, 2010, 10:48:50 PM6/15/10
to

Hi Luigi,

An example,

using System;
using System.Collections.Generic;
using System.Linq;

public static class EnumerableExtensions
{
private static readonly Random random = new Random();

public static IEnumerable<T> SelectRandomItem<T>(this IEnumerable<T>
source, int total)
{
if (source == null) yield break;

T[] data = source.ToArray();

if (total < 0 || total > data.Length)
{
throw new ArgumentException();
}

for (int i = 0; i < total; i++)
{
int index = random.Next(data.Length - i);

yield return data[index];

data[index] = data[data.Length - i - 1];
}
}
}

// Usage
public class MyClass
{
public static void Main(string[] args)
{
var data = Enumerable.Range(0, 21);

foreach (var item in data.SelectRandomItem(10))
{
Console.WriteLine(item);
}
}
}

Regards.

Luigi

unread,
Jun 16, 2010, 4:52:30 AM6/16/10
to
Thanks Fred.

Luigi

Göran Andersson

unread,
Jun 17, 2010, 3:26:59 AM6/17/10
to

You can loop from the lower bound and up, and calculate the probability
for each number to be picked:

int num = 0; // 0 to 20 inclusive
int cnt = 21;
int left = 10; // how many to pick
Random rnd = new Random();
while (left > 0) {
if (rnd.Next(cnt) < left) {
Console.WriteLine(num);
left--;
}
num++;
cnt--;
}

Example:

1
5
6
7
8
11
14
17
18
19

--
Göran Andersson
_____
http://www.guffa.com

Peter Duniho

unread,
Jun 17, 2010, 11:29:45 AM6/17/10
to
Göran Andersson wrote:
> On 2010-06-15 12:10, Luigi wrote:
>> Hello,
>> how can I write a method that returns me 10 random numbers from 0 to 20
>> (included), without repetitions?
>>
>> Thanks a lot.
>>
>> Luigi
>>
>
> You can loop from the lower bound and up, and calculate the probability
> for each number to be picked:

But that only works if the order doesn't need to be random. Which, when
dealing with randomized data is not usually the case.

To get the order random, you still wind up needing to shuffle the
result. So you might as well just shuffle the entire selection range
and then just pick the first N elements of the shuffled range.

Performance-wise, if there is a very large disparity between the range
of possible numbers and the actual number of numbers one needs, there
might be some benefit to the "pick first, shuffle later" approach,
because the memory required would only be for the number of numbers
picked, rather than the entire selection range.

But you'd have to have a pretty large selection range and a pretty small
output range to make a two-pass algorithm worth bothering with.
Otherwise, the memory performance won't wind up mattering at all, and
the two-pass algorithm would actually be slower because it has more
calls to the Random class, negating any potential performance benefit
that might come from lower memory usage.

Personally, I'd go with the simpler "shuffle and copy", and only look
for alternatives if for some reason that proved to be too inefficient.
And for sure, picking 10 random numbers from the range of 0 to 20 the
"shuffle and copy" approach is not too inefficient. :)

Pete

0 new messages