精华内容
下载资源
问答
  • 闲来无事,突然想起来红包随机分配算法要怎么实现,经过一阵子思考,勉强用CAS操作和锁两种方式实现了该算法,但对于CAS实现的方式心里没底,我没办法证明算法的正确性,只能简单的重复执行该算法10000次这种恶劣的...

    闲来无事,突然想起来红包随机分配算法要怎么实现,经过一阵子思考,勉强用CAS操作和锁两种方式实现了该算法,但对于CAS实现的方式心里没底,我没办法证明算法的正确性,只能简单的重复执行该算法10000次这种恶劣的方式来验证。真心希望有这方面经验的朋友可以交流一下,互相学习。还有个问题是,我把两种算法分别执行10000次的记录耗时,结果发现锁方式比CAS快,这有点出乎意料之外。但事后又想想CAS方式在竞争比较大的情况下,不停尝试然后失败确实挺耗费时间的。

    package test1.Test1;

    import java.math.BigDecimal;

    import java.util.Iterator;

    import java.util.concurrent.ConcurrentLinkedQueue;

    import java.util.concurrent.CountDownLatch;

    import java.util.concurrent.ExecutorService;

    import java.util.concurrent.Executors;

    import java.util.concurrent.atomic.AtomicInteger;

    import java.util.concurrent.atomic.AtomicReference;

    /**

    * 红包随机分配算法,每一个红包必须大于最小值小于平均值的2倍

    *

    */

    public class HongBaoAlgorithm {

    //每个红包的最小金额

    private static final double MIN = 0.01;

    class HongBao{

    //红包总金额

    private AtomicReference amount = new AtomicReference();

    //红包个数

    private AtomicInteger count;

    //红包总金额

    private BigDecimal hbAmount;

    private int hbCount;//红包个数

    //上面的两对参数分别对应CAS和锁操作

    public HongBao(double amount,int count){

    this.amount.set(new BigDecimal(amount));

    this.count = new AtomicInteger(count);

    this.hbAmount = new BigDecimal(amount);

    this.hbCount = count;

    }

    /**

    * 用CAS操作随机分配一个红包

    * @return

    */

    public double assignHongBao(){

    while(true){

    //如果红包个数为0,则表示红包也被抢完,返回0

    if(count.get()<=0){

    return 0.0;

    }

    //如果是最后一个红包则直接将剩余的金额返回

    if(count.get()==1){

    BigDecimal c = amount.get();

    if(amount.compareAndSet(c, new BigDecimal(0))){

    count.decrementAndGet();

    return c.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();

    }else{//如果最后一个红包金额修改失败,则表示最后一个红包已被抢走,已没有剩余红包,直接返回0

    return 0.0;

    }

    }

    BigDecimal balanceAmount = amount.get();

    int balanceCount = count.get();

    if(balanceCount==0){

    return 0.0;

    }

    //求出剩余红包金额和个数的平均值

    double avg = balanceAmount.divide(new BigDecimal(balanceCount),8,BigDecimal.ROUND_HALF_UP).doubleValue();

    //随机获取一个MIN到2倍平均值之间的值

    double cur = getRandom(MIN, avg*2);

    //获取剩余金额和分配金额的差值

    double b = balanceAmount.add(new BigDecimal(-cur)).doubleValue();

    //由于每个红包至少是MIN这么大,此处获取剩余红包个数应该有的最小的红包金额,

    //比如MIN=0.01,那么如果这次分配之后还剩2个红包,则金额至少要剩下2分钱,不然不够分

    double c = new BigDecimal(balanceCount-1).multiply(new BigDecimal(MIN)).doubleValue();

    //分配之后剩余金额b 需大于等于 剩余的最小值c,如果不满足则重新分配红包大小,直到满足要求

    while(b < c){

    cur = getRandom(MIN, avg*2);

    b = balanceAmount.add(new BigDecimal(-cur)).doubleValue();

    }

    //如果是最后一个红包则直接将剩余的金额返回,

    //在返回结果之前再一次执行这个判断的目的是为了在多线程情况如果在返回结果之前已经被抢到只剩最后一个的时候

    //还是返回随机获得金额的话则会导致总金额不会被抢完

    if(count.get()==1){

    BigDecimal c1 = amount.get();

    if(amount.compareAndSet(c1, new BigDecimal(0))){

    count.decrementAndGet();

    return c1.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();

    }else{//如果最后一个红包金额修改失败,则表示最后一个红包已被抢走,已没有剩余红包,直接返回0

    return 0.0;

    }

    }

    //CAS更新金额和个数同时成功,则返回随机分配的红包金额

    if(amount.compareAndSet(balanceAmount, balanceAmount.add(new BigDecimal(-cur)))){

    count.decrementAndGet();

    return cur;

    }

    }

    }

    /**

    * 用锁控制

    * @return

    */

    public synchronized double assignHongBao2(){

    //如果红包个数为0,则表示红包也被抢完,返回0

    if(hbCount==0){

    return 0.0;

    }

    //如果是最后一个红包则直接将剩余的金额返回

    if(hbCount==1){

    hbCount--;

    return hbAmount.doubleValue();

    }

    //求出剩余红包金额和个数的平均值

    double avg = hbAmount.divide(new BigDecimal(hbCount),8,BigDecimal.ROUND_HALF_UP).doubleValue();

    //随机获取一个MIN到2倍平均值之间的值

    double cur = getRandom(MIN, avg*2);

    //获取剩余金额和分配金额的差值

    double b = hbAmount.add(new BigDecimal(-cur)).doubleValue();

    //由于每个红包至少是MIN这么大,此处获取剩余红包个数应该有的最小的红包金额,

    //比如MIN=0.01,那么如果这次分配之后还剩2个红包,则金额至少要剩下2分钱,不然不够分

    double c = new BigDecimal(hbCount-1).multiply(new BigDecimal(MIN)).doubleValue();

    //分配之后剩余金额b 需大于等于 剩余的最小值c,如果不满足则重新分配红包大小,直到满足要求

    while(b < c){

    cur = getRandom(MIN, avg*2);

    b = hbAmount.add(new BigDecimal(-cur)).doubleValue();

    }

    hbAmount = hbAmount.add(new BigDecimal(-cur));

    hbCount--;

    return cur;

    }

    /**

    * 计算两个数之间的随机值,结果保留两位小数

    * @param begin

    * @param end

    * @return

    */

    private double getRandom(double begin,double end){

    double random = Math.random();

    double amount = random*(end - begin)+begin;

    BigDecimal bg = new BigDecimal(amount);

    return bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();

    }

    }

    private static void test(double hbAmount,int hbCount,int personCount) throws InterruptedException{

    HongBaoAlgorithm h = new HongBaoAlgorithm();

    final HongBao hb = h.new HongBao(hbAmount,hbCount);

    int THREAD_COUNT = personCount;

    ExecutorService pool = Executors.newFixedThreadPool(THREAD_COUNT);

    final ConcurrentLinkedQueue total = new ConcurrentLinkedQueue();

    final CountDownLatch latch = new CountDownLatch(THREAD_COUNT);

    for(int i=0;i

    pool.execute(new Runnable() {

    public void run() {

    double m = hb.assignHongBao();

    total.add(m);

    //if(m>0){

    //System.out.println(Thread.currentThread().getName()+"抢到:"+m);

    //}else{

    //System.out.println(Thread.currentThread().getName()+"没抢到红包");

    //}

    latch.countDown();

    }

    });

    }

    pool.shutdown();

    latch.await();

    double amount = 0.0;

    Iterator it = total.iterator();

    while(it.hasNext()){

    amount += it.next();

    }

    amount = new BigDecimal(amount).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();

    //如果分配到的总金额和传入的总金额不相等

    if(amount!=hbAmount){

    System.out.println("amount:"+amount);

    }

    //计算抢到的红包总额来判断跟设定的金额是否一致,从而判断算法的正确性,很恶劣的方式

    }

    public static void main(String[] args) throws InterruptedException{

    long start = System.currentTimeMillis();

    //执行10000次,验证一下正确率

    for(int i=0;i<10000;i++){

    //9个红包,10个人抢

    test(100, 9, 10);

    }

    System.out.println("用时:"+(System.currentTimeMillis()-start)+"ms");

    }

    }

    展开全文
  • 微信红包算法在知乎上面有个专题讨论,其实红包的发放的随机算法,有两种作法:java一、预生产:算法无外乎是在发红包的时候,随机去把金额生成到某个容器当中,而后要用的时候,一个一个的POP;微信二、实时随机dom...

    微信红包算法在知乎上面有个专题讨论,其实红包的发放的随机算法,有两种作法:java

    一、预生产:

    算法

    无外乎是在发红包的时候,随机去把金额生成到某个容器当中,而后要用的时候,一个一个的POP;微信

    二、实时随机dom

    用户在抢红包的时候,根据随机算法,算出此次用户要抢到多少测试

    本文讲的是第二种。优化

    之因此没弄第一种,是由于咱们的研发同窗张智哥,在之前的红包发放算法里面就是用的第二种,而我在征求他的意见看是否改为预生产的时候,他想偷个懒,不想再加表、动流程啥的。我想一想也是,动流程动出问题来了,到时候仍是得哥背锅。虽然做为研发一直都有丰富的背锅经验和强大的背锅心里,可是,可以少背个仍是少背个。spa

    今后,也就开始了我比较黑暗的调整算法、调整参数的过程。code

    红包算法关键是要简单、迅速的找出随机值,而这个坑,什么正态分布修正、什么平方后再开方取随机数优化,我都尝试过。orm

    结果很惨淡:要么是前面的拿大头的概率很大,要么是后面的拿大头的概率很大,而前面拿大头,或者后面拿大头,是咱们运营的大爷们吐槽咱们的随机算法作得不如微信好的一个重要缘由(尼玛谈需求的时候不讲,还弄了个随机数范围要在8%到74%之间作限制,以为不爽就让研发背锅)。

    get

    废话完了,说下个人算法:

    其实很简单,两个随机数,一个随机0到2;一个随机-1到1;两个随机数之和乘以均值,就是此次跑出来的随机数。而后再作下上下限的保护就好了。

    个人代码里面偷了个懒,只作了下限,没作上限的保护。由于毕竟是研究算法,不是实际生产环境代码。

    public static void dispath(int total, int people, int min){

    for(int i = 0; i < people - 1 ; i++ ){

    int leftPeople = people - i;

    double avg = Double.valueOf(total)/leftPeople;

    double ratio1 = getRandom(0, 2);

    double ratio2 = getRandom(-1, 1);

    double ratio = ratio1+ratio2;

    int cur = (int) Math.floor(ratio * avg) > min ? (int) Math.floor(ratio * avg) : min;

    // 扣减总额阅点数目

    total = total - cur;

    System.out.format("第 %d 个红包: %d 阅点,剩下: %d 阅点\n", i + 1, cur,total);

    }

    // 剩余的就是最后一个用户的阅点额度

    System.out.format("第 %d 个红包: %d 阅点,剩下: 0 阅点\n", people, total);

    }

    结果嘛,还马马虎虎,反正跑了几回测试,基本上还能够知足要求,反正最大和最小的,不会固定在某个地方出现了。

    展开全文
  • 红包随机算法&微信群红包随机算法

    千次阅读 2021-02-20 11:14:40
    1.前言 因疫情影响,部门 2021 年会以线上直播的形式进行,通过微信小程序展开。为活跃年会氛围,年会直播间会有抢红包环节。因产品要求,红包金额...所以这里可以抽象成如下算法: input: <sum, num, min, max>

    在这里插入图片描述

    1.前言

    因疫情影响,部门 2021 年会以线上直播的形式进行,通过微信小程序展开。为活跃年会氛围,年会直播间会有抢红包环节。因产品要求,红包金额要随机生成,所以这里涉及到指定红包总额、数量和最大最小值情况下如何生成红包金额。

    可以看出,红包随机金额生成的输入是一个四元组 <sum, num, min, max>,其中 sum 是红包总额,num 是红包数量,min 和 max 分别是红包最小最大值。所以这里可以抽象成如下算法:

    input: <sum, num, min, max>
    output: 随机红包金额数组
    

    因为法币都有最小单位,比如人民币是分,所以上面输入四元组均可视为整数。

    2.参考微信群红包算法

    本质上,这和微信群红包没什么区别,发出一个固定总金额的红包,指定红包数量,那么随机分配红包金额时需要满足哪些规则?
    (1)所有人抢到金额之和等于红包总金额,不能超过,也不能少于;
    (2)抢到的红包金额至少是一分钱;
    (3)要保证抢到红包的人获取到的红包金额是随机的。

    实际上,微信群红包的 min 是 1 分钱,max 是剩余红包金额均值的两倍,为什么是这两个值,因为这么做会保证随机值的期望值等于均值,来保证不会因为抢红包的先后顺序而造成不公平。这两个值是算法内设的,不提供给用户指定。另外总金额 sum 和数量 num 是由用户指定的。

    为什么微信群红包要搞一个最大上限,因为如果不设置一个最大上限,会出现一种不公平的现象。就是越在前边领取红包的同学,其可随机范围越大,获得大额红包的几率也越高。一旦前边的同学随机到一个较大的金额,后边的同学可以随机的范围就逐步收窄,抢红包就变成了一个拼手速的游戏了。

    实际上,微信群红包采用的是二倍均值法,也就是每次随机上限为剩余红包金额均值的两倍

    微信群红包金额分配算法是这样的:

    每次抢红包直接随机,随机的范围是[1, 剩余红包金额均值的两倍],单位分
    

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

    实际上微信群红包的算法虽然公平,但是有个缺陷,不过这个微信产品同学可以接受,只是对于用户来说体验并不是那么友好,因为有时发个群红包会出现下面这种最后两个之一红包金额非常大的情况。

    出现这种情况的原因是,上面的随机上限 max 为剩余红包金额均值的两倍,如果剩余红包金额均值越来越大,那么越是后抢期望越大,就会出现上面这种情况。当然,出现这种情况的概率非常小,需要除了最后两次之前的所有结果都小于剩余均值,即小金额。

    这说明了一个什么问题呢?红包金额随机分配算法不是一个标准算法,而是产品逻辑。 如果你是产品同学,你完全可以搞一个你想要的随机分配算法,比如随机范围严格在 [min, max] 之间,或者像微信群红包那样,每次抢红包时,max 是动态变化的。

    这里说下大家最关心的问题,就是如何才能抢到大红包。通过上面的介绍,结论就是除了最后两个红包金额之一有可能很大,因为每次都是在 [0.01 - 剩余均值*2] 之间随机,越往后剩余均值可能越大,导致最后两位抢时,期望最大。如果红包数量充足,那么最后两位抢才有可能获得大红包。但绝大部分情况是僧多粥少,需要拼手速才能抢到红包,这种情况下,你不能保证你是最后两位抢到红包的人。

    3.一个可用的随机算法

    此次年会产品同学开始跟我说需要像微信群红包那样的随机分配红包金额,但是仔细研究了微信群红包的算法,才发现产品同学想要的效果和微信群红包并不同,她想要的是红包金额严格随机范围在 [min, max]。

    在实现时要满足如下几个条件:
    (1)所有人抢到金额之和等于红包总金额,不能超过,也不能少于;
    (2)抢到的红包金额在 [min, max] 之间;
    (3)要保证抢到红包的人获取到的红包金额是随机的。

    下面给一个可行的随机分配算法。

    // min 最小金额分 max 最大金额分 num 红包数量 sum 红包总额分
    input:<min, max, num, sum>
    
    // 参数合法性校验
    step 1: min*num <= sum <= max*num 
    step 2: 将 num 个在 min 填入数组
    step 3: 循环随机一个范围为 [0, max - min] 数加到最小值数组中。如果随机数大于剩余金额,则取剩余金额作为随机数;如果累加值大于最大值,则取最大值与原值差值作为随机数。如果剩余金额为 0 结束循环
    step 4: 如果均值靠近 min 或 max,第三步分别会出现很多 min 或者 max,看起来不够随机。这里需要经过一轮或多轮遍历,将 (min, max) 之间的数减掉部分给到 min 或者从 max 获得部分
    step 5: 打乱数组顺序
    

    注意,在第四步消除最小值或最大值,是控制在一定比例还是完全消除,也是一个产品逻辑,需要由产品同学来定。下面的实现示例,只进行一轮循环,可能会存在少量最小值或最大值。

    下面以 NodeJS 为例,给出实现。

    // brief: 获取随机整数 [min, max]
    function random(min, max) {
      const range = max - min;
      const rand = Math.round(Math.random() * range);
      return min + rand;
    }
    
    // brief: 消除最小值和最大值
    function smooth(min, max, arr) {
      for (let i = 0; i < arr.length; i++) {
        if (!(min < arr[i] && arr[i] < max)) {
          continue
        }
        for (let j = 0; j < arr.length; j++) {
            // 消除最小值
            if (arr[j] === min) {
              let rm = Math.floor((arr[i] - min)/10)
              arr[i] -= rm
              arr[j] += rm
              break
            }
            // 消除最大值
            if (arr[j] === max) {
              let rm = Math.floor((max - arr[i])/10)
              arr[i] += rm
              arr[j] -= rm
              break
            }
        }
      }
    }
    
    // brief: 打乱数组顺序
    function shuffle(arr) {
      arr.sort(() => Math.random() - 0.5);
    }
    
    // brief: 生成随机整数数组
    function randnum(min, max, num, sum) {
      // step 1 检查参数
      if (min <= 0 || max <= 0 || num <= 0 || sum <= 0) {
        return [];
      }
      if (!(min * num <= sum && sum <= max * num)) {
        return [];
      }
    
      // step 2 将 num 个在 min 填入数组
      var arr = new Array(num).fill(min);
      
      // step 3 循环随机生成[0, max-min]加到最小值数组
      let leftTotal = parseInt(sum - min*num);
      LABEL:
      while(true) {
        for (let i = 0; i < num; i++) {
            let rand = random(0, parseInt(max-min));
            // 如果随机数大于剩余金额,则取剩余金额作为随机数
            if (rand > leftTotal) {
                rand = leftTotal;
            }
            // 如果累加值大于最大值,则取最大值与原值差值作为随机数
            if (arr[i] + rand > max) {
                rand = max - arr[i];
            }
            arr[i] += rand;
            leftTotal -= rand;
            if (leftTotal === 0) {
                break LABEL;
            }
        }
      }
      
      // step 4 消除大部分最小值和最大值
      smooth(min, max, arr)
      
      // step 5 打乱数组顺序
      shuffle(arr)
      
      return arr;
    }
    

    上面的代码可以在 Online NodeJS IDE 执行。

    下面采用两组入参,均值分别靠近最小值和最大值来观察多次运行后的输出结果。

    第一组入参,最小金额 5 元,最大金额 50 元,数量 10 个,总金额 100 元。均值 10 靠近最小值。

    // 单位为分
    console.log(randnum(500, 5000, 10, 10000))
    
    // 第一轮结果
    [ 516, 3317, 646, 515,  677, 636, 1861,  501, 518, 813 ]
    
    // 第二轮结果
    [ 724,  502,  500, 726, 2761, 2740, 500,  502,  522, 523 ]
    
    // 第三轮结果
    [ 500, 500, 1009, 899, 504, 4492, 500, 505,  551, 540 ]
    

    第二组入参,均值靠近最大值,最小金额 5 元,最大金额 50 元,数量 10 个,总金额 450 元。均值 45 靠近最大值。

    // 单位为分
    console.log(randnum(500, 5000, 10, 40000))
    
    // 第一轮结果
    [ 4832, 4999, 4953, 4990, 3515, 3929, 4835, 4572, 3482, 4893 ]
    
    // 第二轮结果
    [ 4868, 5000, 4901, 5000, 4733, 5000, 4106, 3804, 2588, 5000 ]
    
    // 第三轮结果
    [ 4999, 3493, 3795, 5000, 3210, 4849, 4867, 4985, 5000, 4802 ]
    

    从上面的实验结果可以看出,相同入参多次运行结果是不同的。如果均值靠近最小值或者最大值,结果可能分别会出现多个最小值和最大值,这个可以通过多次执行 smooth 函数来完全消除。


    参考文献

    [1] 漫画:如何实现抢红包算法?
    [2] 微信拼手气红包背后的算法逻辑

    展开全文
  • public class NumberRandomSplitUtil {/*** 把一个正整数随机拆分成count个正整数** @param totalNum* @param count* @return*/public static List random(int totalNum, int count) {// 创建一个长度的红包数组List...

    public class NumberRandomSplitUtil {

    /**

    * 把一个正整数随机拆分成count个正整数

    *

    * @param totalNum

    * @param count

    * @return

    */

    public static List random(int totalNum, int count) {

    // 创建一个长度的红包数组

    List redList = new ArrayList<>();

    int totalMoney = (totalNum);

    /*if (totalMoney < count || totalMoney < 1) {

    return redList; // 返回空的集合

    }*/

    //2. 进行随机分配

    Random rand = new Random();

    int leftMoney = totalMoney; // 剩余金额

    int leftCount = count; // 剩余份数

    // 随机分配公式:1 + rand.nextInt(leftMoney / leftCount * 2);

    for (int i = 0; i < count - 1; i++) {

    int money_ = 0;

    if (leftMoney > 0) {

    if ((leftMoney / leftCount * 2) < 1) {

    money_ = leftMoney;

    } else {

    money_ = 1 + rand.nextInt(leftMoney / leftCount * 2);

    }

    } else {

    money_ = 0;

    }

    redList.add(money_);

    if (money_ > 0) {

    leftMoney -= money_;

    leftCount--;

    }

    }

    // 把剩余的最后一个放到最后一个包里

    redList.add(leftMoney);

    return redList;

    }

    }

    展开全文
  • 红包随机算法Java实现

    2021-04-12 16:29:27
    工具:idea参考:微信红包算法以及带上下限的红包算法基于微信红包算法以及带上下限的红包算法优化,修改了部分极值时,报错的问题,例如0.03元的红包分为2份。import com.alibaba.fastjson.JSON;import org.junit....
  • 通过实验加强对基于顺序搜索的动态分区分配算法的理解和掌握。 加深理解有关存储结构的概念。 主存的分配和回收的实现与主存储器的管理方式有关的,通过本实验帮助学生理解在可变分区管理方式下应怎样实现主存空间...
  • 随机索引分配给数组或ArrayList中的每个值非常简单。 Collections.shuffle(coins);//if coins is array Collections.shuffle(Arrays.asList(coins));//if coins is an ArrayList 当您使用swap作为索引时,您将使用...
  • } /** * 平均分配&指定数量分配,多余的任务不予分配 * * @param users 人 * @param tasks 任务 * @param count 每人指定分配数量 * @return */ public static Map> allotOfAverage(List users, List tasks, Integer...
  • 先说场景: 有一批客户要分配到销售手里进行维护,一个客户的list集合,一个销售的list集合,要让销售分到的客户一样多,除非分配到最后客户数量不够每一个销售了,才进行随机分配,销售之间的客户数量只有一个客户...
  • 升级2:对每个样本添加权重,要求抽取概率按照权重分配。基础问题问题描述:从N个样本中随机抽取m个样本,要求每个样本被抽取的概率一致,求怎么样抽取?数据量为百万级。看到这个问题,最先想到的方法是,依次遍历...
  • 比如将100随机分配为10个,最小1,最大12PS:下面是我的实现方式(先生成一个10个数的数组,每个数组元素都是1,然后再进入循环,随机生成一个数组下标进行 +1,如果当前数组元素超过最大数12则不进行叠加)/最小1%, ...
  • 一、简单的平均算法 /* * 平均分配 */ public Map<String,List> allotOfAverage(List users,List tasks){ Map<String,List> allot=new ConcurrentHashMap<String,List>(); //保存分配的...
  • java 分配算法

    2021-02-26 10:13:19
    /** 随机分配*/public Map allotOfRandom(List users,List tasks){Map allot=new ConcurrentHashMap(); //保存分配的信息if(users!=null&&users.size()>0&&tasks!=null&&tasks.size()>...
  • 随机比例算法

    2021-02-09 16:35:36
    随机比例算法 缘起,由于业务需求的需要,需要在保持相对稳定的比例下,生成随机选择数。 应用场景 此类算法常用于限定资源下的,负载均衡算法,抽奖算法等等。关键点在需要保持在某个基数量下,按照比例分布随机...
  • 文章目录前言一、最优化问题的地形图二、Metropolis算法与模拟退火算法1.引入库2.读入数据三、局部搜索对Hopfield神经网络的应用四、局部搜索对最大割近似的应用五、选择邻居关系六、用局部搜索分类七、最佳响应动态...
  • //对list做拆分算法,源码:https://my.oschina.net/u/2391658/blog/703032 List> splitRes = listSplit.split(srcDatas,splitCopies); int preListSize = 0;//初始化第一份List的最小下标 for(int i=0;i List list...
  • )分配算法不难,但是用java写起来还是蛮巧妙的~ 觉得很有意思,遂记之。算法设计:1)总的任务数能被权重和整除,则每个人分配的数量就是:总任务数/权重和*权重2)总的任务数不能被权重和整除,则先按整除的数按1)的...
  • 循环首次适应算法 分配内存时不是从链首进行查找可以分配内存的空闲分区,而是从上一次 分配内存的空闲分区的下一个分区开始查找,直到找到可以为该进程分配内存 的空闲分区。 3.最佳适应算法 将空闲分区链中的空闲...
  • 微信红包分配算法

    2021-02-08 22:07:32
    微信红包分配算法 public class RedPackageUtil { //设置金额限额 private static final float MINMONEY = 0.01f; private static final float MAXMONEY = 200f; /** * 判断金额是否合法 * @param money 总...
  • fn(离散时间)和时间限制(int),应找到最大输出,即在不同函数之间分配时间以最大化所用函数输出的总和。对于任何函数,任何时候的值表示如果用于所述时间的函数的总输出。 即F(2)=函数的总输出,如果使用2秒。 不是...
  • 概率分析与随机算法

    2021-02-05 20:10:32
    指示随机变量指示随机变量(indicator random variable,IRV)是概率分析中非常重要的一种离散随机变量,其用来表征某事件是否发生。更加具体的,假设事件A发生,变量IRV取值为1,否则取值为0. 数学上表述为: 指示...
  • 红包分配算法

    2021-03-13 04:48:17
    微信红包的分配算法,在知乎上已经有人讨论过了,详见《微信红包的随机算法是怎样实现的?》。基本的原则是:红包分配的钱数满足截尾正态随机数分布。大致为在截尾正态分布中取随机数,并用其求和数除以总价值,获得...
  • 使用一个一维数组来模拟内存储空间,建立内存块来记录内存分配使用情况,通过随机产生进程及其所需要的内存来模拟真实的进程。通过给进程分配内存及回收来实现对动态不等长存储管理方法。 #include "math.h" //#...
  • 分析下问题的实质,分配一个图形的实质就是需要在数组里随机选出几个下标 ,使得这几个下标能够组成所需的图形 ,那么解决方案就很简单了,下面记录下我们需要做的事情: 随机得到数组中任意一点 以此点为轴心,看...
  • 红包金额总是能分完,而且每个人获得的金额都是随机的,那么其中的算法思路是怎样的呢?来看看吧思路1.首先我们要知道红包的总金额大小和红包分发的个数,要随机分完,而且每份加起来要等于总金额,于是可以这样假设...
  • 1.1 随机森林算法随机森林就是通过集成学习的思想将多棵树集成的一种算法,它的基本单元是决策树,每棵决策树都是一个分类器(假设现在针对的是分类问题),那么对于一个输入样本,N棵树会有N个分类结果。而随机...
  • 需求是这样的,根据可变参数 $people 来给每个人随机分配百分比,条件是人数一定会控制在 3 < N < 100,弱条件是尽量保证每个人分配到的比例在 30% 一下,不会出现极值。写了个简单的分配,但会出现最后一个人...
  • Python 抢红包算法模拟

    2021-04-27 06:19:31
    抢红包算法模拟本篇内容为抢随机红包模拟算法,仅供参考。方法本篇使用的是二倍均值法,在此之前,先大概讲下普通随机法。普通随机方法该方法的原理是:每次都以 [最小值,剩余金额值] 之间进行随机取值。假设红包...
  • 红包分配算法代码实现发给大家,祝红包大丰收! #coding=gbkimport randomimport sys#print random.randint(0, 99)#print "====", random.uniform(0, 0.99)def calRandomValue(min, max, total, num):print min, max...
  • 通过这篇文章算是把微信群红包的算法弄明白了 1.前言 因疫情影响,部门 2021 年会以线上直播的形式进行,通过微信小程序展开。为活跃年会氛围,年会直播间会有抢红包环节。因产品要求,红包金额要随机生成,所以...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 176,771
精华内容 70,708
关键字:

随机分配算法