按照权重分配资源

什么是权重?

权重的数学表达式:(A1*P1+a2*P2+A3*P3+……An*Pn)/(A1+A2+A3+……+An)

权重是统计学中的一个概念。它主要反映个体在总体中占有的地位或比重,其所求出的具体数值就是权重值。

Example:

某班有一次测试成绩分别为:80、82、85、80、85

在这些成绩中:

80分:2个

82分:1个

85分:2个

所以,80分、82分、85分的权重分别为2、1、2,权重和为5,即总体。

 

权重在计算平均数的时候最为常用,我们知道一般计算平均数的方法为(80*2+82*1+85*2)/5=82.4

 

那么权重在java当中有什么实际意义呢?可以做抽奖效果等等……

Example:需要做一个抽奖系统,需求:抽中特等奖、一等奖、二等奖、三等奖的概率分别为1:2:3:4

思路:假设我们有10个数,分别是0、1、2、3、4、5、6、7、8、9,分布比例如下图:

那么:生成的随机数为0(大于等于0,小于1),占整体的概率是1/10;
生成的随机数为1,2(大于等于1,小于3),占整体的概率是2/10;
生成的随机数为3,4,5(大于等于3,小于6),占整体的概率是3/10;
生成的随机数为6,7,8,9(大于等于6,小于10),占整体的概率是4/10;

我们可以归纳为:

元素

最小

最大

A

0=0

1=0+1

B

1=A最大

3=A最大+2

C

3=B最大

6=B最大+3

D

6=C最大

10=C最大+4

由数学归纳法得:E0最小=0,E0最大=E0最小+权值0;En最小=En-1最大,En最大=En最小+权值n。 即当前元素概率范围,最小值是上一个元素的最大值,最大值是当前元素的最小值,加上当前元素的权值

Java代码:

思路:从最大范围开始找,weight会大于rand,当第一个rand大于或等于weight是结束

/**

 * 权重随机数

*/

public static int random(List<Integer> weight){

   List<Integer> weightTmp = newArrayList<Integer>(weight.size()+1);

    weightTmp.add(0);

    Integer sum = 0;

    for( Integer d: weight ){

        sum += d;

       weightTmp.add(sum);

    }

    Random random =new Random();

    int rand =random.nextInt(sum);

int index = 0;

    for(int i =weightTmp.size()-1; i >0; i--){ 

        if( rand>= weightTmp.get(i)){

            index = i;

            break;

        }

    }

    return index;

}

//这只是整数权重的,如果是小数、或者百分比,可以先转化成整数,在执行这个方法

权重的应用:

 

权重还在资源调度等系统当中有比较广泛的应用。一个简单的按照权重来随机的实现,权重为几个随机对象(分类)的命中的比例,权重设置越高命中越容易,之和可以不等于100

 

import java.util.ArrayList; 

import java.util.List; 

import java.util.Random; 

public class WeightRandom { 

    static List<WeightCategory>  categorys = new ArrayList<WeightCategory>(); 

    private static Random random = new Random(); 

    public static void initData() { 
        WeightCategory wc1 = new WeightCategory("A",60); 
        WeightCategory wc2 = new WeightCategory("B",20); 
        WeightCategory wc3 = new WeightCategory("C",20); 
        categorys.add(wc1); 
        categorys.add(wc2); 
        categorys.add(wc3); 
    } 

    public static void main(String[] args) { 

          initData(); 

          Integer weightSum = 0; 

          for (WeightCategory wc : categorys) { 
              weightSum += wc.getWeight(); 
          } 
          if (weightSum <= 0) { 
           System.err.println("Error: weightSum=" + weightSum.toString()); 
           return; 
          } 

          Integer n = random.nextInt(weightSum); // n in [0, weightSum) 

          Integer m = 0; 

          for (WeightCategory wc : categorys) { 
               if (m <= n && n < m + wc.getWeight()) { 
                 System.out.println("This Random Category is "+wc.getCategory()); 
                 break; 
               } 
               m += wc.getWeight(); 

          } 
    } 
} 

 
class WeightCategory { 

    private String category; 

    private Integer weight; 

    public WeightCategory() { 
        super(); 
    } 

    public WeightCategory(String category, Integer weight) { 
        super(); 
        this.setCategory(category); 
        this.setWeight(weight); 
    } 

    public Integer getWeight() { 
        return weight; 
    } 

    public void setWeight(Integer weight) { 
        this.weight = weight; 
    } 

    public String getCategory() { 
        return category; 
    } 

    public void setCategory(String category) { 
        this.category = category; 
    } 

}

你是技术宅么?那就加入我们吧!点击下方链接 或 扫描二维码 即可。

欢迎加入 CSDN技术交流群2:(点击即可加群)QQ群:456543087

               CSDN技术交流群(已满员):(点击即可加群)QQ群:681223095。  

商务合作@群主,谢谢!

因经常有人留言,未能及时查看到和回复,所以特建此群,以方便交流。方便问题讨论,有问题和没有问题的小伙伴均可加入,用作自我学习和共同进步。本博主不一定长期在线,但是qq群里会有很多热心的小伙伴,大家一起讨论解决问题。
右边的二维码是公众号。关注公众号,更多学习内容给予推送,争取每日更新

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值