studio numeros enteros con java math random probability

numeros - random in java



Generando una distribuciĆ³n de probabilidad. (6)

Dada una matriz de tamaño n , quiero generar probabilidades aleatorias para cada índice tal que Sigma(a[0]..a[n-1])=1

Un posible resultado podría ser:

0 1 2 3 4 0.15 0.2 0.18 0.22 0.25

Otro resultado perfectamente legal puede ser:

0 1 2 3 4 0.01 0.01 0.96 0.01 0.01

¿Cómo puedo generar estos de forma fácil y rápida? Las respuestas en cualquier idioma están bien, se prefiere Java.


Obtenga n números aleatorios, calcule su suma y normalice la suma a 1 dividiendo cada número con la suma.

Ampliando la respuesta de Kobi , aquí hay una función de Java que hace exactamente eso.

public static double[] getRandDistArray(int n) { double randArray[] = new double[n]; double sum = 0; // Generate n random numbers for (int i = 0; i < randArray.length; i++) { randArray[i] = Math.random(); sum += randArray[i]; } // Normalize sum to 1 for (int i = 0; i < randArray.length; i++) { randArray[i] /= sum; } return randArray; }

En una ejecución de prueba, getRandDistArray(5) devolvió lo siguiente

[0.1796505603694718, 0.31518724882558813, 0.15226147256596428, 0.30954417535503603, 0.043356542883939767]


Esto es relativamente tarde, pero para mostrar la enmienda a la respuesta simple y directa de @ Kobi dada en este paper señalado por @dreeves que hace que el muestreo sea uniforme. El método (si lo entiendo claramente) es

  1. Genere n-1 valores distintos del rango [1, 2, ..., M-1].
  2. Ordenar el vector resultante
  3. Agregue 0 y M como el primer y último elemento del vector resultante.
  4. Genere un nuevo vector calculando x i - x i-1 donde i = 1,2, ... n. Es decir, el nuevo vector está formado por las diferencias entre elementos consecutivos del vector antiguo.
  5. Divide cada elemento del nuevo vector por M. ¡Tienes tu distribución uniforme!

Tengo curiosidad por saber si generar valores aleatorios distintos y normalizarlos a 1 dividiéndolos por su suma también producirá una distribución uniforme.


La tarea que está tratando de realizar es equivalente a dibujar un punto aleatorio de la unidad N-dimensional simplex.

http://en.wikipedia.org/wiki/Simplex#Random_sampling podría ayudarlo.

Una solución ingenua podría ser la siguiente:

public static double[] getArray(int n) { double a[] = new double[n]; double s = 0.0d; Random random = new Random(); for (int i = 0; i < n; i++) { a [i] = 1.0d - random.nextDouble(); a [i] = -1 * Math.log(a[i]); s += a[i]; } for (int i = 0; i < n; i++) { a [i] /= s; } return a; }

Para dibujar un punto uniformemente de la unidad simplex de N dimensiones, debemos tomar un vector de variables aleatorias distribuidas exponencialmente , luego normalizarlo por la suma de esas variables. Para obtener un valor distribuido exponencialmente, tomamos un log negativo de valor distribuido uniformemente.


Obtenga n números aleatorios, calcule su suma y normalice la suma a 1 dividiendo cada número con la suma.



public static double[] array(int n){ double[] a = new double[n]; double flag = 0; for(int i=0;i<n;i++){ a[i] = Math.random(); flag += a[i]; } for(int i=0;i<n;i++) a[i] /= flag; return a; }

Aquí, al principio, almacena números al azar. Y la bandera mantendrá la suma de todos los números generados de modo que en el siguiente bucle for los números generados se dividirán por la bandera , que al final la matriz tendrá números aleatorios en la distribución de probabilidad.