471,319 Members | 1,411 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,319 software developers and data experts.

Array.Sort exception when randomizing an Array

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]'."
Nov 27 '05 #1
6 7741
On Sun, 27 Nov 2005 15:31:13 +0100, "Paul van Brenk"
<pa************@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
Nov 27 '05 #2
mmh, interesting... I get the exception under 200 iterations. I'll try it on
a different machine tomorrow.

thanks anyway,

Paul

"Christoph Nahr" <ch************@kynosarges.de> wrote in message
news:91********************************@4ax.com...
On Sun, 27 Nov 2005 15:31:13 +0100, "Paul van Brenk"
<pa************@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

Nov 27 '05 #3
> 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/
Nov 27 '05 #4

"Anders Norås" <an**********@objectware.no> wrote in message
news:66*************************@news.microsoft.co m...
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.

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

Nov 27 '05 #5
>> 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);
}

Regards,
Anders Norås
http://dotnetjunkies.com/weblog/anoras/
Nov 28 '05 #6
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" <an**********@objectware.no> wrote in message
news:66*************************@news.microsoft.co m...
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);
}

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

Nov 28 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

21 posts views Thread by Jeff Thies | last post: by
4 posts views Thread by bg_ie | last post: by
21 posts views Thread by yeti349 | last post: by
5 posts views Thread by muskie | last post: by
2 posts views Thread by yeshello54 | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.