number - Método correcto de un aleatorio "estático". ¿Siguiente en C#?
random c# unity (12)
Creando una nueva instancia de Random y llamándola inmediatamente varias veces, por ejemplo:
for (int i = 0; i < 1000; i++)
{
Random rand = new Random();
Console.WriteLine(rand.Next(1,100));
}
Te dará una distribución que está ponderada hacia el extremo inferior del rango.
Haciéndolo de esta manera:
Random rand = new Random();
for (int i = 0; i < 1000; i++)
{
Console.WriteLine(rand.Next(1,100));
}
Te dará una mejor distribución.
¿Por qué necesito crear una instancia de clase Aleatoria, si quiero crear un número aleatorio entre 1 y 100 ... como
Random rand = new Random();
rand.Next(1,100);
¿Hay alguna función estática de la clase Random para hacer lo mismo? me gusta...
Random.Next(1,100);
No quiero crear una instancia innecesariamente
Crear una instancia efímera en C # es casi gratis. No pierdas tu tiempo preocupándote por esto. Probablemente tenga mejores lugares para buscar ganancias de perf o memoria.
Desde MSDN: clase aleatoria (sistema) :
"La generación de números aleatorios comienza desde un valor de inicialización. Si la misma semilla se usa repetidamente, se genera la misma serie de números. Una forma de producir diferentes secuencias es hacer que el valor de la semilla dependa del tiempo, produciendo así una serie diferente con cada nueva instancia de Random. De forma predeterminada, el constructor sin parámetros de la clase Random usa el reloj del sistema para generar su valor inicial , mientras que su constructor parametrizado puede tomar un valor Int32 basado en el número de ticks en el tiempo actual. tiene una resolución finita, usando el constructor sin parámetros para crear diferentes objetos aleatorios en estrecha sucesión crea generadores de números aleatorios que producen secuencias idénticas de números aleatorios . El siguiente ejemplo ilustra que dos objetos aleatorios que se instancian en estrecha sucesión generan una serie idéntica de números aleatorios. .. "
Es una buena práctica crear una sola instancia de Random
y usarla en todo su programa; de lo contrario, los resultados pueden no ser tan aleatorios. Este comportamiento se fomenta al no crear una función estática.
No debe preocuparse por "crear una instancia innecesariamente", el impacto es insignificante en el mejor de los casos: esta es la forma en que funciona el marco.
He hecho uno en:
http://www.codeproject.com/Tips/254057/Random-Color-Generator
Utiliza la distancia de color CIELab (una de las mejores para ojos humanos) para garantizar colores fácilmente diferenciables. Tiene una colección observable de colores que desea mantener alejados (como el color de fondo) más un factor de distancia (donde 1 es el valor predeterminado).
Espero eso ayude...
La mejor forma de hacerlo es tener una instancia de ThreadStatic
Random
:
[ThreadStatic] static Random random;
Random Get() {
if (random == null) random = new Random(Guid.NewGuid().GetHashCode());
return random;
}
Esto se ocupa de todo .
- Hilo de seguridad
- Actuación
- No es necesario sembrar
Me elude por qué .NET Framework (y cualquier otro marco en la tierra) no utiliza algo en este espíritu.
Los generadores de números aleatorios deben mantener el estado para ser "aleatorios". El generador de números aleatorios crea una secuencia que se genera en base a una semilla aleatoria. El problema es que nada en una computadora es en realidad aleatorio. Lo más parecido que tiene la computadora a mano es el reloj del sistema; ese es efectivamente el tiempo en el cual el proceso toma lugar. Por lo tanto, de forma predeterminada, se utiliza el conteo de ticks actual del reloj del sistema. Si su aplicación es lo suficientemente rápida, entonces pueden ocurrir muchos cálculos de números aleatorios bajo el mismo tick del sistema. Si el generador de números aleatorios no mantiene el estado en absoluto, proporcionará el mismo número aleatorio varias veces (la misma entrada da el mismo resultado). Esto no es generalmente lo que quieres.
Sé que ya está respondido, pero solo tengo que decir que prefiero usar el patrón singleton en este caso.
Necesitas algo similar si quieres la sintaxis que mencionas.
namespace MyRandom
{
public class Random
{
private static m_rand = new Random();
public static Next(int min, int max)
{
return m_rand.Next(min, max);
}
}
}
Esto debería permitirle hacer Random.Next(1,100);
sin tener que preocuparse por la siembra.
No es "innecesario", porque la clase Random almacena algún estado internamente. Lo hace para asegurarse de que si llama .Next()
varias veces muy rápidamente (en el mismo milisegundo o tick o lo que sea) no obtendrá el mismo número.
Por supuesto, si eso no es un problema en su caso, siempre puede combinar esas dos líneas de código en una sola:
new Random().Next(1, 100);
Por qué no?
Debe crear una instancia porque la forma en que se generan los números aleatorios es que las respuestas anteriores afectan a las respuestas posteriores. De forma predeterminada, el new Random()
constructor new Random()
usa la hora actual del sistema para "inicializar" la secuencia, pero no tiene que ser así: puede pasar su propio número si lo desea. En particular:
var rand = new Random(1234);
Console.WriteLine(rand.Next(0, 100));
Console.WriteLine(rand.Next(0, 100));
Console.WriteLine(rand.Next(0, 100));
Console.WriteLine(rand.Next(0, 100));
Producirá la misma secuencia de números "aleatorios" cada vez.
Eso significa que la clase Random
necesita mantener los datos de la instancia (la respuesta anterior, o "semilla") para las siguientes llamadas.
Ya tienes respuestas aquí. Solo reiterando la solución correcta :
namespace mySpace
{
public static class Util
{
private static Random rnd = new Random();
public static int GetRandom()
{
return rnd.Next();
}
}
}
Entonces puedes llamar:
var i = Util.GetRandom();
todo a través de. Si estrictamente necesita un verdadero método estático sin estado para generar números aleatorios, puede confiar en un Guid
.
public static class Util
{
public static int GetRandom()
{
return Guid.NewGuid().GetHashCode();
}
}
Va a ser un poquito más lento, pero puede ser mucho más aleatorio que Random.Next
. Random.Next
, al menos según mi experiencia.
Pero no
new Random(Guid.NewGuid().GetHashCode()).Next();
La creación de objetos innecesarios lo hará más lento, especialmente debajo de un bucle.
Y nunca :
new Random().Next();
No solo es más lento (dentro de un bucle), sino que la aleatoriedad es ... bueno, no muy buena según yo ...
//Function to get random number
private static readonly Random random = new Random();
private static readonly object syncLock = new object();
public static int RandomNumber(int min, int max)
{
lock(syncLock) { // synchronize
return random.Next(min, max);
}
}