精华内容
下载资源
问答
  • 红包分配算法

    千次阅读 2019-01-12 22:01:19
    实现红包分配要有如下要求: (1)每个人抢到的红包金额必须为随机的。 (2)所有人抢到的红包总额等于红包总金额。 (3)最少红包金额为0.01。 解法1:切割法 本质为发完红包后根据人数进行划分。(先划分,再根据...

    本文为阅读公众号“程序员小灰”的一篇文章有感。仅作为自己的笔记而已。
    实现红包分配要有如下要求:
    (1)每个人抢到的红包金额必须为随机的。
    (2)所有人抢到的红包总额等于红包总金额。
    (3)最少红包金额为0.01。

    解法1:切割法
    本质为发完红包后根据人数进行划分。(先划分,再根据顺序分配)何谓线段切割法?我们可以把红包总金额想象成一条很长的线段,而每个人抢到的金额,则是这条主线段所拆分出的若干子线段。

    在这里插入图片描述

    如何确定每一条子线段的长度呢?由“切割点”来决定。当N个人一起抢红包的时候,就需要确定N-1个切割点。

    因此,当N个人一起抢总金额为M的红包时,我们需要做N-1次随机运算,以此确定N-1个切割点。随机的范围区间是(1, M)。

    当所有切割点确定以后,子线段的长度也随之确定。这样每个人来抢红包的时候,只需要顺次领取与子线段长度等价的红包金额即可。

    这就是线段切割法的思路。在这里需要注意以下两点:

    1.当随机切割点出现重复,如何处理。
    2.如何尽可能降低时间复杂度和空间复杂度。

    算法实现:

    public static void main(String[] args) {
    Integer totalAmount=1000;//红包金额  分
    		Integer totalPeopleNum=10;//红包个数
    		List<Integer> list=new ArrayList<Integer>();
    		Random random = new Random();
    		
    		while (list.size()<=totalPeopleNum) {
    			int i=random.nextInt(totalAmount)+1;//最低1分钱
    			if(list.indexOf(i)<0){//非重复切割添加到集合
    				list.add(i);
    			}
    		}
    		Collections.sort(list);
    		int  flag=0;
    		int fl=0;
    		for (int i=0;i<list.size();i++) {
    			int temp=list.get(i)-flag;
    			flag=list.get(i);
    			fl+=temp;
    			System.out.println("红包切割金额"+AmountUtil.div(temp,100));
    		}
    		//最后一个红包
    		list.add(totalAmount-fl);
    		System.out.println("红包切割金额"+AmountUtil.div(AmountUtil.sub(totalAmount, fl),100));
    		
    		System.out.println(fl+AmountUtil.sub(totalAmount, fl));
    }
    --------------------- 
    作者:楓楓楓楓楓 
    来源:CSDN 
    原文:https://blog.csdn.net/feng905001561/article/details/84768239 
    版权声明:本文为博主原创文章,转载请附上博文链接!
    

    解法2:二倍均值法
    设抢到的金额为X,剩余的红包金额为T,剩余的红包数量为N

    X=Math.random(0,T/N*2)

    保证了每次随机金额的平均值是相等的,不会因为抢红包的先后顺序而造成不公平。
    算法实现:

    //发红包算法,金额参数以分为单位
    public
     
    static
     
    List
    <
    Integer
    > divideRedPackage(
    Integer
     totalAmount, 
    Integer
     totalPeopleNum){
        
    List
    <
    Integer
    > amountList = 
    new
     
    ArrayList
    <
    Integer
    >();
        
    Integer
     restAmount = totalAmount;
        
    Integer
     restPeopleNum = totalPeopleNum;
        
    Random
     random = 
    new
     
    Random
    ();
        
    for
    (
    int
     i=
    0
    ; i<totalPeopleNum-
    1
    ; i++){
            
    //随机范围:[1,剩余人均金额的两倍),左闭右开
            
    int
     amount = random.nextInt(restAmount / restPeopleNum * 
    2
     - 
    1
    ) + 
    1
    ;
            restAmount -= amount;
            restPeopleNum --;
            amountList.add(amount);
        }
        amountList.add(restAmount);
        
    return
     amountList;
    }
    public
     
    static
     
    void
     main(
    String
    [] args){
        
    List
    <
    Integer
    > amountList = divideRedPackage(
    5000
    , 
    30
    );
        
    for
    (
    Integer
     amount : amountList){
            
    System
    .
    out
    .println(
    "抢到金额:"
     + 
    new
     
    BigDecimal
    (amount).divide(
    new
     
    BigDecimal
    (
    100
    )));
        }
    }
    
    展开全文
  • 主要介绍了php仿微信红包分配算法的实现方法,涉及简单的php数学运算与字符串操作相关技巧,需要的朋友可以参考下
  • 红包分配算法代码实现发给大家,祝红包大丰收! #coding=gbk import random import sys #print random.randint(0, 99) #print "====", random.uniform(0, 0.99) def calRandomValue(min, max, total, num): print ...
  • 微信红包分配算法

    2021-02-08 22:07:32
    微信红包分配算法 public class RedPackageUtil { //设置金额限额 private static final float MINMONEY = 0.01f; private static final float MAXMONEY = 200f; /** * 判断金额是否合法 * @param money 总...

    微信红包分配算法

    public class RedPackageUtil {
        //设置金额限额
        private static final float MINMONEY = 0.01f;
        private static final float MAXMONEY = 200f;
    
        /**
         * 判断金额是否合法
         * @param money 总金额
         * @param count 红包个数
         * @return
         */
        private boolean isRight(float money,int count){
            double  avg = money/count;
            if (avg > MAXMONEY || avg < MINMONEY){
                return false;
            }
            return true;
        }
    
        //用随机方法产生一个在最大值和最小值之间的一个红包,并判断该红包是否合法,
        // 是否在产生这个红包之后红包金额变成负数。另外,在这次产生红包值较小时,下一次就产生一个大一点的红包。
        private float randomRedPacket(float money,float mins,float maxs,int count){
            if(count==1) {
                return (float)(Math.round(money*100))/100;
            }
            if(mins == maxs) {
                return mins;//如果最大值和最小值一样,就返回mins
            }
            float max = maxs>money?money:maxs;
            float one = ((float)Math.random()*(max-mins)+mins);
            one = (float)(Math.round(one*100))/100;
            float moneyOther = money - one;
            if(isRight(moneyOther,count-1)) {
                return one;
            } else{
                //重新分配
                float avg = moneyOther / (count-1);
                if(avg<MINMONEY) {
                    return randomRedPacket(money,mins,one,count);
                }else if(avg>MAXMONEY) {
                    return randomRedPacket(money,one,maxs,count);
                }
            }
            return one;
        }
    
        private static final float TIMES = 2.1f;
    
        public List<Float> splitRedPackets(float money, int count){
            if(!isRight(money,count)) {
                return null;
            }
            List<Float> list = new ArrayList<Float>();
            float max = (float)(money*TIMES/count);
    
            max = max>MAXMONEY?MAXMONEY:max;
            for(int i=0;i<count;i++) {
                float one = randomRedPacket(money,MINMONEY,max,count-i);
                list.add(one);
                money-=one;
            }
            return list;
        }
    
        public static void main(String[] args) {
            RedPackageUtil redPackageUtil = new RedPackageUtil();
            System.out.println(redPackageUtil.splitRedPackets(100,24));
        }
    }
    
    展开全文
  • 本文实例讲述了 php 仿微信红包分配算法的实现方法 分享给大家供大家参考 具体如 下 /*  * 红包分配把一定金额随机分配给指定人数  *  * @param int $money 用于分配的金额  * @param int $num 分配...
  • 一个不严谨的红包分配算法 /** * 红包分配算法 * @param total 总金额 (单位: 分) * @param num 总份数 * @return */ public static Map<String, Object> lottery(int total, int num) { Map<String,...

    一个不严谨的红包分配算法

    import java.util.ArrayList;
    import java.util.List;
    import java.util.Random;
    import java.util.concurrent.ThreadLocalRandom;
    
    public class RedPacketUtils {
    
        /**
         * 红包分配算法
         * 
         * @param total     总金额 (单位: 分)
         * @param count     总份数
         * @return
         */
        public static List<Integer> random(final int total, final int count) {
            if (total <= 0) { 
                throw new IllegalArgumentException("The total must be greater than 0.");
            }
            if (count <= 0) { 
                throw new IllegalArgumentException("The count must be greater than 0.");
            }
            int restMoney = total;
            int restCount = count;
            Random random = ThreadLocalRandom.current();
            List<Integer> data = new ArrayList<Integer>(count);
            // 随机发前 totalCount - 1 个红包, 最后一个不需要随机
            for (int i = 0; i < count - 1; i++) {
                // 最少1分钱, 最多不超过剩下金额平均数的2倍
                int threshold = (restMoney / restCount * 2);
                int item = random.nextInt(threshold) + 1;
                data.add(item);
                restMoney -= item;
                restCount--;
            }
            // 最后一个红包不需要随机
            data.add(restMoney);
            return data;
        }
    
        /**
         * 红包分配算法
         * 
         * @param total     总金额 (单位: 分)
         * @param count     总份数
         * @param min       包下限 (单位: 分)
         * @param max       包上限 (单位: 分)
         * @param factor    浮动阈 [0.0f, 1.0f]
         * @return
         */
        public static List<Integer> random(final int total, final int count, 
                                           final int min, final int max, final float factor) {
            if (total <= 0) { 
                throw new IllegalArgumentException("The total must be greater than 0.");
            }
            if (count <= 0) { 
                throw new IllegalArgumentException("The count must be greater than 0.");
            }
            if (min <= 0) { 
                throw new IllegalArgumentException("The min must be greater than 0.");
            }
            if (max <= 0) { 
                throw new IllegalArgumentException("The max must be greater than 0.");
            }
            if (total < count * min || total > count * max) {
                throw new IllegalArgumentException("The total must be between count * min and count * max.");
            }
            if (factor < 0.0f || factor > 1.0f) {
                throw new IllegalArgumentException("The factor must be between 0 and 1.");
            }
            Random random = ThreadLocalRandom.current();
            List<Integer> data = new ArrayList<Integer>(count);
            // 平均分配红包
            int avg = total / count;
            int rest = total - avg * count;
            for (int i = 0; i < count; i++) {
                data.add(i < rest ? avg + 1 : avg);
            }
            // 根据浮动阈重新标定
            if (factor <= 0 || factor > 1) {
                return data;
            }
            for (int i = 0; i < count - 1; i++) {
                int itemThis = data.get(i);
                int itemNext = data.get(i + 1);
                boolean isLt = itemThis < itemNext;
                int rangeThis = isLt ? max - itemThis : itemThis - min;
                int rangeNext = isLt ? itemNext - min : max - itemNext;
                int rangeBound = (int) Math.ceil(factor * (Math.min(rangeThis, rangeNext) + 1));
                int mark = random.nextInt(rangeBound) + 1;
                int rule = isLt ? mark : -mark;
                data.set(i, data.get(i) + rule);
                data.set(i + 1, data.get(i + 1) - rule);
            }
            return data;
        }
    
    }
    
    展开全文
  • 红包分配算法代码实现发给大家,祝红包大丰收!#coding=gbkimport randomimport sys#print random.randint(0, 99)#print "====", random.uniform(0, 0.99)def calRandomValue(min, max, total, num):print min, max,...

    红包分配算法代码实现发给大家,祝红包大丰收!

    #coding=gbk

    import random

    import sys

    #print random.randint(0, 99)

    #print "====", random.uniform(0, 0.99)

    def calRandomValue(min, max, total, num):

    print min, max, total, num

    total = float(total)

    num = int(num)

    min = 0.01

    if(num return

    if num == 1:

    print "第%d个人拿到红包数为:%.2f" %(num, total)

    return

    i = 1

    total_money = total

    #rtotal = (total*100 - min*num*100)/100

    while( i max = total_money - min*(num- i)

    k = int((num-i)/2)

    if num -i k = num -i

    max = max/k

    monney = random.randint(int(min*100), int(max*100))

    monney = float(monney)/100

    total_money = total_money - monney

    print "第%d个人拿到红包数为:%.2f, 余额为: %.2f" %(i, monney, total_money)

    i += 1

    print "第%d个人拿到红包数为:%.2f, 余额为: %.2f" %(i, total_money, 0.0)

    if __name__ == "__main__":

    min = sys.argv[1]

    max = sys.argv[2]

    total = sys.argv[3]

    num = sys.argv[4]

    calRandomValue(min, max, total, num)

    python 2.py 0.01 10 20 30

    0.01 10 20 30

    第1个人拿到红包数为:1.34, 余额为: 18.66

    第2个人拿到红包数为:1.06, 余额为: 17.60

    第3个人拿到红包数为:1.08, 余额为: 16.52

    第4个人拿到红包数为:0.98, 余额为: 15.54

    第5个人拿到红包数为:0.88, 余额为: 14.66

    第6个人拿到红包数为:0.48, 余额为: 14.18

    第7个人拿到红包数为:0.26, 余额为: 13.92

    第8个人拿到红包数为:0.90, 余额为: 13.02

    第9个人拿到红包数为:0.12, 余额为: 12.90

    第10个人拿到红包数为:0.41, 余额为: 12.49

    第11个人拿到红包数为:0.43, 余额为: 12.06

    第12个人拿到红包数为:0.63, 余额为: 11.43

    第13个人拿到红包数为:0.36, 余额为: 11.07

    第14个人拿到红包数为:0.25, 余额为: 10.82

    第15个人拿到红包数为:1.38, 余额为: 9.44

    第16个人拿到红包数为:0.17, 余额为: 9.27

    第17个人拿到红包数为:0.79, 余额为: 8.48

    第18个人拿到红包数为:0.52, 余额为: 7.96

    第19个人拿到红包数为:0.44, 余额为: 7.52

    第20个人拿到红包数为:1.15, 余额为: 6.37

    第21个人拿到红包数为:0.13, 余额为: 6.24

    第22个人拿到红包数为:0.76, 余额为: 5.48

    第23个人拿到红包数为:1.32, 余额为: 4.16

    第24个人拿到红包数为:0.80, 余额为: 3.36

    第25个人拿到红包数为:0.16, 余额为: 3.20

    第26个人拿到红包数为:0.27, 余额为: 2.93

    第27个人拿到红包数为:1.82, 余额为: 1.11

    第28个人拿到红包数为:0.45, 余额为: 0.66

    第29个人拿到红包数为:0.27, 余额为: 0.39

    第30个人拿到红包数为:0.39, 余额为: 0.00

    以上所述就是本文的全部内容了,希望大家能够喜欢。

    展开全文
  • 红包分配算法代码实现发给大家,祝红包大丰收!1234567891011121314151617181920212223242526272829303132333435363738394041#coding=gbkimport randomimport sys#print random.randint(0, 99)#print "====", random...
  • 红包分配算法,总金额分配算法

    千次阅读 2020-02-25 12:24:39
    类似于红包分配方式,解释说明都写在类里了 解释和说明 * 1 抢红包的期望收益应与先后顺序无关 2 保证每个用户至少能抢到一个预设的最小金额,人民币红包设置的最小金额一般是0.01元,如果需要发其他货币类型的...
  • 简单的红包分配算法

    2016-01-12 18:14:22
    今天在群里听朋友说公司要他写一个红包分配算法,闲来无事,就临时帮他写了一下。 废话不多说,直接上代码: $num = 3; //红包个数 $total = 10; //红包总金额 $scale = array(); //比例数组 for($i=0; $i...
  • 红包分配算法的实现

    2021-03-28 15:35:23
    最近在做一个抢红包的项目,关于红包怎么分配,才能达到一个最佳效果,我做了一些调研以及对应的实现方案。 关于每个红包金额的范围采用二倍均值算法[0 .01 - M/N * 2],其中M表示总金额,N表示红包个数。比如:总...
  • Java模拟微信红包分配算法

    千次阅读 2017-03-28 23:10:00
     * Java模拟微信红包分配算法(还有点问题,明天优化一下)  * @author Administrator  *  */ public class Demo10 { /* * 1.红包总结不超过200*100,单位(分) * 2.每个红包都要有钱,最低不能低于1...
  • 本文实例讲述了php仿微信红包分配算法的实现方法。分享给大家供大家参考,具体如下:/*** 红包分配:把一定金额随机分配给指定人数** @param int $money 用于分配的金额* @param int $num 分配人数*/function Random...
  • 红包分配算法 http://www.ucai.cn/ask/detail?queid=1967 大家过年期间有没有抢红包呢?有一种随机红包,是指定了红包数和总额。然后就将总金额随机分为指定的份数,额度各不相同,并且各红包金额数目之和正好与...
  • 记一次面试-简单的红包分配算法简介解题思路代码 简介 是这个样子的,前段时间去面试,接近尾声时面试官突然提出这样一个问题:将一个100元的红包,分为20份,每份最低3元,最高不得超过6元;瞬间一脸懵B,之前确实是对算法...
  • 公司有个红包分发业务模块,需要红包随机生成金额,克提供参数为: 1、红包金额(最小精确到厘:0.001,数据库是用int表示,1元也就是1000厘) 2、红包发放数量 3、红包金额上限 4、红包金额下限 5、金额精度(精度...
  • PHP红包分配算法

    2020-03-31 10:22:17
    <?php /** * User: phpmianshi.com * Date: 2020/3/31 * Time: 10:16 */ class redPack { /** * 测试红包生成 */ public function test(){ for($i=0;$i<5;$i++){ $n...
  • 我之前的博客中用c语言写了一个红包均分算法,用到的数据结构是链式数组,今日用堆改进此算法-相较...//使用堆完成红包分配算法 package main import "fmt" //用于影响分配结果的因子 var yz float32 = 0 type ...
  • 我的红包分配算法

    2020-05-20 17:46:21
    } //红包算法 Random random = new Random(); for(int i = 0; i ; ++i){ int add = random.nextInt(scale); data[i] = data[i] - add; int idx = (i+1)%n; data[idx] = data[idx] + add; } return data; } 数字波动...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,302
精华内容 1,320
关键字:

红包分配算法