转载

一个红包随机分配算法

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

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

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 
原文  http://www.letiantian.me/2016-04-23-red-envelope/
正文到此结束
Loading...