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

Array.Sort exception when randomizing an Array

2 views
Skip to first unread message

Paul van Brenk

unread,
Nov 27, 2005, 9:31:13 AM11/27/05
to
When you run the Shuffle[0] method often enough it will throw exception[1].
And I can't figure out why.

Anybody?

Paul van Brenk

[0] the code:
static void Shuffle(){
int[] ints = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
System.Random rand = new System.Random((int)DateTime.Now.Ticks);
Array.Sort(ints, delegate(int x, int y){
// since you're not allowed to return anything else than 0 for
x.CompareTo(x)
if (x == y) {
return 0;
}
return rand.Next(-1,2);
}
);
}

[1] the exception:
exc.Message "IComparer (or the IComparable methods it relies upon) did not
return zero when Array.Sort called x. CompareTo(x). x: '5' x's type:
'Int32' The IComparer: 'System.Array+FunctorComparer`1[System.Int32]'."


Christoph Nahr

unread,
Nov 27, 2005, 9:53:06 AM11/27/05
to
On Sun, 27 Nov 2005 15:31:13 +0100, "Paul van Brenk"
<paul.va...@nospam.tamtam.nl> wrote:

>When you run the Shuffle[0] method often enough it will throw exception[1].
>And I can't figure out why.

Neither can I, but I don't get the exception either. How often is
"often enough?" I ran your method ca. 100,000 times with no luck.
--
http://www.kynosarges.de

Paul van Brenk

unread,
Nov 27, 2005, 10:06:09 AM11/27/05
to
mmh, interesting... I get the exception under 200 iterations. I'll try it on
a different machine tomorrow.

thanks anyway,

Paul

"Christoph Nahr" <christo...@kynosarges.de> wrote in message
news:91ijo1tr7e8pe2i5p...@4ax.com...

Anders Norås

unread,
Nov 27, 2005, 3:09:39 PM11/27/05
to
> When you run the Shuffle[0] method often enough it will throw
> exception[1]. And I can't figure out why.
Yes. Since you're making a random decision on wheter int x should be sorted
before or after int y you'll get an exception whenever you reach the last
element in the array and your delegate returns something different from 0.
This doesn't happen every time you call the Shuffle method, and it is less
likely to happen the faster your computer is because the random generator
relies on the system clock to generate "random" number. If you place a Thread.Sleep(1)
within the loop calling your Shuffle method you'll slow the processing down,
and you'll be more likely to get an exception.

The way you're sorting the array is not only error prone, it is also inefficient.
The sort delegate will be called more than ten times for each call to the
Shuffle method, since the method is randomized, the exact number cannot be
predicted, but a quick test I wrote had an average of 35 calls for 200 iterations.

A better way to get a randomize int array with the numbers between 1-10 is
shown below:
Random r=new Random();
int[] numbers=new int[10];
for (int i=0; i<10; i++)
{
numbers[i]=r.Next(1,10);
}

Regards,
Anders Norås
http://dotnetjunkies.com/weblog/anoras/


Paul van Brenk

unread,
Nov 27, 2005, 6:02:36 PM11/27/05
to

"Anders Norås" <anders...@objectware.no> wrote in message
news:6658940788ec8...@news.microsoft.com...

>> When you run the Shuffle[0] method often enough it will throw
>> exception[1]. And I can't figure out why.
> Yes. Since you're making a random decision on wheter int x should be
> sorted before or after int y you'll get an exception whenever you reach
> the last element in the array and your delegate returns something
> different from 0.

You sure? If I shortcircuit the array with "return 1;" everything works as
expected.

> This doesn't happen every time you call the Shuffle method, and it is less
> likely to happen the faster your computer is because the random generator
> relies on the system clock to generate "random" number. If you place a
> Thread.Sleep(1) within the loop calling your Shuffle method you'll slow
> the processing down, and you'll be more likely to get an exception.
>
> The way you're sorting the array is not only error prone, it is also
> inefficient. The sort delegate will be called more than ten times for each
> call to the Shuffle method, since the method is randomized, the exact
> number cannot be predicted, but a quick test I wrote had an average of 35
> calls for 200 iterations.
>
> A better way to get a randomize int array with the numbers between 1-10 is
> shown below:
> Random r=new Random();
> int[] numbers=new int[10];
> for (int i=0; i<10; i++)
> {
> numbers[i]=r.Next(1,10);
> }

this would give me an array of 10 random integeres not an array of integers
0-9 in random order.

Anders Norås

unread,
Nov 28, 2005, 4:15:07 AM11/28/05
to
>> A better way to get a randomize int array with the numbers between
>> 1-10 is
>> shown below:
>> Random r=new Random();
>> int[] numbers=new int[10];
>> for (int i=0; i<10; i++)
>> {
>> numbers[i]=r.Next(1,10);
>> }
> this would give me an array of 10 random integeres not an array of
> integers 0-9 in random order.

Ops. Sorry Paul, I cut and pasted the wrong code snippet. Below is the code
I intended to post.
List<int> numbers=new List<int>(new int[] { 1,2,3,4,5,6,7,8,9,10 });
List<int> randomizedNumbers=new List<int>();
Random r=new Random();
while (numbers.Count>0)
{
int i=r.Next(0,numbers.Count);
randomizedNumbers.Add(numbers[i]);
numbers.RemoveAt(i);

Paul van Brenk

unread,
Nov 28, 2005, 7:40:25 AM11/28/05
to
thanks,

I used this method from the powercollections, which is a little more
generic:

public static T[] RandomShuffle<T>(IEnumerable<T> collection, Random
randomGenerator)

{

// We have to copy all items anyway, and there isn't a way to produce the
items

// on the fly that is linear. So copying to an array and shuffling it is an
efficient as we can get.

if (collection == null)

throw new ArgumentNullException("collection");

if (randomGenerator == null)

throw new ArgumentNullException("randomGenerator");

T[] array = Algorithms.ToArray(collection);

int count = array.Length;

for (int i = count - 1; i >= 1; --i) {

// Pick an random number 0 through i inclusive.

int j = randomGenerator.Next(i + 1);

// Swap array[i] and array[j]

T temp = array[i];

array[i] = array[j];

array[j] = temp;

}

return array;

}

"Anders Norås" <anders...@objectware.no> wrote in message

news:6658940792238...@news.microsoft.com...

0 new messages