Necesito algoritmo num aleatorio con mas posibilidades en 1

Hola, nose si lo pregunto en el sitio adecuado, pero creo que en desarrollo es el mejor sitio.
Pues eso, estoy programando un mini juego de simulacion. Necesito una funcion que pasado un conjunto de valores (diccionario) me de uno en random pero que depende de un valor tenga mas posibilidades que me de uno que otro.
Nose si me explico... seria asi:

Array[0]=7
Array[1]=3
Array[2]=18
funcionRandom(Array){
devolver indiceAleatorioArray
}
Lo mas probable es que me devuelva el indice 2, pero a veces me pueda dar los otros (el indice 1 seria el que salga menos)

Un metodo podria ser:
SumaDeTodos = Array[0]+Array[1]+Array[2]
Num=Random(mod SumaDeTodos)
Si Num esta entre 0 y Array[0]
devuelve 0
Si Num esta entre Array[0]+1 y Array[0]+Array[1]
devuelve 1
Si Num esta entre Array[0]+Array[1]+1 y Array[0]+Array[1]+Array[2]
devuelve 2

Esta funcion me daria exactamente lo que quiero... pero si tengo un array de 20 valores, este metodo es inviable.

Alguien sabe un buen metodo??
Saludos
Muy interesante y de gran ayuda. Muchas gracias, voy a investigar este metodo.
Saludos
XESC escribió:Muy interesante y de gran ayuda. Muchas gracias, voy a investigar este metodo.
Saludos

NPI, pero si lo encuentras postéalo por favor para poder recurrir a él en un futuro
No te sirve hacer un random de 0,1,2?
Si al final vas a devolver eso... O no lo he entendido bien
XESC escribió:Hola, nose si lo pregunto en el sitio adecuado, pero creo que en desarrollo es el mejor sitio.
Pues eso, estoy programando un mini juego de simulacion. Necesito una funcion que pasado un conjunto de valores (diccionario) me de uno en random pero que depende de un valor tenga mas posibilidades que me de uno que otro.
Nose si me explico... seria asi:

Array[0]=7
Array[1]=3
Array[2]=18
funcionRandom(Array){
devolver indiceAleatorioArray
}
Lo mas probable es que me devuelva el indice 2, pero a veces me pueda dar los otros (el indice 1 seria el que salga menos)

Un metodo podria ser:
SumaDeTodos = Array[0]+Array[1]+Array[2]
Num=Random(mod SumaDeTodos)
Si Num esta entre 0 y Array[0]
devuelve 0
Si Num esta entre Array[0]+1 y Array[0]+Array[1]
devuelve 1
Si Num esta entre Array[0]+Array[1]+1 y Array[0]+Array[1]+Array[2]
devuelve 2

Esta funcion me daria exactamente lo que quiero... pero si tengo un array de 20 valores, este metodo es inviable.

Alguien sabe un buen metodo??
Saludos


un método por ejemplo aunque un poco costoso de tiempo de CPU

ArrayTemp = new Array[Array1.length+Array2.length + ... + ArrayN.length]
int puntero = 0;
//*****N representa bucles según el número del array
for(int i = 0; i < ArrayN.length ; i++,puntero++){
puntero++;
ArrayTemp[Puntero+i] = N;
}

return ArrayTemp[Random.nextInteger(0,ArrayTemp.Length)];
Hola,

Quieres que el valor del array en cada indice sea el peso sobre la ponderacion de la pseudo-aleatoriedad, no?
Por ejemplo, si tienes la suerte que todos los valores del array valgan 100 y array[0] = 5, tu algoritmo devuelva un 0 el 5% de las veces. Es esto correcto?

Si no te preocupa la memoria puedes hacerlo de una manera muy rapida. Puedes utilizar otra estructura en vez de tu array plano. Si tienes un array asi:
a[0] = 2; a[1] = 1; a[2] = 3
Tendrias un array como el siguiente:
otherA[0] = 0; otherA[1] = 0 ;otherA[2] = 1; otherA[3] = 2; otherA[4] = 2; otherA[5] = 2;

En vez de indexar el valor siempre puedes anhadir el numero de veces el nuevo indice que quieres incluir y tu funcion random iria de 0 al tamanho de otherA. Esto significa que tendras siempre un array/lista en memoria cuya longitud es el numero total de apariciones. Es mucho gasto de memoria, pero es rapido. Y a la hora de incluir o borrar hay que hacer algo de magia.

Si estas forzado a mantener el array original puedes hacer un alrgoritmo que haga lo siguiente:

- calcula el valor del agregador total de valores, llamemoslo n. (Siempre puedes guardarlo en alguna variable y mantenerlo)
- randomIndex = rand() % n;
- int currentIndex = 0; int realIndex = 0;
- while (currentIndex < randomIndex) {
if (realIndex == array.length - 1) {
break;
}
if (randomIndex >= currentIndex + array[realIndex + 1]) {
currentIndex += array[realIndex++];
} else {
break;
}
}
- realIndex es el valor del indice que quieres obtener

Esta solucion no tiene mala pinta. Habria que verificar casos limite pero en general este esquema puede funcionar.
Te va bien?

Un saludo!
PS Perdona por las tides y derivados. Juro que el teclado extranjero tiene la culpa!
Buenas, la respuesta de alkaitz me parece una buena solución. Se me ha ocurrido una solución que no se si te la han dado, (no leí a fondo todas las respuestas) pero quizás no es la mas optima.

Si siempre es 0, 1 o 2 entonces creo que no afectara mucho al rendimiento pero si el array de opciones tiende a N pues entonces ya habría que mirar.

Ejemplo.

Situación a = [7,5,11]
Como tenemos 3 posibilidades pues calcularía 3 random, el primero de 0 a 7, el segundo de 0 a 5 y el tercero de 0 a 11. Nos quedamos con el random de mayor valor y ese es el indice que devuelves.

Pseudocodigo:

a = [7,5,11];
indice = funcion (a);

funcion (a) {
max_value = 0;
indice = 0;
for(i=0; i<a.length; i++){
c = rand() % a[i]
if(c > max_value){ //Aquí habría que mirar que condición le pones, si > o >= o alguna otra.
indice = i;
max_value = c;
}
}
return indice;
}

--------------

No se si quedo muy claro :)

Suerte
7 respuestas