当前位置:   article > 正文

.NET C# 红包生成算法,可设置红包总额和数量,可限制最大最小红包_c# 红包金额随机分配算法

c# 红包金额随机分配算法

原理:割绳子算法:每次都取最大值为总绳长的随机值,最后将其排序,计算每两个的差值,总差值即就是总绳子长度,但是割绳子算法算出来的金额可能会出现超出最大金额的值,那么就会需要使用平均算法。
平均算法(自己取的名字):将超过最大限定金额的值全部重新赋值,并将他们舍去的部分,随机分给最小的金额,并保证最小的金额加上一个值不超过最大值即可。
洗牌算法:最终要将排序的金额进行打乱。

开源是程序员的基本美德

  1.             int pp = 100;//元换算成分的比例
  2.             int total =(int)((decimal)10 * pp);//红包总额 
  3.             int num = 8;//红包个数
  4.             int min = (int)((decimal)0.02 * pp);//红包不少于
  5.             int max = (int)((decimal)2 * pp);//最大红包不超过 
  6.             if (min <= 0 && min >= (total - max) / (num - 1))
  7.             {
  8.                 Console.WriteLine($"红包最小值异常:{total}分{num}个红包,最小值必须大于0,且不能小余{(total - max) / (num - 1)/100f}");
  9.                 return;
  10.             }
  11.             if (num * min > total)
  12.             {
  13.                 Console.WriteLine($"红包最小值异常:{total}分{num}个红包,红包最小值不能超过{total / num / 100f}");
  14.                 return;
  15.             }
  16.             if (num * max < total)
  17.             {
  18.                 Console.WriteLine($"红包最大值异常:{total}分{num}个红包,红包最大值不能小余{total / num / 100f}");
  19.                 return;
  20.             }
  21.             if (max > total - min * (num - 1))
  22.             {
  23.                 Console.WriteLine($"红包最大值异常:{total}分{num}个红包,红包最大值不能超过{(total - min * (num - 1)) / 100f}");
  24.                 return;
  25.             }
  26.             float[] ret = new float[num];
  27.             ret[0] = 0;
  28.             int i = 1;
  29.             //下面不考虑随机数的唯一性,给每个人都预留最少的钱
  30.             int totalByHundred = total - (num * min);
  31.             Random random = new Random();
  32.             while (i < num)
  33.             {
  34.                 ret[i] = random.Next(totalByHundred);
  35.                 i++;
  36.             }
  37.             //先从大到小排序  将差值计算出来+最先预留的min值
  38.             Array.Sort(ret);
  39.             i = 0;
  40.             while (i < num - 1)
  41.             {
  42.                 ret[i] = (ret[i + 1] - ret[i] + min);//每个人都预留最少的钱
  43.                 i++;
  44.             }
  45.             ret[i] = (totalByHundred - ret[i] + min);//最后一个 仍然是最大可分值-自身+min值即可。
  46.             //再次排序金额  将超出最大值的金额 全部重新赋值,并将差值累加给tempmax ,然后将tempmax再依次随机分给最小的金额
  47.             Array.Sort(ret);
  48.             float tempmax = 0;
  49.             for (int k = ret.Length - 1; k >= 0; k--)
  50.             {
  51.                 if (ret[k] > max)
  52.                 {
  53.                     float t = random.Next(min,max);
  54.                     tempmax += ret[k] - t;
  55.                     ret[k] = t;
  56.                 }
  57.                 else
  58.                 {
  59.                     break;
  60.                 }
  61.             }
  62.             //分完为止  可能运气好  没有可分的 
  63.             while (tempmax > 0)
  64.             {
  65.                 Console.WriteLine("触发平均算法执行");
  66.                 Array.Sort(ret);
  67.                 for (int k = 0; k < ret.Length; k++)
  68.                 {
  69.                     //一轮分不完  将再次排序再分  tempmax为0即可
  70.                     if (tempmax > 0)
  71.                     {
  72.                         int tm = max - (int)ret[k];
  73.                         if (tempmax< tm)
  74.                         {
  75.                             //此处判断非常重要 
  76.                             ret[k] = ret[k] + tempmax;
  77.                             tempmax = 0;
  78.                         }
  79.                         else
  80.                         {
  81.                             float t = random.Next(tm);
  82.                             ret[k] = ret[k] + t;
  83.                             tempmax -= t;
  84.                         }
  85.                     }
  86.                     else
  87.                     {
  88.                         break;
  89.                     }
  90.                 }
  91.             }
  92.             //最后利用洗牌算法进行打乱数组
  93.             int currentIndex;
  94.             float tempValue;
  95.             for (int j = 0; j < ret.Length; j++)
  96.             {
  97.                 currentIndex = random.Next(0, ret.Length - j);
  98.                 tempValue = ret[currentIndex];
  99.                 ret[currentIndex] = ret[ret.Length -1- j];
  100.                 ret[ret.Length-1 - j] = tempValue;
  101.             }
  102.             //完美
  103.             for (int j = 0; j < ret.Length; j++)
  104.             {
  105.                 Console.WriteLine($"第{j + 1}个红包:金额{(ret[j] / 100f)}元");
  106.             }
  107.             //最后检查总红包金额以及最大最小红包是否符合要求  肯定符合要求的  只是输出看一下
  108.             Console.WriteLine($"红包总金额:{(ret.Sum() / 100f).ToString("F2")}元,红包最大值:{ret.Max() / 100f}元,红包最小值:{ret.Min() / 100f}元");

该算法由C#写成,更多交流请关注原文博客地址:

红包算法的一种

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/849688
推荐阅读
相关标签
  

闽ICP备14008679号