美文网首页
实现抢红包算法

实现抢红包算法

作者: 492284513d5a | 来源:发表于2020-04-04 21:16 被阅读0次

    发出一个固定金额的红包,由若干人来抢,需要满足哪些规则?

    1.所有人抢到金额之和等于红包金额,不能超过,也不能少于。
    2.每个人至少抢到一分钱。
    3.要保证所有人抢到金额的几率相等。

    一般想到的是每次抢红包的时候直接随机就好,随机的上限是剩余的红包余额。
    每次抢到的金额 = 随机区间(0,剩余金额)
    但是这样是有问题的。先抢的人会有很大的优势,越往后的人随机的金额越小
    例:
    假设有10个人,红包总额100元。
    第一个人的随机范围(0,100元),平均可以抢到50元。
    假设第一人随机到50元,剩余金额是100-50 = 50元。
    第二个人的随机范围是(0,50元),平均可以抢到25元。
    以此类推,每一次随机范围越来越小。

    二倍均值法

    剩余红包金额为M,剩余人数为N,那么有如下公式:
    每次抢到的金额 = 随机区间(0,M/N X 2)
    这个公式 ,保证了每次随机金额的平均值是相等的,不会因为抢红包的先后顺序而造成不公平。
    例:
    假设有10个人,红包总额100元。
    (100 / 20 )x 2 = 20 所以第一个人的随机范围是(0,20 ),平均可以抢到10元。
    假设第一个人随机到10元,那么剩余金额是100-10 = 90 元。
    90/9X2 = 20, 所以第二个人的随机范围同样是(0,20 ),平均可以抢到10元。
    假设第二个人随机到10元,那么剩余金额是90-10 = 80 元。
    80/8X2 = 20, 所以第三个人的随机范围同样是(0,20 ),平均可以抢到10元。
    以此类推,每一次随机范围的均值是相等的。

    import java.util.*;
    
    public class WeiXinRedPackage1 {
    
    
    public static void main(String[] args) {
        double sum = 0;
        ArrayList<Double> res 
               = WXRedPackageAlgorithm(10,3);
    
        for(double money:res) {
            sum += money;
            System.out.print(money +" ");
        }
    
        System.out.println();
        System.out.println(sum);     
    }
    
    private static ArrayList<Double> WXRedPackageAlgorithm(double restMoney,int restNum){                
        ArrayList<Double> res 
                 = new ArrayList<>(restNum);
    
        Random random=new Random();
        while(restNum>1) {
            //最大的红包为:两倍的平均红包大小
            double max=(restMoney/restNum) * 2;
    
            //产生[0,1)之间的随机数
            double r=random.nextDouble();
    
            //抢到的红包区间[0,max)
            double money = r * max;
            if(money<0.01)
                money = 0.01;
            else 
                money= Math.floor(money*100)/100;        
    
            res.add(money);
    
            restNum--;
            restMoney -= money; 
        }   
    
        //最后一个红包为剩余余额
        res.add(Math.floor(restMoney*100)/100 );
        return res;
    }
    }
    
    #!user/bin/env python
    #-*- coding utf-8 -*-
    # author:liruikun
    import random
    # summoney=input("please input the amount of money:")
    # divide_n=input("divide into?:")
    
    def hongbao(money,n):
        k=n
        sum=0#sum为前n个人抢得的总和,为了方便计算最后一个人的金额,初始值为0
        round=n#剩余人次
        while k>1:
            current_money = money  # 当前剩余的钱,初始值为money
            for i in range(1,n+1):
                get_money=random.randint(0,int(2*current_money/round))
                print('id[%s] have geted money %s'%(i,get_money))
                current_money -= get_money
                round -= 1
                sum += get_money
                k-=1
    
    
        if k==1:#最后一个人,分得剩余的所有
            print('id[%s] have geted money %s'%(n,money-sum))
        print(current_money)
    hongbao(100,10)
    

    相关文章

      网友评论

          本文标题:实现抢红包算法

          本文链接:https://www.haomeiwen.com/subject/sjqsphtx.html