Questo problema e le diverse soluzioni proposte mi hanno incuriosito. Ho fatto un piccolo test dei tre algoritmi di base suggeriti e quali valori medi avrebbero prodotto per i numeri generati.
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
Il tempo misure sono da prendere con un grano di sale in quanto potrebbero essere più influenzati dalla gestione della memoria Python che con lo stesso algoritmo. Sono troppo pigro per farlo correttamente con timeit
. L'ho fatto su Atom a 1 GHz in modo che questo spieghi perché ci è voluto così tanto tempo.
In ogni caso, scegliere_uno_e_divide_rest è l'algoritmo suggerito da Andrie e il poster della domanda stessa (AND): si sceglie un valore a in [0,1], quindi uno in [a, 1] e poi si guarda quello che hai lasciato. Si aggiunge a uno, ma questo è tutto, la prima divisione è due volte più grande degli altri due. Uno potrebbe averlo indovinato ...
choose_two_points_and_use_intervals è la risposta accettata da ddzialak (DDZ). Prende due punti nell'intervallo [0,1] e usa la dimensione dei tre sub-intervalli creati da questi punti come i tre numeri. Funziona come un fascino e i mezzi sono tutti 1/3.
choose_three_and_normalize è la soluzione di Anders Gustafsson e Josh O'Brien (JOB). Genera solo tre numeri in [0,1] e li normalizza di nuovo a una somma di 1. Funziona altrettanto bene e sorprendentemente un po 'più veloce nella mia implementazione Python. La varianza è leggermente inferiore rispetto alla seconda soluzione.
Là ce l'hai. Non ho idea di quale sia la distribuzione beta di queste soluzioni o quale insieme di parametri nel documento corrispondente a cui ho fatto riferimento in un commento, ma forse qualcun altro può capirlo.
È un'opzione per rinormalizzare i numeri casuali dopo la generazione? –
Che ne dici di generare 2 numeri casuali aeb? Quindi a + b + c = 1 => c = 1 - (a + b) –
e se a e b somma a maggiore di 1? – mmann1123