Aquí es una sencilla aplicación (pero efectivo) de la reproducción aleatoria de Fischer-Yates/Knuth:
Random rnd = new Random();
for (int i = files.Length; i > 1; i--) {
int pos = rnd.Next(i);
var x = files[i - 1];
files[i - 1] = files[pos];
files[pos] = x;
}
O una ligera variación:
Random rnd = new Random();
for (int i = 1; i < files.Length; i++) {
int pos = rnd.Next(i + 1);
var x = files[i];
files[i] = files[pos];
files[pos] = x;
}
Como se trata de una Operación O (n), es la forma más eficiente de barajar una lista. Como todos los elementos de la lista tienen que poder moverse, no es posible barajar una lista de manera más eficiente que O (n).
Hice una pequeña prueba de rendimiento mezclando un millón de artículos mil veces cada uno utilizando este método y la respuesta actualmente aceptada (LINQ OrderBy), y esto es aproximadamente 15 veces (!) Más rápido.
¿Realmente desea la * solución más eficiente posible * o desea una * solución aceptablemente eficiente *? Porque hay algoritmos que son aún más eficientes que Fischer-Yates siempre que esté dispuesto a abandonar ciertas propiedades agradables, como la falta de parcialidad. (No es que Fischer-Yates implementado a continuación sea imparcial, sino que está profundamente sesgado) –
@Eric: Fischer-Yates _es_ imparcial. La implementación dada a continuación es incorrecta, como ha señalado. Por supuesto, hay implementaciones más eficientes si está dispuesto a tener sesgos. Por ejemplo, haz _nothing_ en absoluto. Realmente no entiendo tu punto. El OP no ha especificado nada, y es razonable (IMO) suponer que está buscando una mezcla uniforme. –
¿Es eso * realmente * razonable? El algoritmo de mezcla en cuestión es para archivos multimedia. Es posible que desee desviar la mezcla hacia la repetición más frecuente de las canciones más valoradas. –