求给出一个生成n个和为1,且每个数都在[0,1]间的随机数的算法

问题描述:

同题,有伪码就好了,或者其他什么代码都可以。要求生成的随机数分布不会有明显的集中,比如最后几个随机数总是近似为零

这不很简单吗。
理论上:先生成n个随机数,求总和得S,每个数都除以S,就保证和为1。
实现上:
1)除之前先判断一下S是否为0(随机算法太妖了吧),是0就重来。
2)考虑到小数的精度问题,最后一个数修正为 1-(前n-1个数的和)。

第一印象解法,
就是先生成随机数,生成n-1个随机数,最后一个数是计算得到,保证和为固定数

比如n为10,则先生成9个随机数,数量级都为1w~2w的,第10个数用10w减去这9个数得到。
最后,这10个数全部除以10w即可。

感觉觉得可以将这个问题,先放大,然后再缩小,比如将和为1的扩大到和为10,100,1000,10000这类,然后获得这类数中N个和为对应的数据的,
然后再缩小。

这个简单,产生n个0~1的随机数,相加,然后得到一个和S。用每个数字除以s,即可。
比如n=3
产生的随机数是
0.12
0.78
0.36
S=0.12+0.78+0.36=1.26
因此随机数是
0.12/1.26=0.095
0.78/1.26=0.619
0.36/1.26=0.286
这样可以保证所有的数都充分随机

javascript可以很轻松的实现这个功能。
Math.random()就能随机生成0到1之间的任何数字

     function rd(num,result) {
        var l = [];
        var s = 0;
        var r =result;
        for (var i = 0; i < num; i++) {
            var a = "";
            if (i<num-1) {
                a = Math.random()*r;
                l.push(a);
                r = r-a;
            } else {
                a= r;
                l.push(a);
            }
        }
        for (var j =0; j < l.length; j++){
            s += l[j]
        }
        document.write(l+"<br>"+s);
    }
    rd(5,1)

这个应该可以解决问题