方法1:二倍均值法
剩余红包金额为M,剩余人数为N,那么有如下公式:
每次抢到的金额 = 随机区间 (0, M / N X 2)
这个公式,保证了每次随机金额的平均值是相等的,不会因为抢红包的先后顺序而造成不公平。
- 举个栗子:
假设有10个人,红包总额100元。
100/10X2 = 20, 所以第一个人的随机范围是(0,20 ),平均可以抢到10元。
假设第一个人随机到10元,那么剩余金额是100-10 = 90 元。
90/9X2 = 20, 所以第二个人的随机范围同样是(0,20 ),平均可以抢到10元。
假设第二个人随机到10元,那么剩余金额是90-10 = 80 元。
80/8X2 = 20, 所以第三个人的随机范围同样是(0,20 ),平均可以抢到10元。
以此类推,每一次随机范围的均值是相等的。
我写了一段:
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
# Created by changyanlong
# Project: der
import time
import random
import copy
import re
import os
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
def rand_send_pack(total_money=15,redpack_count=5,result_arr=[]):
if redpack_count > 1:
bonus = random.uniform(0, total_money/redpack_count *2)
rand_send_pack(
(total_money-bonus),
(redpack_count-1)
)
elif redpack_count == 1:
bonus = total_money
else:
pass
print round(bonus,2)
rand_send_pack()
方法2:线段切割法
何谓线段切割法?我们可以把红包总金额想象成一条很长的线段,而每个人抢到的金额,则是这条主线段所拆分出的若干子线段。

如何确定每一条子线段的长度呢?由“切割点”来决定。当N个人一起抢红包的时候,就需要确定N-1个切割点。
因此,当N个人一起抢总金额为M的红包时,我们需要做N-1次随机运算,以此确定N-1个切割点。随机的范围区间是(1, M)。
当所有切割点确定以后,子线段的长度也随之确定。这样每个人来抢红包的时候,只需要顺次领取与子线段长度等价的红包金额即可。
这就是线段切割法的思路。在这里需要注意以下两点:
- 当随机切割点出现重复,如何处理;
- 如何尽可能降低时间复杂度和空间复杂度。
代码如下
这段代码来自 https://blog.csdn.net/u011510825/article/details/80149029
import random
def line_cut(total, number):
"""
生成切断点 (list)
:param total: 总数
:param number: 人数
:return:
"""
cut_num = number - 1
random_list = []
for i in range(cut_num):
while True:
random_num = random.randint(1, total)
if random_num not in random_list:
random_list.append(random_num)
break
return sorted(random_list)
def amount(total, random_list):
"""
根据切割点分配金额
:param total:
:param random_list:
:return:
"""
test_total = 0
for i in range(len(random_list)+1):
try:
num = random_list[0] if i == 0 else random_list[i+1] - random_list[i]
except:
try:
num = total - random_list[i]
except:
num = total - test_total
test_total += num
print('第{}个人分配金额{}, 剩余金额{}'.format(i+1, num, total-test_total))
if __name__ == '__main__':
total, number = 100, 10
random_list = line_cut(total, number)
amount(total, random_list)
网友评论