我的红包分配算法

数字较均匀

  /**
     * 将数值随机分成N份,数字较均匀,采用先算平均值,再在平均值基础上增减
     * @param num 基数
     * @param n 份数
     * @param scale 波动范围
     * @return
     */
    public static int[] randDivide(int num, int n, int scale){
        if(n < 1){
            n = 1;
        }
        int[] data = new int[n];
        if(num <= n){
            Arrays.fill(data, 1);
            return data;
        }

        //先平均分配
        int avg = num/n;
        Arrays.fill(data, avg);
        //不能整除的情况
        int last = num - avg*(n-1);
        data[n-1] = last;

        //波动范围,不超过平均数
        if(scale < 1 || scale > avg){
            scale = avg;
        }

        //红包算法
        Random random = new Random();
        for(int i = 0; i < n; ++i){
            int add = random.nextInt(scale);
            data[i] = data[i] - add;
            int idx = (i+1)%n;
            data[idx] = data[idx] + add;
        }
        return data;
    }

数字波动较大

/**
     * 将数值随机分成N份,数字变化较大,采用平均值倍数波动
     * @param num 基数
     * @param n 份数
     * @param times 波动倍率
     * @param used 倍率波动使用次数
     * @return
     */
    public static int[] randDivide1(int num, int n, int times, int used){
        if(n < 1){
            n = 1;
        }
        int[] data = new int[n];
        //不够分配直接返回
        if(num <= n){
            Arrays.fill(data, 1);
            return data;
        }

        Random random = new Random();
        for(int i = 0; i < n; ++i){
            //剩余个数
            int left = n-i;
            //限制大倍率使用次数
            if(i >= used){
                times = 2;
            }
            //大倍率自动衰减
            if(times > left){
                times = left;
            }

            //平均值波动倍数
            int avg = num/left;
            int max = avg * times;
            int min = avg / times;
            //最大值不能超过,保证剩下的数据够分配
            if(max > num - left){
                max = num - left;
            }

            int range = max - min;
            int randed;
            if(range < 1){
                randed = min;
            }else{
                randed = max - random.nextInt(range);
            }
            data[i] = randed;
            num -= randed;
        }

        //打乱顺序
        for(int i=0; i<n; ++i){
            int idx = random.nextInt(n);
            if(i == idx){
                continue;
            }
            int temp = data[i];
            data[i] = data[idx];
            data[idx] = temp;
        }
        return data;

    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值