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);
        }
    }
}

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

  1. 网站开发和企业级开发有什么区别?

    经常看到Web开发.网站开发.企业级开发,以前很难分清楚它们之前有什么不同?以前也有个说法:Java比较适合企业级开发. 现在经验增加了一点,谈谈我的一点看法. Web开发:www访问的网页.网站,B ...

  2. 为什么使用dojo?dojo与jquery有什么不同?dojo适合什么开发场景?

    首先介绍一下dojo的特性: 1.Dojo是一个符合AMD规范的企业级框架(dojo是一个重量级框架) 2.Dojo全面支持异步加载JS机制(即:支持通过require异步加载JS模块,通过defin ...

  3. Mysql 面向企业级开发(一)

    你需要在企业级开发中了解这些 数据类型 整数类型 实数类型 VARCHAR类型 CHAR类型 DATETIME日期类型 TIMESTAMP时间戳 体系结构 InnoDB存储引擎 存储特性 事务特性 M ...

  4. 如何让NoSQL内存数据库适合企业级应用

    如何让NoSQL内存数据库适合企业级应用 作者:chszs,转载需注明.博客主页:http://blog.csdn.net/chszs 英文原文:How to Make Your In-memory ...

  5. JAVE EE 企业级开发之从零开始学JAVA【51CTO技术论坛】

    http://bbs.51cto.com JAVE EE 企业级开发之从零开始学JAVA         从零开始学JAVA?YES!本刊内容全部为午饭redking整理.撰写,所涉及内容均为原创,非 ...

  6. php和python web开发-php与python谁更适合web开发?为什么?

    就单纯PHP和python比较的话,甚至说是强大的Java(Java的优势是复杂业务逻辑,企业级应用,当然电商领域例如阿里也喜欢)来说,PHP就是为Web而生的!开课通知:php中文网<第10期 ...

  7. php和python哪个用了开发web好-php与python谁更适合web开发?为什么?

    就单纯PHP和python比较的话,甚至说是强大的Java(Java的优势是复杂业务逻辑,企业级应用,当然电商领域例如阿里也喜欢)来说,PHP就是为Web而生的!开课通知:php中文网<第10期 ...

  8. spring5企业级开发实战 pdf_终于总结出Spring全家桶+微服务设计模式+Netty+MySQL调优PDF...

    Spring源码深度解析(2020年1月第二版) Spring是一个源码开放的轻量级Java开发框架,旨在解决业务逻辑层和其他各层的松耦合问题! 自从2003年推出以来,Spring 逐渐发展成为事实 ...

  9. 关于PHP在企业级开发领域的访谈——企业级开发,PHP准备好了吗?

    关于PHP在企业级开发领域的访谈 --企业级开发,PHP准备好了吗? 转自:http://www.nowamagic.net/librarys/veda/detail/256 虽然PHP是Web应用开 ...

最新文章

  1. Spring Cloud(五) Zuul Filter
  2. ChartDirector资料小结
  3. 支持异构图、集成GraphGym,超好用的图神经网络库PyG更新2.0版本
  4. 西固哪家计算机学校好,兰州市西固区有什么技术学校和大学
  5. LeetCode MySQL 1126. 查询活跃业务
  6. 零基础学sql要多久_零基础小白如何迈出学习SQL的第一步?文科生学SQL的心得
  7. leetcode939.MinimumAreaRectangle
  8. STL模型文件修改软件magics 21.0的安装及使用
  9. 2021-2022年数学建模资料汇总——数学模型篇
  10. 联盛德W806+INA226 = 功率计
  11. 重新注册所有dll文件
  12. 基于FPGA的冗余链路高速切换解决方案
  13. java+ElementUI前后端分离旅游项目第二天 旅游管理和自由行
  14. python 定时发送微信,利用python在微信中实现一个定时发送消息的功能
  15. Vue-router:二级路由跳转另一条路由下的子级
  16. zabbix 监控 php-fpm
  17. 01.三节点集群搭建--VM配置
  18. 记录制作音响的青葱岁月
  19. 一款很小巧的桌面窗口隐藏工具
  20. springboot读取bootstrap配置及knife4j版本兼容性问题

热门文章

  1. 万用表怎么测量电池容量_如何使用万用表,使用万用表测量常用的六个方面
  2. c语言case后面多字符,多SWITCH-CASE结构时的C语言对象方式化解
  3. VIM_shortcut_Cheat_sheet
  4. 【Hadoop 分布式部署 五:分布式部署之分发、基本测试及监控】
  5. mysql caching_sha2_password异常分析
  6. Notepad++ 删除空白行的方法(转)
  7. 利用ngnix解决跨域问题
  8. python基础之if、while、for语句
  9. vue组件实现查看大图效果
  10. css3属性:美化表单、点击元素产生的背景与边框怎么去掉,滚动回弹效果