Pregunta

Tengo una matriz de doble de los valores de "vals", necesito al azar índice en esta matriz y obtener un valor.GenRandomNumber() devuelve un número entre 0 y 1, pero nunca es 0 o 1.Estoy usando Convertir.ToInt32 para conseguir básicamente todo a la izquierda de mi decimal, pero debe haber una manera más eficiente de hacerlo?

Aquí está mi código:

public double GetRandomVal()
{
   int z = Convert.ToInt32(GenRandomNumber() * (vals.Length));
   return vals[z];
}

Gracias

Actualización

Gracias a todos los que han respondido, pero yo estoy obligado a utilizar un MersenneTwister número aleatorio aplicación que tiene el método de rand.NextDouble()

Actualización 2

Pensando en esto un poco más, todo lo que necesitas hacer es generación de un número aleatorio entre 0 y matriz.longitud-1 y, a continuación, utilizar esa forma aleatoria índice en la matriz.vals longitud es de 2^20 = 1048576 por lo que la generación aleatoria de int es suficiente.Noto que mi MersenneTwister tiene un método:

public int Next(int maxValue)

Si me llaman como vals[rand.Siguiente(vals.longitud-1)] que debe hacer lo correcto?También puedo ver la MersenneTwister tiene un constructor:

public MersenneTwister(int[] init)

No está seguro de lo que esto es, ¿puedo usar esto para rellenar previamente la aceptable de números aleatorios para que me ofrecen una gama de 0 a vals.longitud?

FYI vals es una matriz doble de la longitud de la 1048576 partición de la curva de distribución normal.Yo soy básicamente el uso de este mecanismo para crear una distribución normal números tan rápido como sea posible, la la simulación de monte carlo se utiliza miles de millones de aleatorias distribuidas Normalmente los números de cada día así que cada poco ayuda.

¿Fue útil?

Solución

Trate de usar un entero aleatorio en lugar:

Random random = new Random();
int randomNumber = random.Next(0, vals.Length);
return vals[randomNumber];

Otros consejos

return vals[rng.Next(vals.Length)];

Donde RNG es

Random rng = new Random();

Creo que usted tiene la más simple y más directa, la aplicación ya identificados.

Pero si usted está buscando para las ganancias de rendimiento en su azar algoritmo de indexación, usted puede ser capaz de simplemente 'crack'el IEEE 754 codificado doble en su exponente y fracción - y el uso de la fracción modulo el tamaño de la matriz como un índice aleatorio.

Esta técnica NO ES probable que ser criptográficamente seguro - por lo que si es una consideración - no lo hagas.

Además, este enfoque NO hacer el código más obvio - yo me quedaría con el original de su ejecución, a menos que se maximiza el rendimiento es la consideración.Como un aparte, la parte más lenta de este procesamiento es más probable que el Mersenne Twister generación de números aleatorios.

Aquí está el código:

[StructLayout(LayoutKind.Explicit)] // used create a union of Long and Double
public struct IEEE754
{
    private const ulong SIGN_BITS     = 0x8000000000000000;
    private const ulong EXPONENT_BITS = 0x7FF0000000000000;
    private const ulong FRACTION_BITS = 0x000FFFFFFFFFFFFF;

    private const int SIGN_OFFSET     = 63;
    private const int EXPONENT_OFFSET = 52;

    // [FieldOffset] attribute is .NET's way of defining how to explicitly
    // layout the fields of a structure - we're using it to overlay the
    // double and long into a single bit-space ... effectively a C# 'union'
    [FieldOffset( 0 )] private double DoubleValue;
    [FieldOffset( 0 )] private ulong LongValue;

    public IEEE754(double val)
    {
        DoubleValue = val;
    }
    // properties that retrieve the various pieces of an IEEE754 double
    public long Fraction { get { return (long)(LongValue & FRACTION_BITS); } }
    public long Exponent { get { return (long)((LongValue & EXPONENT_BITS) >> EXPONENT_OFFSET); } }
    public long Sign     { get { return (long)((LongValue & SIGN_BITS) >> SIGN_OFFSET); } }

    public void Set( double val ) { DoubleValue = val; }
}

public static void TestFunction()
{
    var array = Enumerable.Range( 1, 10000 ).ToArray();   // test array...

    // however you access your random generator would go here...
    var rand = new YourRandomNumberGenerator();

    // crack the double using the special union structure we created...
    var dul = new IEEE754( rand.GenRandomNumber() );

    // use the factional value modulo the array length as a random index...
    var randomValue = array[dul.Fraction % array.Length];
}

¿Usted ha considerado el uso de la clase Random .NET?

Me gustaría utilizar Random.Next (Int32), que devuelve un valor menor que el de entrada y> = cero. Pase su longitud de la matriz como entrada, y usted tiene un índice válido al azar.

Como otras personas ya se han señalado, System.Random tiene una sobrecarga siguiente que va a hacer lo que ya está pidiendo.

En cuanto a tu comentario sobre Convert.ToInt32 y una alternativa más eficiente, puede convertir directamente un double a un int:

double d = 1.5;
int i = (int)d;
private static readonly Random _random = new Random();

public double GetRandomVal()
{
    int z = _random.Next(vals.Length);
    return vals[z];
}

Si no está de restricción para utilizar su función aleatoria, utilice la clase Random.

public Double GetRandomValue(Double[] values)
{
    return values[new Random().Next(values.Length)];
}

Else me acaba de utilizar un molde, ya que da el comportamiento correcto -. Redondeo hacia cero en lugar del número entero más cercano; Convert.ToInt32() hace

public Double GetRandomValue(Double[] values)
{
    return values[(Int32)(GetNextRandomNumber() * values.Length)];
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top