前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C#红包波动系数·高可用性,适合企业级开发

C#红包波动系数·高可用性,适合企业级开发

作者头像
红目香薰
发布2022-11-28 15:55:56
1660
发布2022-11-28 15:55:56
举报
文章被收录于专栏:CSDNToQQCodeCSDNToQQCode

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;

namespace testDemo1 {     /// <summary>     /// 红包算法,波动比例0-1之间     /// </summary>     class Program     {

        static void Main(string[] args) {             Program p = new Program();             //金额分配的时候一定注意总金额与分发数量以及最大金额的合理规划             List<decimal> lists = p.createBonusList(500,500,decimal.Parse("0.01"),10,decimal.Parse("0.5"));             decimal Count = 0;             foreach (var item in lists)             {                 Count += item;                 Console.WriteLine(item);             }             Console.WriteLine("总:"+Count);         }

        Random ra = new Random();

        /// <summary>         /// 生成红包一次分配结果·主要方法入口         /// </summary>         /// <param name="totalBonus">totalBonus</param>         /// <param name="totalNum">totalNum</param>         /// <param name="rdMin"></param>         /// <param name="rdMax"></param>         /// <param name="bigRate">指定大范围区间的概率</param>         /// <returns></returns>         public List<decimal> createBonusList(decimal totalBonus, decimal totalNum, decimal rdMin, decimal rdMax, decimal bigRate)         {             decimal sendedBonus = 0;             decimal sendedNum = 0;             List<decimal> bonusList = new List<decimal>();             while (sendedNum < totalNum)             {                 decimal bonus = randomBonusWithSpecifyBound(totalBonus, totalNum, sendedBonus, sendedNum, rdMin, rdMax, bigRate);                 bonus = Convert.ToDecimal(bonus.ToString("#0.00"));                 bonusList.Add(bonus);                 sendedNum++;                 sendedBonus += bonus;             }             return bonusList;         }

        /// <summary>         /// 随机分配第n个红包         /// </summary>         /// <param name="totalBonus"></param>         /// <param name="totalNum"></param>         /// <param name="sendedBonus"></param>         /// <param name="sendedNum"></param>         /// <param name="rdMin"></param>         /// <param name="rdMax"></param>         /// <param name="bigRate">平衡度0-1</param>         /// <returns></returns>         private decimal randomBonusWithSpecifyBound(decimal totalBonus, decimal totalNum, decimal sendedBonus,         decimal sendedNum, decimal rdMin, decimal rdMax, decimal bigRate)         {             decimal avg = totalBonus / totalNum;  // 平均值             decimal leftLen = avg - rdMin;             decimal rightLen = rdMax - avg;             decimal boundMin = 0, boundMax = 0;

            // 大范围设置小概率             if (leftLen.Equals(rightLen))             {                 boundMin = Math.Max((totalBonus - sendedBonus - (totalNum - sendedNum - 1) * rdMax), rdMin);                 boundMax = Math.Min((totalBonus - sendedBonus - (totalNum - sendedNum - 1) * rdMin), rdMax);             }             else if (rightLen.CompareTo(leftLen) > 0)             {                 // 上限偏离                 decimal standardRdMax = avg + leftLen;  // 右侧对称上限点                 decimal _rdMax = canReward(bigRate) ? rdMax : standardRdMax;                 boundMin = Math.Max((totalBonus - sendedBonus - (totalNum - sendedNum - 1) * standardRdMax), rdMin);                 boundMax = Math.Min((totalBonus - sendedBonus - (totalNum - sendedNum - 1) * rdMin), _rdMax);             }             else             {                 // 下限偏离                 decimal standardRdMin = avg - rightLen;  // 左侧对称下限点                 decimal _rdMin = canReward(bigRate) ? rdMin : standardRdMin;                 boundMin = Math.Max((totalBonus - sendedBonus - (totalNum - sendedNum - 1) * rdMax), _rdMin);                 boundMax = Math.Min((totalBonus - sendedBonus - (totalNum - sendedNum - 1) * standardRdMin), rdMax);             }

            // 已发平均值偏移修正-动态比例             if (boundMin.Equals(boundMax))             {                 return getRandomVal(boundMin, boundMax);             }             decimal currAvg = sendedNum == 0 ? avg : (sendedBonus / sendedNum);  // 当前已发平均值             decimal middle = (boundMin + boundMax) / Convert.ToDecimal(2.0);             decimal subMin = boundMin, subMax = boundMax;             // 期望值              decimal exp = avg - (currAvg - avg) * sendedNum / (totalNum - sendedNum);             if (middle > exp)             {                 subMax = Math.Round((boundMin + exp) / Convert.ToDecimal(2.0));             }             else             {                 subMin = Math.Round((exp + boundMax) / Convert.ToDecimal(2.0));             }             decimal expBound = (boundMin + boundMax) / 2;             decimal expSub = (subMin + subMax) / 2;             decimal subRate = (exp - expBound) / (expSub - expBound);             return getRandomValWithSpecifySubRate(boundMin, boundMax, subMin, subMax, subRate);         }

        /// <summary>         /// 下限随机         /// </summary>         /// <param name="rate"></param>         /// <returns></returns>         private bool canReward(decimal rate)         {             return Convert.ToDecimal(ra.NextDouble().ToString()) <= rate;         }

        /**          * 返回min~max区间内随机数,含min和max          * @param min          * @param max          * @return          */         private decimal getRandomVal(decimal min, decimal max)         {             decimal v = Convert.ToDecimal(ra.NextDouble()) * max;             v = Convert.ToDecimal(v.ToString("#0.00"));             return v >= min ? v : min;         }

        /// <summary>         /// 带概率偏向的随机算法,概率偏向subMin~subMax区间返回boundMin ~boundMax区间内随机数(含boundMin和boundMax),同时可以指定子区间subMin ~subMax的优先概率例:传入参数(10, 50, 20, 30, 0.8),则随机结果有80%概率从20 ~30中随机返回,有20%概率从10 ~50中随机返回         /// </summary>         /// <param name="boundMin"></param>         /// <param name="boundMax"></param>         /// <param name="subMin"></param>         /// <param name="subMax"></param>         /// <param name="subRate"></param>         /// <returns></returns>         private decimal getRandomValWithSpecifySubRate(decimal boundMin, decimal boundMax, decimal subMin, decimal subMax, decimal subRate)         {             if (canReward(subRate))             {                 return getRandomVal(subMin, subMax);             }             return getRandomVal(boundMin, boundMax);         }     } }

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-02-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档