js权重计算代码

dhso
2018/04/17 00:53
统计中

计算权重值

// 设3个项目人数比例为 15:50:72
var nums = [15, 50, 72];

// 求最小项目组人数
var min = Math.min.apply(Math, nums);

// 求权重
var weight = nums.map(function(n) {
    return min / n;
});

得到weight = [1, 0.3, 0.20833333333333334]

A组一票权重为1,B组一票权重为0.3,C组一票权重为0.2083

代码

/** 
* js数组实现权重概率分配,支持数字比模式(支持2位小数)和百分比模式(不支持小数,最后一个元素多退少补) 
* @param    Array    arr    js数组,参数类型[Object,Object,Object……] 
* @return   Array           返回一个随机元素,概率为其weight/所有weight之和,参数类型Object 
*/  

function weight_rand(arr){  
    //参数arr元素必须含有weight属性,参考如下所示
    //var arr=[{name:'1',weight:1.5},{name:'2',weight:2.5},{name:'3',weight:3.5}];
    //var arr=[{name:'1',weight:'15%'},{name:'2',weight:'25%'},{name:'3',weight:'35%'}];
    //求出最大公约数以计算缩小倍数,perMode为百分比模式
    var per;  
    var maxNum = 0;  
    var perMode = false;  
    //自定义Math求最小公约数方法
    Math.gcd = function(a,b){  
        var min = Math.min(a,b);  
        var max = Math.max(a,b);  
        var result = 1;  
        if(a === 0 || b===0){  
            return max;  
        }  
        for(var i=min; i>=1; i--){  
            if(min % i === 0 && max % i === 0){  
                result = i;  
                break;  
            }  
        }  
        return result;  
    };  
      
    //使用clone元素对象拷贝仍然会造成浪费,但是使用权重数组对应关系更省内存
    var weight_arr = new Array();  
    for (i = 0; i < arr.length; i++) {  
        if('undefined' != typeof(arr[i].weight))  
        {  
            if(arr[i].weight.toString().indexOf('%') !== -1) {  
                per = Math.floor(arr[i].weight.toString().replace('%',''));  
                perMode = true;  
            }else{  
                per = Math.floor(arr[i].weight*100);  
            }  
        }else{  
            per = 0;  
        }  
        weight_arr[i] = per;  
        maxNum = Math.gcd(maxNum, per);  
    }  
    //数字比模式,3:5:7,其组成[0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2]
    //百分比模式,元素所占百分比为15%,25%,35%
    var index = new Array();  
    var total = 0;  
    var len = 0;  
    if(perMode){  
        for (i = 0; i < arr.length; i++) {  
            //len表示存储arr下标的数据块长度,已优化至最小整数形式减小索引数组的长度
            len = weight_arr[i];  
            for (j = 0; j < len; j++){  
                //超过100%跳出,后面的舍弃
                if(total >= 100){  
                    break;  
                }  
                index.push(i);  
                total++;  
            }  
        }  
        //使用最后一个元素补齐100%
        while(total < 100){  
            index.push(arr.length-1);  
            total++;  
        }  
    }else{  
        for (i = 0; i < arr.length; i++) {  
            //len表示存储arr下标的数据块长度,已优化至最小整数形式减小索引数组的长度
            len = weight_arr[i]/maxNum;  
            for (j = 0; j < len; j++){  
                index.push(i);  
            }  
            total += len;  
        }  
    }  
    //随机数值,其值为0-11的整数,数据块根据权重分块
    var rand = Math.floor(Math.random()*total);  
    //console.log(index);
    return arr[index[rand]];  
}

测试

var arr=[{name:'1',weight:1.5},{name:'2',weight:2.5},{name:'3',weight:3.5}];  
console.log(weight_rand(arr));  

var arr=[{name:'1',weight:'15%'},{name:'2',weight:'25%'},{name:'3',weight:'35%'}];  
console.log(weight_rand(arr));  

本文为 dhso 原创

发布在 http://blog.minws.com/jsquan-zhong-ji-suan-dai-ma/

如有转载,请标明来源!

作者信息
姓名:dhso
热评文章
最新评论
文章概览