python抢红包程序算法_Python 抢红包算法模拟

抢红包算法模拟

本篇内容为抢随机红包模拟算法,仅供参考。

方法

本篇使用的是二倍均值法,在此之前,先大概讲下普通随机法。

普通随机方法

该方法的原理是:每次都以 [最小值,剩余金额值] 之间进行随机取值。

假设红包金额为 88.88,红包数量为 8 个,那么第一个人领取金额将从 [0.01, 88.88] 之间进行取值,假设取值为 20.20,那么剩余的金额为 68.68。

第二个领取金额将从 [0,01, 68.68] 之间进行取值,以此类推...

这里可以明显看出此方法的弊端,前面领取红包的金额区间更大,也就更容易获取更大的红包金额。下面看二倍均值法的原理。

二倍均值法

方法实现的原理是:每次以 [最小值,红包剩余金额 / 人数 * 2] 的区间进行取值。

假设红包金额为 88.88,红包数量为 8 个,理想情况下,方法的实现效果:

第一个人领取红包金额区间为 [0.01, 88.88 / 8 * 2],即是 [0.01, 22.22] 之间随机获取金额数。假设取平均值 11.11,则剩余金额 77.77;

第二个人领取红包金额区间为 [0.01, 77.77 / 7 * 2],即是 [0.01, 22.22] 之间随机获取金额数。假设取平均值 11.11,则剩余金额 66.66;

以此类推...

该方法也不是完美的,上述是非常理想情况下红包的领取金额,同时每个人获取金额区间相对公平。但是当其中一个人在区间取值接近最小值或者最大值都会对后面的区间造成影响。当取到接近最小值时,后面领取红包金额区间将会变大;反之,则变小。这也是该方法的弊端。

代码实现

# -*- coding: utf-8 -*-

'''

@File: red_packet.py

@Time: 2020/01/29 20:41:36

@Author: 大梦三千秋

@Contact: yiluolion@126.com

'''

# Put the import lib here

import random

def get_random_red_packet(total_amount, quantities):

'''抢红包函数

Args:

total_amount: 红包总金额

quantities: 红包个数

Returns:

返回每人领取红包的金额数

'''

# 用以存储每个人领取的红包金额

amount_list = []

# 抢红包人数

person_num = quantities

# 涉及红包金额可带 2 位小数部分

# 使用先乘 100 计算,再除 100 处理小数点部分

cur_total_amount = total_amount * 100

# 这里采用的是二倍均值法

# 除最后一人,先对前面领取红包金额进行处理

# 最后剩下的金额,即是最后一人的金额

for _ in range(quantities - 1):

amount = random.randint(1, cur_total_amount // person_num * 2)

# 每次减去当前随机金额,用剩余金额进行下次随机获取

cur_total_amount -= amount

person_num -= 1

amount_list.append(amount / 100)

amount_list.append(cur_total_amount / 100)

# print(sum(amount_list))

return amount_list

def main():

amount_list = get_random_red_packet(88.88, 8)

for amount in amount_list:

print('红包金额:{}'.format(amount))

if __name__ == "__main__":

main()

实现效果

红包金额:18.64

红包金额:10.32

红包金额:9.82

红包金额:9.72

红包金额:5.11

红包金额:19.16

红包金额:15.15

红包金额:0.96

延伸

线段切割法

该方法的思路是:把红包总金额当成一条线段,每个人领取红包金额即是该线段拆分的子线段。

当红包数量为 i 时,也就是 i 个人抢红包。对线段进行切割,确定 i - 1 个切割点。

当切割点确定,也就是子线段长度确定。领取红包时只需依次领取子线段对应金额数即可。

以上就是本篇的主要内容

欢迎关注微信公众号《书所集录》

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值