• 微信平台抽奖算法总结-再也不用怕奖品被提前抢光


    前言

    但凡商户搞点营销活动,为了能触达更多的顾客,来点儿抽奖的把戏,应该是极好的,什么“刮刮乐”、“砸金蛋”、“大转盘”等等,换汤不换药,屡试不爽。从微客多营销平台各种活动的使用情况也能看出,抽奖活动一直是商户用得最多的线上活动,正所谓无利不起早,给点“花蜜”犒劳下“蜜蜂”也是应该的。

    需求分析

    那么问题来了,发奖机制怎么玩?作为一个服务商户的营销平台,怎样将商户配置的奖品发出去才能起到比较好的效果呢?

    先来看目标,什么是比较好的效果,也就是用户(商户)的需求是什么:

    • 抽奖活动期间奖品数量是固定的
    • 稀有的奖品尽量靠后被抽中
    • 物尽其用,奖品不希望有剩余
    • 每个奖品可以设置被抽中的概率

    场景模拟

    为了讨论方便,我们先把场景假设一下:

    抽奖活动时间:

    00:00:00-23:59:59

    奖品设置:

    奖品级别 奖品名称 奖品数量
    一等奖 A 2
    二等奖 B 3
    三等奖 C 4

    具体分析

    第一种能想到的做法就是给每种奖品设置中奖概率,每次按设置好的中奖概率派奖,但是问题又来了:

    奖品数量固定,但是参与抽奖的人数不可预知,根本无法控制奖品的消耗速度,如果概率设置高了,抽奖者一拥而上奖品很快就没了,设置低了,奖品可能到最后都发不完。另外,概率这个偏技术的术语用户理解起来肯定五花八门,使用时沟通成本非常高。

    而实际上“每个奖品可以设置被抽中的概率”是个十分模糊的说法,说它模糊,主要是因为你并不知道这个设置的概率用在什么地方,这些概率设置需要满足什么条件,总样本数量(总抽奖次数)是多少。

    所以最好的做法应该是用户不必关心所谓的“奖品被抽中的概率”,只关注前三个预期效果即可。

    经过分析,我们发现,要达到用户上面的那三个效果,只要奖品在活动期间陆续被抽走即可,那能不能给每件奖品设置一个允许被抽走的时间呢?对!如果控制好每件奖品的发放时间点,再安排好各类奖品的发放顺序,大奖不会一开始就抽走,直到活动最后阶段都能保证有奖。

    具体设计

    顺着这个想法,我们来看具体的设计:

    将奖品均匀地埋在整个活动时间(3600*24=86400秒)里,如上面假设场景,一共有9个奖品,则把活动时间均匀的分成9份

    dgf

    sadfsf

    以奖品剩余数量作为权重,陆续随机选择每个时间段里的奖品类型(颜色对应的奖品见上表)

    sdfdf

    在每个时间段里随机选择奖品的“释放”时间点,一是为了均匀,二是避免直接暴露精确的时间点

    sadsadf

    实现方案

    说完思路,我们再看实现:在奖品释放时间点之后的抽奖用户就有机会(这个概率可配置,如100%或者80%)拿到该时间段的奖品,如果奖品未被抽走,将继续等待抽奖者的到来。

    思路一

    直观的做法是建立三张表

    t_award_batch(奖品描述表,用于记录各种奖品的配置信息),

    ID 名称(name) 奖品总量(amount)
    1 A 2
    2 B 3
    3 C 4

    t_award_pool(奖池表,用于生成每一次奖品释放的时间点),

    ID 奖品ID(award_id) 释放时间(release_time) 剩余数(balance)
    1 3 1:03:27 0
    2 2 3:15:13 1
    3 3 5:29:57 1
    4 2 9:35:34 1
    5 1 12:57:20 1
    6 2 13:47:03 1
    7 3 17:31:50 1
    8 1 18:13:26 1
    9 3 22:28:40 1

    t_record(抽奖记录表,用于记录每次抽奖者的抽奖记录)

    ID 奖品ID(award_id) 中奖时间(hit_time) 用户ID(owner_id)
    1 3 1:03:45 peteryan

    活动开始前,根据t_award_batch中的奖品配置信息,初始化t_award_pool中的数据,把每种奖品的释放时间初始化好,用户来抽奖时,根据当前时间在t_award_pool表中的查询到一条已经释放而且未被抽掉的奖品

    查询到后对其进行更新,如果被他人抢走,则未中奖

    同时留下抽奖情况到t_record中。

    思路二

    在思路一中,为了方便抽奖时判断当前是否有可中奖品,进行了初始化每件奖品的释放时间,当奖品数量比较小的时候,情况还好,对于奖品数非常多的时候,抽奖的查询耗时会增加,初始化奖池也是耗时的动作,是否可以不依赖这个表之间通过实时计算判断当前是否有奖品释放。

    在t_award_batch表中添加两个字段,奖品总剩余量balance和上一次中奖时间last_update_time。

    ID 名称(name) 奖品总量(amount) 奖品余量(balance) 更新时间(last_update_time)
    1 A 2 2 1:03:45
    2 B 3 3 0:00:00
    3 C 4 3 0:00:00

    这样具体实现上仅需要依赖奖品配置信息即可,示例代码如下(点击图片全屏查看):

    dsfdf

    其中awardBatch表示一类奖品,如上表中提到的一等奖。上面代码中,随机选出下一个待释放的奖品逻辑如下:

    dsgdfg

    通过这套发奖机制,很好地满足了营销商户的目标,同时减少了对复杂概率计算的纠结,再也不用担心奖品被提前抢光了。

  • 相关阅读:
    回文串---最长回文
    回文串---Hotaru's problem
    回文串--- Girls' research
    回文串---吉哥系列故事——完美队形II
    回文串---Palindrome
    treap树---营业额统计
    treap树---Double Queue
    《程序员代码面试指南》第二章 链表问题 复制含有随机指针节点的链表
    《程序员代码面试指南》第二章 链表问题 将单链表按某值划分为左边小,中间相等,右边大的链表
    《程序员代码面试指南》第二章 链表问题 反转部分单向链表
  • 原文地址:https://www.cnblogs.com/sunshq/p/4171468.html
Copyright © 2020-2023  润新知