当前位置:首页 > 算法 > 正文内容

不同概率的抽奖

canca6年前 (2020-04-01)算法544

需求很简单,为了更加形象,这里我们列一个表格来显示我们抽奖的物品和对应的概率(没有边框,大家凑合着看看吧,不想改造Octopress的样式了)

序号物品名称物品ID抽奖概率
1物品1P10.2
2物品2P20.1
3物品3P30.4
4物品4P40.3
5物品5P50.0
6物品6P6-0.1
7物品7P70.008

数据很简单,那么就直接看代码了

VO类,具体对应就是上面表格里的内容

package org.usc.usc.lottery;

public class Gift {
    private int index;
    private String gitfId;
    private String giftName;
    private double probability;

    public Gift(int index, String gitfId, String giftName, double probability) {
        this.index = index;
        this.gitfId = gitfId;
        this.giftName = giftName;
        this.probability = probability;
    }

    public int getIndex() {
        return index;
    }

    public void setIndex(int index) {
        this.index = index;
    }

    public String getGitfId() {
        return gitfId;
    }

    public void setGitfId(String gitfId) {
        this.gitfId = gitfId;
    }

    public String getGiftName() {
        return giftName;
    }

    public void setGiftName(String giftName) {
        this.giftName = giftName;
    }

    public double getProbability() {
        return probability;
    }

    public void setProbability(double probability) {
        this.probability = probability;
    }

    @Override
    public String toString() {
        return "Gift [index=" + index + ", gitfId=" + gitfId + ", giftName=" + giftName + ", probability=" + probability + "]";
    }

}

工具类,真正的不同概率的抽奖就在这里

package org.usc.usc.lottery;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 不同概率抽奖工具包
 *
 * @author Shunli
 */
public class LotteryUtil {
    /**
     * 抽奖
     *
     * @param orignalRates
     *            原始的概率列表,保证顺序和实际物品对应
     * @return
     *         物品的索引
     */
    public static int lottery(List<Double> orignalRates) {
        if (orignalRates == null || orignalRates.isEmpty()) {
            return -1;
        }

        int size = orignalRates.size();

        // 计算总概率,这样可以保证不一定总概率是1
        double sumRate = 0d;
        for (double rate : orignalRates) {
            sumRate += rate;
        }

        // 计算每个物品在总概率的基础下的概率情况
        List<Double> sortOrignalRates = new ArrayList<Double>(size);
        Double tempSumRate = 0d;
        for (double rate : orignalRates) {
            tempSumRate += rate;
            sortOrignalRates.add(tempSumRate / sumRate);
        }

        // 根据区块值来获取抽取到的物品索引
        double nextDouble = Math.random();
        sortOrignalRates.add(nextDouble);
        Collections.sort(sortOrignalRates);

        return sortOrignalRates.indexOf(nextDouble);
    }
}

结果

Gift [index=1, gitfId=P1, giftName=物品1, probability=0.2], count=199139, probability=0.199139
Gift [index=2, gitfId=P2, giftName=物品2, probability=0.1], count=99328, probability=0.099328
Gift [index=3, gitfId=P3, giftName=物品3, probability=0.4], count=396575, probability=0.396575
Gift [index=4, gitfId=P4, giftName=物品4, probability=0.3], count=296997, probability=0.296997
Gift [index=7, gitfId=P7, giftName=物品7, probability=0.0080], count=7961, probability=0.007961

不同概率的抽奖原理很简单 
就是把0到1的区间分块,而分块的依据就是物品占整个的比重,再根据随机数种子来产生0-1中间的某个数,来判断这个数是落在哪个区间上,而对应的就是抽到了那个物品。随机数理论上是概率均等的,产生的每个数理论上也应该概率均等,那么相应的区间所含数的多少就体现了抽奖物品概率的不同。(p.s. 当然数目是数不清楚的,具体抽象话了点)

这个实例的数据可以说明 
1. 概率可以是负数和0,当然实际上中应该不会(p.s. 正常情况下可能真的有0,比如抽个iphone5,当然是抽不到的了,这个时候,构建礼物(List gifts)的时候最好就不要加这个进去),还有可以把负数的处理放到抽奖工具类(LotteryUtil)中; 
2. 所有礼物加起来的概率可以不是1,可以认为这里的概率是一个权重;




扫描二维码推送至手机访问。

版权声明:本文由Ant.Master's Blog发布,如需转载请注明出处。

本文链接:https://iant.work/post/705.html

标签: 算法
分享给朋友:

“不同概率的抽奖” 的相关文章

MySQL悲观锁 select for update实现秒杀案例(jfinal框架)

为了方便测试,博主使用最新的jfinal框架,里边的东西就修改了一下a_little_config.txt,配置数据库链接的,启动直接打开DemoConfig.java,main方法启动即可(记得修改端口),这样就不用再去写jdbc了。感兴趣的朋友可以去了解一下:主要源码(模拟120人同时抢购100...

MySQL Redis分布式锁实现秒杀案例(jfinal框架)

我们加锁就一行代码:jedis.set(String key, String value, String nxxx, String expx, int time),这个set()方法一共有五个形参:    第一个为key,我们使用key来当锁,因为key是唯一...

zookeeper分布式锁实现秒杀案例(jfinal框架)

ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。ZooKeeper的架构通过冗余服务实现高可用性。...

MySQL乐观锁 实现秒杀案例,增加version字段来判断(jfinal框架)

MySQL乐观锁和悲观锁的主要区别在于:悲观锁在查询的时候就认为别人会和我抢,我查询的时候就先锁起来。乐观锁在查询的时候认为别人不会和我抢,我在更新的时候判断一下就可以了。所以如果在高并发的情况下,博主认为乐观锁并不适合做这种业务,因为是先查询,导致数据库有很多的更新失败,处理异常再次执行的情况,相...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。