0

Below snippet shuffle numbers And changes sequence of numbers in every execution:

Enumerable.Range(1, 1000).OrderBy(r => Guid.NewGuid()).ToList();

BUT I want shuffle numbers and generate a same sequence of numbers in every execution of application?

user197508
  • 1,282
  • 2
  • 18
  • 31
  • 5
    Doesn't that defeat the purpose of randomly arranging the numbers? –  Jun 12 '17 at 18:28
  • Generate them once and hard-code the result. Or just use `Enumerable.Range(1, 1000).ToArray()`. That's a plausible, albeit unlikely, random ordering. – 15ee8f99-57ff-4f92-890c-b56153 Jun 12 '17 at 18:29
  • 2
    Don't use GUIDs to shuffle. Use a `Random` object for shuffling and initialize the object with the same seed. – itsme86 Jun 12 '17 at 18:30
  • You can generate a new `Random` class object and initialize it with a hard-coded seed value. Doing this will guarantee the same random numbers each execution. See here: https://msdn.microsoft.com/en-us/library/ctssatww(v=vs.110).aspx – Icemanind Jun 12 '17 at 18:52

2 Answers2

5

It is more efficient to use an algorithm like Fisher-Yates shuffle to reorder the items. The run-time complexity of OrderBy is O(N log N) while Fisher-Yates shuffle is O(N).

Also, to provide random numbers you should use the Random class, not Guid.NewGuid which serves a completely different purpose and just happens to create something that is random (at a higher cost).

I prefer to implement the shuffle as an extension method:

public static class ListExtensions
{
    public static IList<T> Shuffle<T>(this IList<T> list, Random random)
    {
        for (var i = list.Count; i > 1; i -= 1)
        {
            var j = random.Next(i); 
            var temp = list[j];
            list[j] = list[i - 1];
            list[i - 1] = temp;
        }
        return list;
    }
}

You can achieve the desired result by providing a Random instance with a specific seed (in this case 0). This will ensure that the sequence of random numbers generated are the same each time the code executes:

var shuffledList = Enumerable.Range(0, 1000).ToList().Shuffle(new Random(0));
Martin Liversage
  • 104,481
  • 22
  • 209
  • 256
3

Instead of using an O(n log n) sort to shuffle (never mind the overhead of generating the Guid values), you should use Random and the standard O(n) Fisher-Yates shuffle. Then you can give the Random object the same seed with every execution.

Peter Duniho
  • 68,759
  • 7
  • 102
  • 136