What is the best way to randomize the order of a generic list in C#? I've got a finite set of 75 numbers in a list I would like to assign a random order to, in order to draw them for a lottery type application.
相关问题
- Sorting 3 numbers without branching [closed]
- Graphics.DrawImage() - Throws out of memory except
- Why am I getting UnauthorizedAccessException on th
- 求获取指定qq 资料的方法
- How to know full paths to DLL's from .csproj f
A very simple approach to this kind of problem is to use a number of random element swap in the list.
In pseudo-code this would look like this:
Idea is get anonimous object with item and random order and then reorder items by this order and return value:
Here's a thread-safe way to do this:
This is my preferred method of a shuffle when it's desirable to not modify the original. It's a variant of the Fisher–Yates "inside-out" algorithm that works on any enumerable sequence (the length of
source
does not need to be known from start).This algorithm can also be implemented by allocating a range from
0
tolength - 1
and randomly exhausting the indices by swapping the randomly chosen index with the last index until all indices have been chosen exactly once. This above code accomplishes the exact same thing but without the additional allocation. Which is pretty neat.With regards to the
Random
class it's a general purpose number generator (and If I was running a lottery I'd consider using something different). It also relies on a time based seed value by default. A small alleviation of the problem is to seed theRandom
class with theRNGCryptoServiceProvider
or you could use theRNGCryptoServiceProvider
in a method similar to this (see below) to generate uniformly chosen random double floating point values but running a lottery pretty much requires understanding randomness and the nature of the randomness source.The point of generating a random double (between 0 and 1 exclusively) is to use to scale to an integer solution. If you need to pick something from a list based on a random double
x
that's always going to be0 <= x && x < 1
is straight forward.Enjoy!
If you don't mind using two
Lists
, then this is probably the easiest way to do it, but probably not the most efficient or unpredictable one: