2010-11-23 5 views
2

Disons que j'ai un nombre, comme 100, et que je veux générer 5 nombres aléatoires différents, mais ils doivent tous totaliser 100, comment ferais-je cela? (de préférence en PHP Pour les maths/statisticiens, je n'ai pas besoin de nombres vraiment aléatoires, mais quelque chose qui semble aléatoire).n nombres aléatoires dans les paramètres

Donc cette fonction, produirait quelque chose comme ceci:

5, 51, 9, 18, 19 = 100 34, 52, 3, 7, 4 = 100

Et ainsi de suite.

Idéalement, quelque chose qui prend 5, 100 et produit le reste:

generateRandom (100,5)

+2

J'ai posé une question similaire il y a quelque temps et une grande réponse a obtenu: http://stackoverflow.com/questions/2794582/ replace-duplicate-values-in-array-avec-new-randomly-generated-values ​​ –

+0

duplication possible de [Non biased retourne une liste de n nombres positifs aléatoires (> = 0) de sorte que leur somme == total_sum] (http: //stackoverflow.com/questions/3959021/non-biased-return-a-list-of-n-random-positive-numbers-0-so-that-their-sum) –

Répondre

4
a = RandomInteger[{1, 96}] 
b = RandomInteger[{1, 97 - a}] 
c = RandomInteger[{1, 98 - a - b}] 
d = RandomInteger[{1, 99 - a - b - c}] 
e = 100 - a - b - c - d 

échantillons:

{34,25,26,3,12,Sum =,100} 

{90,5,1,1,3,Sum =,100} 

{29,16,21,9,25,Sum =,100} 

{4,13,71,10,2,Sum =,100} 

Les chiffres ne sont également distribués, bien sûr.

Modifier

Voici une répartition plus homogène:

a = RandomInteger[{1, 20}]; 
b = RandomInteger[{1, 40 - a}]; 
c = RandomInteger[{1, 60 - a - b}]; 
d = RandomInteger[{1, 80 - a - b - c}]; 
e = 100 - a - b - c - d; 

sortie:

{5,33,2,8,52,Sum =,100} 
{14,9,50,5,22,Sum =,100} 
{3,23,12,34,28,Sum =,100} 
{1,16,4,5,74,Sum =,100} 
{6,28,6,9,51,Sum =,100} 
{11,25,7,1,56,Sum =,100} 
{4,34,12,18,32,Sum =,100} 
{6,13,25,26,30,Sum =,100} 
{8,27,14,5,46,Sum =,100} 
{17,13,23,25,22,Sum =,100} 

Voici les fréquences pour les numéros:

alt text

Modifier

Peut-être un meilleur:

a = Max[#, 1] & /@ Evaluate[RandomInteger[{1, 20}, 5] - 1]; 
b = 100 - [email protected]; 
c = Mod[b, 5]; 
d = (b - c)/ 5; 
a = a + d + {c, 0, 0, 0, 0}; 

Distribution: alt text

Modifier

En Mathematica vous pouvez facilement générer tous les 5-tuples ajouter jusqu'à 100 comme:

IntegerPartitions[100, {5}] 

Il y a 38225 bêtes différentes, sans permutations compter

[email protected][100, {5}] 
(* -> 38225 *) 

La fréquence pour chaque numéro dans ces quintuplés est:

[email protected]@IntegerPartitions[100, {5}] 

enter image description here

La courbe est très similaire si l'on prend en compte les permutations:

t = [email protected]@(Permutations[#] & /@ IntegerPartitions[100, {5}]); 
[email protected][t, #[[1]] &][[All, 2]] 

enter image description here

+0

Au-dessus et au-delà, bravo à vous. Je te donne +1 juste pour l'effort seul. –

+0

@Brad Christie Astuce du chapeau: D –

+0

Donc, j'essaie de faire cela dans une fonction encore rand de 1, dans la fonction rand() de php me donne encore un résultat 0 - étrange. Sinon, ma fonction mise à jour fonctionne bien, Des idées là-dessus? Je pense à pair (rand (1,65535)% $ high_value + 1) –

1

Le long des lignes de Bélisaire:

// Generates an array (of $elements elements) full of random numbers whose 
    // total is equal to the $total_sum 
    function generate_random_array($elements = 5, $total_sum = 100) 
    { 
    // build result array 
    $result = Array(); 

    // iterate over all elements (except for the last, last will be the delta) 
    for ($_ = 0; $_ < ($elements - 1); $_++) 
    { 
     // typical low value (non-zero) 
     $low_value = 1; 

     // high value, skewed to have high results first 
     //$high_value = ($total_sum - ($elements - $_) - array_sum($result)); 
     // high value, non-skewed 
     $step = (int)floor($total_sum/$elements); // give "not-to-exceed" ranges 
     $high_value = (($_ + 1) * $step) - array_sum($result); 

     // produce the result and add it 
     $result[] = rand($low_value,$high_value); 
     //$result[] = rand(1,65535) % $high_value + 1; // alternate to make rand a little smoother 
    } 

    // add the final result as the remainder 
    $result[] = $total_sum - array_sum($result); 

    // now return it 
    return $result; 
    } 
+0

+1 Vous êtes presque là :) –

+0

Presque? Hah, qu'est-ce qui me manque? - Vous voulez dire votre dernière mise à jour? –

+0

Juste une blague! prendre plaisir! –