V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
kikione
V2EX  ›  程序员

一般的抽奖程序是怎么写的?

  •  1
     
  •   kikione · 2021-11-09 22:37:55 +08:00 · 4931 次点击
    这是一个创建于 1094 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如题。

    51 条回复    2021-11-11 16:16:44 +08:00
    xiaoyukid
        1
    xiaoyukid  
       2021-11-10 08:47:22 +08:00
    Ramdom 完事
    vicya
        2
    vicya  
       2021-11-10 08:52:46 +08:00 via iPhone
    随机数完事
    lqw3030
        3
    lqw3030  
       2021-11-10 09:00:37 +08:00
    随会在乎公平呢(狗头)
    jenlors
        4
    jenlors  
       2021-11-10 09:13:27 +08:00 via iPhone   ❤️ 1
    大奖为 0 ,其他随机
    aliveyang
        5
    aliveyang  
       2021-11-10 09:14:39 +08:00
    彩票怎么写就怎么写
    2i2Re2PLMaDnghL
        6
    2i2Re2PLMaDnghL  
       2021-11-10 09:19:01 +08:00   ❤️ 4
    // 就算没有中奖也有 20%概率发送弹幕,产生一种中奖的人很多的错觉
    HelloWorld556
        7
    HelloWorld556  
       2021-11-10 09:22:25 +08:00   ❤️ 8
    ```
    if(name=='张三') return 一等奖
    if(name=='李四') return 二等奖
    return 谢谢参与
    ```
    markgor
        8
    markgor  
       2021-11-10 09:23:16 +08:00
    一般抽奖程序就和平常抽奖程序一样写就行了。
    Saxton
        9
    Saxton  
       2021-11-10 09:24:27 +08:00
    @long2ice 兄弟你是腾讯来的吧 笑死
    Junh
        10
    Junh  
       2021-11-10 09:26:54 +08:00
    @markgor 听君一席话
    zjsxwc
        11
    zjsxwc  
       2021-11-10 09:30:25 +08:00
    提前分配中奖者
    cjpjxjx
        12
    cjpjxjx  
       2021-11-10 09:33:52 +08:00
    print("谢谢参与")
    laqow
        13
    laqow  
       2021-11-10 09:33:53 +08:00
    取决于想模拟的随机分布模型
    arnoldxiao
        14
    arnoldxiao  
       2021-11-10 09:44:40 +08:00
    @HelloWorld556 兄弟,你这...可不可以在张三前面给我加个特等奖
    jorneyr
        15
    jorneyr  
       2021-11-10 09:48:58 +08:00
    有一次抽奖 (iPhone),领导抽了第一个人,说名字写的太潦草,看不清,扔回去重新抽了第二个人,谁会关心名字是否太潦草呢?
    jorneyr
        16
    jorneyr  
       2021-11-10 09:50:13 +08:00
    下一年抽奖 (MBA),大家下面起哄谁谁谁今天生日,还是同一个领导抽奖,很幸运过生日的人中奖了。
    murmur
        17
    murmur  
       2021-11-10 09:51:29 +08:00
    按领导意思处理,如果是面对互联网肯定是内定,如果是内部的话高管要避嫌
    newmlp
        18
    newmlp  
       2021-11-10 09:52:45 +08:00
    看需求,再选择随机算法
    amwyyyy
        19
    amwyyyy  
       2021-11-10 09:54:11 +08:00
    之前做了一个,让运营人员上传 excel ,表格填中奖序号和奖品。
    sadfQED2
        20
    sadfQED2  
       2021-11-10 09:58:50 +08:00 via Android
    服务器机房安装一个话筒,根据当时录音的声波值 hash ,然后用 hash 值做随机数种子,然后使用随机函数

    绝对随机算法😏
    jptx
        21
    jptx  
       2021-11-10 09:59:04 +08:00   ❤️ 1
    先准备员工姓名工号列表,作为第一个列表,如果特等奖有内定,则把特等奖那个员工从第一个列表中摘出来单独放一个列表,如果有一等奖内定,则把一等奖那个员工也从列表中摘出来单独放一个列表,以此类推。如果有员工黑名单或者高管或者避嫌不想让中奖的人,则把这些人从第一个列表中移除。
    现在可供抽奖的员工列表准备完毕了,再准备一个列表(员工姓名、工号、头像)供界面滚动,这个列表包含公司全体员工,让每个人(包括老板)都可以在界面上滚动,这个列表是死的,不论是否中过奖,不论是否是内定,都在里面滚动。
    下面开始抽奖,三等奖和二等奖抽的时候,可以使用洗牌算法进行抽取,洗牌算法随便百度就有现成的代码,抽到哪些人,就把他们从第一个列表中移除,单独放入中奖列表,记录下这些人的中奖信息。抽一等奖时要注意,一定要先拉取内定人员列表,再从剩下的列表中抽取,如果一次抽取很多人,这些人在界面上的排序要随机,不要连着。
    raysonlu
        22
    raysonlu  
       2021-11-10 10:00:33 +08:00
    之前参与过一次讨论,确实不只是 Ramdom 那么简单。主要是不能确定抽奖总次数(总人数)。
    一般简单的需求只是提出了中奖概率:一等奖中奖率 1%,二等 3%,三等 5%,为了方便讨论,姑且再简单化每个奖项奖品数量为 1 。
    然后大多数人一上来的写法就是 random1~100 ,然后得出指定的一个或者多个的数,来做中奖判断。
    实际上这种简单模型,只遵循了理论上的中奖率,没有符合到实际需求。因为中奖变得“先到先得”更为重要了(可以写个模拟抽奖 demo 测试一下),但实际上一场抽奖活动更多的是希望吸引更多的人流,并不想活动开了半天大奖全部抽完。
    所以当时我盲猜两种做法:1 极度调低实际的中奖率,配合活动结束时间稍微调整让奖品都能送出; 2 也是要配合活动时间定时定量动态调整奖品中奖率。
    2kCS5c0b0ITXE5k2
        23
    2kCS5c0b0ITXE5k2  
       2021-11-10 10:05:42 +08:00   ❤️ 1
    我用的是 Alias Method. 运行一年多 基本上的结果都和设定的概率趋同.
    rekulas
        24
    rekulas  
       2021-11-10 10:11:42 +08:00
    @sadfQED2 没用,获取声波就大有可操作的地方,毕竟人脑也不可能判断你取得参数是否正确。要想做到真正公平,就必须流程公开人人可计算,例如遵循密码学承诺的开奖方式
    stroh
        25
    stroh  
       2021-11-10 10:17:04 +08:00
    彩票不是随机的,如果真随机早就做不下去了
    necodba
        26
    necodba  
       2021-11-10 10:18:33 +08:00
    我觉得还是要看功能吧,之前有一个什么星 yun 抽奖的,你看它实现的功能再定制你自己需要的功能啊
    HQKM
        27
    HQKM  
       2021-11-10 10:18:59 +08:00
    时间戳做随机种子,还要策划要求的保底功能,欧皇靠概率防不住。
    y0bcn
        28
    y0bcn  
       2021-11-10 10:20:04 +08:00
    大一的时候给学校的活动做过大屏抽奖,主要是根据场地大小预估场地人数,确保性能跟得上
    提供一个二维码链接供用户扫码输入信息,输入的信息会通过 websocket 传到浏览器端,采用 websocket 的主要原因是当时的服务器宽带太小,怕人数多了太卡,等于把大流量的下载变成分散的小流量。
    浏览器端设置一个 strat/stop 方法,控制滚动
    滚动很简单,就是取随机数去改变文字,实测在 70ms 左右效果就不错

    同时可以提供一个控制端,通过 websocket 控制大屏幕的开始或暂停
    当然如果想省事,直接设置快捷键,后台工作人员根据主持人的指示 start/stop 即可

    这是大屏抽奖,中奖率啥的没考虑,因为本身是各奖项数量有限,没有必要去考虑,不过有一个去重,即中奖后会把他从名单拿掉,防止万一重复中奖造成他人眼红。。
    Chad0000
        29
    Chad0000  
       2021-11-10 10:22:01 +08:00
    如果参与人数比较多同时想控制出奖均匀,可以采取定点放奖。这样某个时间一到,第一个抽的人就拿走相应的奖。
    Chad0000
        30
    Chad0000  
       2021-11-10 10:23:10 +08:00
    甚至由运营人员点按钮,人工放大奖。点了大奖马上就放池子里,第一个抽者获得
    securityCoding
        31
    securityCoding  
       2021-11-10 10:24:39 +08:00
    @stroh 彩票是官营博彩,真随机没办法控制
    Immortal
        32
    Immortal  
       2021-11-10 10:25:33 +08:00
    把中奖名额设置可以指定 然后问问老板意思
    geekvcn
        33
    geekvcn  
       2021-11-10 10:30:41 +08:00   ❤️ 2
    return "谢谢参与"

    网页滚动:
    随机姓名 随机号码 刚刚中了 XXX ,运气爆表!!!
    ...
    kop1989
        34
    kop1989  
       2021-11-10 10:40:48 +08:00
    1 、黑名单、白名单。
    2 、时间做种子,如果系统有其他业务的话,可以加一些其他业务的无关信息。(比如昨天某某日志的条数)
    3 、根据业务需要增加保底和概率回归(因为抽奖都是有限次的,所以有可能会导致当场抽奖的概率和理论概率有很大偏差)
    stroh
        35
    stroh  
       2021-11-10 11:13:01 +08:00
    @securityCoding 是的,总得有人吃肉,有人喝汤,有人提供案板,有人自愿躺在上面
    SmiteChow
        36
    SmiteChow  
       2021-11-10 14:19:18 +08:00
    一般内定,然后整个滚动的假象。
    soupu626
        37
    soupu626  
       2021-11-10 14:27:21 +08:00
    每个用户能拿什么奖,事先打好标,一般一个 int 就够了,然后实际抽的时候在对应的人群里选人出来就行
    2i2Re2PLMaDnghL
        38
    2i2Re2PLMaDnghL  
       2021-11-10 14:53:33 +08:00
    @jorneyr 不能不怀疑,有些起哄的人写了过生日的人的名字,属于拔高中奖率了
    2i2Re2PLMaDnghL
        39
    2i2Re2PLMaDnghL  
       2021-11-10 14:54:35 +08:00
    @stroh ?你是不是不懂彩票这东西越随机越能赚钱?
    mengyx
        40
    mengyx  
       2021-11-10 15:14:31 +08:00 via Android
    应该用一个难以控制,但是容易验证的值作为 seed
    比如说,提前约定未来某天的 股指收盘点数
    coolmenu
        41
    coolmenu  
       2021-11-10 15:19:41 +08:00
    把老板指定的人放置好,放点甲乙丙丁假人,最后把自己的控制的代理人也放进去,行啦
    jinzhongyuan
        42
    jinzhongyuan  
       2021-11-10 15:24:05 +08:00
    public static void main(String[] args) {
    WeightRandom<String> weightRandom = WeightRandom.create();
    weightRandom.add("奖品 1", 0.8);
    weightRandom.add("奖品 2", 0.2);
    weightRandom.add("谢谢参与", 0);

    // 统计 (这里用 AtomicInteger 仅仅是因为写起来比较方便,这是一个单线程测试)
    Map<String, AtomicInteger> statistics2 = new HashMap<>();

    for (int i = 0; i < 1_0; i++) {
    String award = weightRandom.next();
    System.out.println(award);
    statistics2.computeIfAbsent(award, (k) -> new AtomicInteger()).incrementAndGet();
    }
    statistics2.forEach(
    (k, v) -> {
    double hit = (double) v.get() / 1_0;
    System.out.println(k + ", hit:" + hit);
    });
    }


    <dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>${hutool}</version>
    </dependency>



    实现概率抽奖,请叫我雷锋
    vitozyf
        43
    vitozyf  
       2021-11-10 16:13:06 +08:00
    ylsc633
        44
    ylsc633  
       2021-11-10 16:46:40 +08:00
    以前写过一个

    有个后台,由运营配置 奖品和库存, 然后根据库存来计算中奖概率

    所以 一等奖的 iPhone 的库存是 0,所以这个就不会抽中,但是会在抽奖列表里

    概率是这么算的(是想公平点......)

    就是随机值

    比如 所有奖项库存是 100
    一等奖是 iPhone,库存 0, 所以 概率就是 0
    二等奖库存 10 个, 概率就是 10%
    三等奖库存 40 个,概率就是 40%
    四等奖库存 50 个,概率就是 50%

    那么第一个人抽, 随机值是从 (0,100]
    如果随机值是 (0,10] 就是二等奖
    如果随机值是[11,50] 就是三等奖
    如果随机值是[51,100]就是四等奖

    第一个人抽中后,库存减一,比如 是抽中二等奖

    那么 接下来的人
    二等奖范围[0,9]
    三等奖[10,49]
    四等奖[50,99]

    这样每个奖品都有库存.. 还可以随时加库存..

    另外,如果有 谢谢惠顾 也是按照一种奖品来设置的. 不过他的奖品 ID 是特定的, 因为它的库存是无限的, 数据库里是有限的,如果不够了,代码会自动补货....

    然后就是 缓存和数据库的事情了

    以前的伪代码: http://interview.wzcu.com/%E8%AE%BE%E8%AE%A1%E9%A2%98/%E5%B8%A6%E6%9C%89%E6%9D%83%E9%87%8D%E7%9A%84%E9%9A%8F%E6%9C%BA%E7%AE%97%E6%B3%95.html#%E4%BB%A3%E7%A0%81

    主要以前量小, 基本问题不大...
    a62527776a
        45
    a62527776a  
       2021-11-10 16:55:32 +08:00
    if (试用期) return
    if (3 年一下) return 阳光普照
    fl2d
        46
    fl2d  
       2021-11-10 16:59:15 +08:00
    众所周知,对于新浪微博来说,任何抽奖都要加一条 user.gender != "M" 。
    wolfie
        47
    wolfie  
       2021-11-10 17:00:10 +08:00
    Random
    中 2 等奖,库存 -1 ,没了 算中 3 等奖,往下推。
    dbpe
        48
    dbpe  
       2021-11-10 17:16:40 +08:00
    类似卡池...
    tzigone
        49
    tzigone  
       2021-11-10 17:35:23 +08:00
    核心就是随机函数,要有人还要继续深究真随机还是假随机,直接让他出随机方案. GG
    3dwelcome
        50
    3dwelcome  
       2021-11-10 23:39:33 +08:00
    “要有人还要继续深究真随机还是假随机”

    这种只能是假随机,就好比游戏氪金一样。在程序员真随机数大数据看来,没问题。可是由于人性的干预,很多人就觉得十连抽,一个 SSS 都不中,就觉得很离谱。又或者 20 连抽后,连续两个 SS 挤在一起。

    假随机给用户的感觉更好。其实随机数还是那些,就是加入了十年抽必中,在给用户结果前,已经后台预先排序过了。
    Alchemistboy
        51
    Alchemistboy  
       2021-11-11 16:16:44 +08:00
    概率可配置,例如根据标签配置概率,如 [优质] 标签中奖概率调高, [新注册] 用户概率调极低之类的,反正就是要提供运营一套她们想让谁中就让谁中的配置化系统。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1523 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 23:57 · PVG 07:57 · LAX 15:57 · JFK 18:57
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.