Este problema y las diferentes soluciones propuestas me intrigaron. Hice una pequeña prueba de los tres algoritmos básicos sugeridos y qué valores promedio arrojarían para los números generados.
choose_one_and_divide_rest
means: [ 0.49999212 0.24982403 0.25018384]
standard deviations: [ 0.28849948 0.22032758 0.22049302]
time needed to fill array of size 1000000 was 26.874945879 seconds
choose_two_points_and_use_intervals
means: [ 0.33301421 0.33392816 0.33305763]
standard deviations: [ 0.23565652 0.23579615 0.23554689]
time needed to fill array of size 1000000 was 28.8600130081 seconds
choose_three_and_normalize
means: [ 0.33334531 0.33336692 0.33328777]
standard deviations: [ 0.17964206 0.17974085 0.17968462]
time needed to fill array of size 1000000 was 27.4301018715 seconds
El tiempo de las mediciones se deben tomar con un grano de sal, ya que podrían ser más influenciados por la gestión de memoria Python que por el propio algoritmo. Soy demasiado flojo para hacerlo correctamente con timeit
. Hice esto en un átomo de 1 GHz, así que eso explica por qué tardó tanto.
De todos modos, choose_one_and_divide_rest es el algoritmo sugerido por Andrie y el póster de la pregunta (AND): elige un valor a en [0,1], luego uno en [a, 1] y luego mira lo que te queda Se suma a uno, pero eso es todo, la primera división es dos veces más grande que las otras dos. Uno podría haber adivinado tanto ...
choose_two_points_and_use_intervals es la respuesta aceptada por ddzialak (DDZ). Toma dos puntos en el intervalo [0,1] y usa el tamaño de los tres subintervalos creados por estos puntos como los tres números. Funciona como un encanto y los medios son todos 1/3.
choose_three_and_normalize es la solución de Anders Gustafsson y Josh O'Brien (JOB). Simplemente genera tres números en [0,1] y los normaliza de nuevo a una suma de 1. Funciona igual de bien y sorprendentemente un poco más rápido en mi implementación de Python. La varianza es un poco menor que para la segunda solución.
Ahí lo tienes. No tengo idea de qué distribución beta corresponden estas soluciones o qué conjunto de parámetros en el documento correspondiente al que me refería en un comentario, pero tal vez alguien más pueda descifrarlo.
¿Es una opción para renormalizar los números aleatorios después de la generación? –
¿Qué hay de generar 2 números aleatorios a y b? Entonces a + b + c = 1 => c = 1 - (a + b) –
y si ayb suman a mayor que 1? – mmann1123