2013-06-02 35 views
7

とにかく、その和が常に定数である乱数のセットを生成すると考えています。たとえば、20は5つの数字(1,2,3,4,10)に分けることができます。合計が20に等しい限り、5つの数字のそれぞれが何であるかは気にしません。プログラムで?は、合計が一定の乱数を生成する

+0

(あなたは、配列の値が別の近くに1になりたい場合など)も、値の間の「相違度」を制御することができますあなたは「製品」を意味しますか?あなたがそれを明確にしても、質問はまだ非常に不明です。 –

+0

http://stackoverflow.com/questions/8064629/random-numbers-that-add-to-100-matlab/8068956#8068956 –

+0

数字の正数のみ、または両方の負の数字がありますか? –

答えて

-1

ライブラリ関数を使用して乱数を取得します。

ここで、あなたが望む乱数は、生成された乱数modと許容された合計です。

次に、許可された合計を、生成した番号だけ減らします。

のは、あなたのライブラリー乱数ジェネレータが返す最初の乱数がだからあなたの最初の乱数が20から109のmod 20 = 9.アップデートあなたの許可総-9 = 11

ある109

あるとしましょう許可された合計がゼロになるまで、あなたは継続します。

あなたが言及した番号5は単なる例であることに注意してください。乱数の数を正確に5にするには、このメソッドを変更する必要があります。

+1

統一されません。これは1つの大きな数字と4つの小さなものである非常に多くの分布を作成します。 –

+0

は一様ではありません。 –

+0

あなたは正しいです - それは一様ではありません。私は、特にこの例では、この特定のケースでは必要と思われませんでした。一般的なケースでは、もちろん、一様な分布が必要です。 – hojusaram

-1

はい!最初に一般的に

[あなたがをしたい場合は、この使用してループを行うことができます] 5つの数字がランダムであり、彼らは20
にまとめる確かにそう

num1=rand()%20; 
num2=rand()%(20-num1); 
num3=rand()%(20-num1-num2); 
num4=rand()%(20-num1-num2-num3); 
num5=20-num4-num3-num2-num1; 

このアルゴリズムをすることができますしてみてください手元の番号まで合計する数[n]をランダムに生成する

n=rand()%k;--assuming the number of rand numbers you want are between 1 and k[sum] 
    n1=rand()%k; 
    n2=rand()%(k-n1) 
    . 
    . 
    nn-1=rand()%(k-n1...-nn-2) 
    nn=k-n1-n2...nn-1 

私はあなたを助けることを願っています!

+0

'n1'が19の場合はどうなりますか? – Kevin

+0

残りの4つの数字のうちの1つが1である確率は、そうでなければすべて0になります。公正な配布をしたい場合は、アルゴリズムを変更する必要があります。同様にrand()mod 20の代わりにrand()mod 6を使用します。 – dsharew

+0

これも、一様なセットではありません。 –

15

一様分布を得るには、あなたの合計を数行として考え、セグメントの乱数を生成し、n-1数を線に沿った点として生成し、減算してセグメントを得る。ここでojrandlibからの機能は次のとおり

static int compare(const void *a, const void *b) { 
    return *(int*)a - *(int*)b; 
} 
void ojr_array_with_sum(ojr_generator *g, int *a, int count, int sum) { 
    int i; 
    for (i = 0; i < count-1; ++i) { a[i] = ojr_rand(g, sum+1); } 
    qsort(a, count-1, sizeof(int), compare); 
    a[count-1] = sum; 
    for (i = count-1; i > 0; --i) { a[i] -= a[i-1]; } 
} 

ojr_rand(g, limit)は0からリミット1に一様ランダム整数を生成します。この関数は配列acountのランダムな整数で塗りつぶし、sumに追加します。他のRNGにこれを適応させることはあまり難しくありません。

+0

+1。私はこれが高次元で統一されていると思いますが、私はそれを証明する必要があります。これまでの他の答えはどれも一様に近いものではありません。より一般的な問題は、すべてが[X、X]の合計で区間[a、b]にあるN個の数値の無作為抽出であることに注意してください。もちろん、与えられた数に合計するランダムな整数を生成することも面白い問題です。 –

+1

本当に美しい解決策です。問題を抱えて、それを異種のものに変えて、より簡単で同等で簡単に解決できるもの - 天才。 – SimpleVar

0

これは私が

(それはとにかく仕事文句を言わないので、ほとんど、あなたが整数が必要になります)、それは最高の
で言っていない、ことが考えとして、これを提示し
トリックのビットですが、それでも:)

必要な乱数が必要とされていない場合は整数:
は 、あなたが[0,1]の間にN個の乱数を生成することができ、その後、生成された数字はnecesserilyされていない場合、あなたのS :)

for(i=0; i<N; i++) 
    arr[i] = rand; 

cursum = 0; 
for(i=0; i<N; i++) 
    cursum+=arr[i]; 

norm = S/cursum; 

for(i=0; i<N; i++) 
    arr[i] *= norm; 
0

に配列を正規化しますポジまたは範囲をwhitin。
あなたは最後の数はSすることができ計算することができます - SUM(A1..A [N-1])N-1の乱数の

の選択は、明らかに均一で
、最後の数がとにかくであるため、残りの数字に依存します
(各セットには最後の数字のオプションが1つしかありません)。

ユニフォームは妨げられません。

0

私の場合は、値の配列のためにこれを実行しなければなりませんでした。これはSumをとり、ランダムに数値の範囲に分割します。

<html> 
<script type="text/javascript"> 
function f(){ 
var array = [{ 
    order: '1-2480831', 
    value: 2040 
}, { 
    order: 'BAESYS-2012-0001', 
    value: 570 
}, { 
    order: 'BAESYS-2012-0002', 
    value: 773 
}, { 
    order: '1-3840231', 
    value: 299 
}, { 
    order: '1-3840298', 
    value: 1609 
}, { 
    order: '1-3841519', 
    value: 1940 
}]; 

    var splitInto = 3; 

    document.write("["); 
    for (i=0; i<array.length; i++) 
    { 
     document.write("{ Id : '"+array[i].order+"', Data : ["); 
    var result = RandGenerator(splitInto,array[i].value); 
    var sum = 0; 
      for(ii =0;ii<result.length; ii++){ 
       sum += result[ii]; 
      document.write(result[ii]+','); 
      } 
      document.write("]},"); 
    } 
    document.write("]"); 
} 

function RandGenerator(count, sum) { 
    var a = []; 
    for (iii = 0; iii < count-1; iii++) 
     { 
      a[iii] = getRandToValue(sum); 
      sum -= a[iii]; 
     } 
    a[count-1] = sum; 
    return a; 
} 

function getRandToValue(maxRand) 
{ 
    var random = Math.random(); 
    var computed = (maxRand)*random; 
    return computed; 
} 

f(); 
</script> 
</html> 
1

この方法では、仕事をして、そして「和」と

/** 
    * Create array of positive integers which exactly sums to a given (integer) number. 
    * @param {Number} number of items 
    * @param {Number} sum required sum 
    * @param {Number} [d=100] difference degree between the values (0..100) 
    */ 
    randomSumArray: function(len, sum, d) { 
     var _sum = 0; 
     var arr = []; 
     var n, i; 

     if (!d && d !== 0) { 
      d = 100; 
     } 

     for (i = 0; i < len; i++) { 
      var from = (100 - d) * 1000, 
       to = (100 + d) * 1000, 
       n = Math.floor(Math.random() * (to - from + 1) + from); //random integer between from..to 

      _sum += n; 
      arr.push(n); 
     } 

     var x = sum/_sum; 

     _sum = 0; //count sum (again) 
     for (var i = 0; i < len; i++) { 
      arr[i] = Math.round(arr[i] * x); 
      _sum += arr[i]; 
     } 

     var diff = sum - _sum; 

     // Correct the array if its sum does not match required sum (usually by a small bit) 
     if (diff) { 
      x = diff/Math.abs(diff); //x will be 1 or -1 
      var j = 0; 
      while (diff && j < 1000) { //limit to a finite number of 'corrections' 
       i = Math.floor(Math.random() * (len + 1)); //random index in the array 
       if (arr[i] + x >= 0) { 
        arr[i] += x; 
        diff -= x; 
       } 
       j++; 
      } 
     } 

     return arr; 
    }