arrays - vacio - Seleccionar elemento de una matriz con probabilidad proporcional a su valor
multiplicacion de matrices en r (4)
Tengo una matriz de dobles y deseo seleccionar un valor de ella con la probabilidad de que cada valor que se seleccione sea inversamente proporcional a su valor. Por ejemplo:
arr[0] = 100
arr[1] = 200
En este ejemplo, el elemento 0 tendría un 66% de ser seleccionado y el elemento 1 una probabilidad del 33%. Estoy teniendo dificultades para codificar esto. Lo que he hecho hasta ahora es calcular el valor total de la matriz (el ejemplo sería 300), luego he jugado con invertir los números antes de calcularlos como un porcentaje del total. No puedo hacer que nada funcione. Al final deseo:
new randomNumber
for(int y=0; y < probabilities.length; y++){
if(randomNumber < probabilities[y]){
Select probabilities[y]
}
}
O algo para eso. ¿Alguna ayuda? La codificación está en Java, pero puedo adaptar cualquier pseudocódigo.
Para la proporcionalidad inversa:
- sumar la matriz
- Elija un número aleatorio entre 0 y (n-1) * suma -1
- Acumula valor de suma comenzando desde el principio hasta que seas> = al valor aleatorio.
Esto es para proporcional
Nota: Todos los valores deben ser positivos para que esto funcione.
- sumar la matriz
- Elija un número aleatorio entre 0 y el suma-1
- Acumule los valores comenzando desde el comienzo de la matriz hasta que esté> = al valor aleatorio.
La técnica habitual es transformar la matriz en una matriz de sumas acumuladas:
[10 60 5 25] --> [10 70 75 100]
Elija un número aleatorio en el rango de cero hasta el total acumulado (en el ejemplo: 0 <= x < 100
). Luego, use la bisección en la matriz acumulada para ubicar el índice en la matriz original:
Random variable x Index in the Cumulative Array Value in Original Array
----------------- ----------------------------- ----------------------
0 <= x < 10 0 10
10 <= x < 70 1 60
70 <= x < 75 2 5
75 <= x < 100 3 25
Por ejemplo, si la variable aleatoria x es 4, bisectar la matriz acumulativa proporciona un índice de posición de 0 que corresponde a 10 en la matriz original.
Y, si la variable aleatoria x es 72, bisectar la matriz acumulativa da un índice de posición de 2 que corresponde a 5 en la matriz original.
En una proporción inversa, la técnica es exactamente la misma excepto que se realiza una transformación inicial de la matriz en sus recíprocos y luego se crea la matriz de suma acumulativa:
[10 60 5 25] --> [1/10 1/60 1/5 1/25] --> [1/10 7/60 19/60 107/300]
Código Php:
/**
* Returns a random item from an array based on a weighted value.
* @param array $array [''foo'' => 70, ''bar'' => 30] Foo has a 70 percent chance of being returned
* @return int|string
*/
public function randomize(array $array)
{
$sumOfWeights = array_sum($array);
$random = rand(1, $sumOfWeights);
foreach ($array as $name => $weight) {
$random -= $weight;
if ($random <= 0) {
return $name;
}
}
}
Encuentra la suma de todos los elementos en la matriz. Luego genere un número aleatorio en este rango. La selección final será el elemento en el índice devuelto por la función anterior.
Enfrenté el mismo problema y presenté una solución simple. No es perfecto, pero es adecuado para algunos casos.
Tienes una matriz con algunos números [1,2,3, ...] y necesitas seleccionar un valor con cierta probabilidad [10,5,20, ...] simplemente haz una nueva matriz y repite cada valor tantas veces como mucha probabilidad tiene, por ejemplo
arr[] = [1,1,1,1,...(10 times),2,2,2,..(5 times),3,3,3,3,...(20 times)];
Y solo obtienen un número aleatorio de 0 a la nueva longitud de matriz y obtienen su valor con el número con la probabilidad deseable.
int r = Random(0,arr.count);
int value = arr[r];
Como menciono, no es perfecto y tampoco es un algoritmo eficiente en memoria, pero funciona.