一个红包随机分配算法

标签: 算法 | 发表时间:2016-04-23 12:15 | 作者:
出处:http://www.letiantian.me/

本文简单的讨论一下随机分配红包的算法实现。若有雷同,纯属巧合。

如何生成指定范围内的随机整数

Python的random库提供了randint函数用于得到整数a和整数b之间的一个随机的整数(包括a和b,其中a<=b)。

  import random
a=1
b=100
print random.randint(a,b)

randint函数可以基于random函数实现。random函数可以随机生成 [0.0, 1.0)之间的一个小数,注意是左闭右开的区间。

下面的my_randint01函数可以得到一个左闭右开区间中的随机整数:

  import random

def my_randint01(left, right):
    if left>=right:
        raise Exception('...')
    rand_number = random.random()
    result = left+rand_number*(right-left)
    return int(result)

if __name__ == '__main__':
    for _ in range(10):
        print my_randint01(2, 6)

下面的my_randint02函数可以得到一个左闭右闭区间中的随机整数:

  import random

def my_randint02(left, right):
    if left>right:
        raise Exception('...')
    rand_number = random.random()
    result = left+rand_number*(right-left+1)  # 此处略有改动
    return int(result)

if __name__ == '__main__':
    for _ in range(10):
        print my_randint01(2, 6)

红包分配要考虑的情况

用户看到的是红包单位是 ,不过RMB的最小单位是分,将金额从 转换为 也许更容易处理。

用户拿到的红包转换为 时,必须是整数。

4分钱发给4个朋友,每个人都应该得到1分的红包。

4分钱不能发给5个朋友。

100分钱发给4个朋友要体现出随机性。

来,发红包

100分钱发给4个人,可以先得到4个大于0的在一定范围内的随机整数。每个人对应一个随机整数,通过这个随机整数可以得到他收到的红包大小在100分钱中的比例,然后按照比例分配。在此基础上还需要考虑下面的细节问题:

1、 涉及到浮点数的乘除法,如果一个人最终得到了 0.2分钱,转转成整数该是0分钱还是1分钱? 解决办法是先给每个人分配1分钱。

2、 涉及到浮点数的乘除法,最后分配的红包取整后的和不一定等于100。解决方法是:每个人的红包向下取整,第4个人直接把剩下的拿到手即可。

3、 按照上面的思路,5分钱分给4个人,第四个人稳拿2分钱。解决方法是:红包分配好后再随机打乱。

最终算法如下:

  #coding: utf-8
import random

def red_envelope(cents, people_number):

    if (not isinstance(cents, int)) or (not isinstance(people_number, int)):
        raise Exception('invalid type!')

    if cents < people_number:
        raise Exception('too many people!')

    if cents <= 0 or people_number <= 0:
        raise Exception('Are you kidding me ?')

    if cents == people_number:
        return [1] * people_number

    if people_number == 1:
        return [cents]

    fix_result = [1] * people_number
    cents = cents - 1*people_number
    balance = cents
    rand_result = []
    rand_numbers = []
    for _ in range(people_number):
        rand_numbers.append(random.randint(10,100))
    rand_sum = float(sum(rand_numbers))

    for idx in range(people_number):
        if idx == people_number - 1:
            rand_result.append(balance)
        else:
            scale = rand_numbers[idx] / rand_sum
            your_cents = int(cents*scale)
            rand_result.append(your_cents)
            balance = balance - your_cents

    result = []
    for fix, rand in zip(fix_result, rand_result):
        result.append(fix+rand)

    random.shuffle(result)  # shuffle the result

    return result


# test
if __name__ == '__main__':
    result = red_envelope(100, 10)
    print result, sum(result)

某次输出结果:

  [15, 10, 11, 10, 3, 7, 14, 3, 20, 7] 100

相关 [红包 随机 算法] 推荐:

一个红包随机分配算法

- - 樂天笔记
本文简单的讨论一下随机分配红包的算法实现. Python的random库提供了randint函数用于得到整数a和整数b之间的一个随机的整数(包括a和b,其中a<=b). randint函数可以基于random函数实现. random函数可以随机生成 [0.0, 1.0)之间的一个小数,注意是左闭右开的区间.

微信红包算法探讨

- - SegmentFault 最新的文章
今年过年微信红包成了全民焦点,虽然大多数的红包就一块八角的样子,还是搞得大家乐此不彼地,蛋爷我年三十晚什么都没干就守在手机旁边不是摇手机红包就是抢群红包. 作为一名程序猿,自然会想了解下红包的实现细节. 我在网上谷歌了下,微信目前是没有公布红包的实现细节的,所以这里就提出一个自己的方案. 红包领了不少,据观察红包主要有以下几个限制条件:.

微信红包金额分配的算法

- - 后端技术 by Tim Yang
虽然春节已经过去一段时间,但不少微信群里面依旧乐此不疲的在玩发红包活动,用户自发的将最初的一个春节拜年的场景功能慢慢演化成一个长尾功能. 用户在微信中抢红包时分成抢包和拆包两个操作. 抢包决定红包是否还有剩余金额,但如果行动不够迅速,在拆包阶段可能红包已经被其他用户抢走的情况. 据某架构群腾讯财付通专家反馈,红包的金额是拆的时候实时计算,而不是预先分配,实时计算基于内存,不需要额外存储空间,并且实时计算效率也很高.

伪随机和真随机

- AWard - LinuxTOY
相信每个计算机相关专业的人都理解伪随机和真随机的差别,那么它们到底“看起来”有什么差别呢. 下面是来自 Random.org 的随机数位图:. 下面是在 Windows 系统上调用 PHP 的 rand() 方法生成的:. 同样这段代码在 Linux 系统上运行时并没有出现这样的规律,换用 Mersenne Twister 的 mt_rand() 方法也没有这样的规律.

随机数原理

- - 崔永键的博客
.Net 创建随机数常用的方法:. C/C++中创建随机数的方法:. 以上随机数的生成原理,基本上是下面这种思路:. 比如,我使用线性同余法来自己生成随机数.      int next = (seed * 29 + 37) % 1000;  //线性同余法. 线性同余法:第n+1个数=(第n个数*29+37) % 1000.

微信红包实现原理

- - PHP源码阅读,PHP设计模式-胖胖的空间
以下内容来源于QCon某高可用架构群聊天记录整理 背景:有某个朋友咨询微信红包的架构,在官方或非官方同学的解释和讨论中得出以下讨论内容,在此期间有多个同学发红包做现网算法测试. 当有人在群里发了一个N人的红包,总金额M元,后台大概发生的事情如下:. 在数据库中增加一条红包记录,存储到CKV,设置过期时间;.

缓存算法

- lostsnow - 小彰
没有人能说清哪种缓存算法由于其他的缓存算法. (以下的几种缓存算法,有的我也理解不好,如果感兴趣,你可以Google一下  ). 大家好,我是 LFU,我会计算为每个缓存对象计算他们被使用的频率. 我是LRU缓存算法,我把最近最少使用的缓存对象给踢走. 我总是需要去了解在什么时候,用了哪个缓存对象.

BFPRT算法

- zii - 小彰
BFPRT算法的作者是5位真正的大牛(Blum 、 Floyd 、 Pratt 、 Rivest 、 Tarjan),该算法入选了在StackExchange上进行的当今世界十大经典算法,而算法的简单和巧妙颇有我们需要借鉴学习之处. BFPRT解决的问题十分经典,即从某n个元素的序列中选出第k大(第k小)的元素,通过巧妙的分析,BFPRT可以保证在最坏情况下仍为线性时间复杂度.

贪心算法

- Shan - 博客园-首页原创精华区
顾名思义,贪心算法总是作出在当前看来最好的选择. 也就是说贪心算法并不从整体最优考虑,它所作出的选择只是在某种意义上的局部最优选择. 当然,希望贪心算法得到的最终结果也是整体最优的. 虽然贪心算法不能对所有问题都得到整体最优解,但对许多问题它能产生整体最优解. 如单源最短路经问题,最小生成树问题等.

缓存算法

- 成 - FeedzShare
来自: 小彰 - FeedzShare  . 发布时间:2011年09月25日,  已有 2 人推荐. 没有人能说清哪种缓存算法由于其他的缓存算法. (以下的几种缓存算法,有的我也理解不好,如果感兴趣,你可以Google一下  ). 大家好,我是 LFU,我会计算为每个缓存对象计算他们被使用的频率.