其他

关于红包分配的问题

2018-10-25  本文已影响2人  _小老虎_
方法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:线段切割法

何谓线段切割法?我们可以把红包总金额想象成一条很长的线段,而每个人抢到的金额,则是这条主线段所拆分出的若干子线段。

WX20181025-000710@2x.png

如何确定每一条子线段的长度呢?由“切割点”来决定。当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)  


上一篇 下一篇

猜你喜欢

热点阅读