在好例子网,分享、交流、成长!
您当前所在位置:首页Others 开发实例一般编程问题 → C#权重控制随机抽取率

C#权重控制随机抽取率

一般编程问题

下载此实例
  • 开发语言:Others
  • 实例大小:0.17M
  • 下载次数:8
  • 浏览次数:210
  • 发布时间:2021-04-21
  • 实例类别:一般编程问题
  • 发 布 人:123.215489
  • 文件格式:.rar
  • 所需积分:2
 相关标签: 随机 控制 权重

实例介绍

【实例简介】
【实例截图】

【核心代码】

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

namespace RandomExtract
{
    class Program
    {
        static void Main(string[] args)
        {
            PrizeMathRandom a = new PrizeMathRandom();
            a.prizeRandom();

            #region 1000、10000次随机抽取,每次抽取6个
            ////从集合中随机抽取个数
            //const ushort COUNT = 1;
            ////循环次数
            //const int FOR_COUNT = 10000;//10000



            //RandomController rc = new RandomController(COUNT);
            ////累积器
            //Dictionary<char, int> result = new Dictionary<char, int>();
            ////随机数生成器
            //Random rand = new Random();
            ////循环生成随机数
            //for (int i = 0; i < FOR_COUNT; i  )
            //{
            //    //char[] rands = rc.RandomExtract(rand);
            //    char[] rands = rc.ControllerRandomExtract(rand);
            //    for (int j = 0; j < COUNT; j  )
            //    {
            //        char item = rands[j];
            //        if (result.ContainsKey(item))
            //            result[item]  = 1;
            //        else
            //            result.Add(item, 1);
            //    }
            //    // Thread.Sleep(5);
            //}

            ////Console.WriteLine("\t\t出现次数\t占总共出现次数百分比");

            ////foreach (KeyValuePair<char, int> item in result)
            ////{
            ////    Console.WriteLine(item.Key   "\t\t"   item.Value.ToString()   "\t\t"   ((double)item.Value / (double)(FOR_COUNT * COUNT)).ToString("0.00%"));
            ////}


            //Dictionary<char, ushort> items = new Dictionary<char, ushort>();
            //for (int i = 0, j = rc.datas.Count; i < j; i  )
            //{
            //    items.Add(rc.datas[i], rc.weights[i]);
            //}

            //Console.WriteLine("\t\t出现次数\t占总共出现次数百分比\t权值");

            //foreach (KeyValuePair<char, int> item in result)
            //{
            //    Console.WriteLine(item.Key   "\t\t"   item.Value.ToString()   "\t\t"   ((double)item.Value / (double)(FOR_COUNT * COUNT)).ToString("0.00%")   "\t\t\t"   items[item.Key]);
            //}

            #endregion
            Console.ReadLine();
        }
    }






    public class Singleton
    {
        private static Singleton _Singleton = null;
        private static object Singleton_Lock = new object();
        public static Singleton CreateInstance()
        {
            if (_Singleton == null) //双if  lock
            {
                lock (Singleton_Lock)
                {
                    Console.WriteLine("路过。");
                    if (_Singleton == null)
                    {
                        Console.WriteLine("被创建。");
                        _Singleton = new Singleton();
                    }
                }
            }
            return _Singleton;
        }
    }

    public class RandomController
    {
        #region Properties
        private int _Count;
        /// <summary>
        /// 随机抽取个数
        /// </summary>
        public int Count
        {
            get { return _Count; }
            set { _Count = value; }
        }

        #endregion

        #region Member Variables

        /// <summary>
        /// 待随机抽取数据集合
        /// </summary>
        public List<char> datas = new List<char>(
            new char[]{
            'A','B','C','D'//,'E','F',
           // 'G','H','I','J'//,'K'//,'L',
            //'M','N','O','P','Q','R',
            //'S','T','U','V','W','X',
            //'Y','Z'
    });

        /// <summary>
        /// 对应奖项权值
        /// </summary>
        public List<ushort> weights = new List<ushort>(
            new ushort[]{
            //1,2,3,4,5,6,
            7,8,9,10
            //1,1,1,1,1,1,
            //1,1,1,1,1,1,
            //1,1
    });

        #endregion

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="count">随机抽取个数</param>
        public RandomController(ushort count)
        {
            if (count > 26)
                throw new Exception("抽取个数不能超过数据集合大小!!");

            _Count = count;
        }


        #region 普通随机抽取
        /// <summary>
        /// 随机抽取
        /// </summary>
        /// <param name="rand">随机数生成器</param>
        /// <returns></returns>
        public char[] RandomExtract(Random rand)
        {
            List<char> result = new List<char>();
            if (rand != null)
            {
                for (int i = Count; i > 0;)
                {
                    char item = datas[rand.Next(25)];
                    if (result.Contains(item))
                        continue;
                    else
                    {
                        result.Add(item);
                        i--;
                    }
                }
            }
            return result.ToArray();
        }
        #endregion

        #region 受控随机抽取
        /// <summary>
        /// 随机抽取
        /// </summary>
        /// <param name="rand">随机数生成器</param>
        /// <returns></returns>
        public char[] ControllerRandomExtract(Random rand)
        {
            List<char> result = new List<char>();
            if (rand != null)
            {
                //临时变量
                Dictionary<char, int> dict = new Dictionary<char, int>(4);

                //为每个项算一个随机数并乘以相应的权值
                for (int i = datas.Count - 1; i >= 0; i--)
                {
                    dict.Add(datas[i], rand.Next(100) * weights[i]);
                }

                //排序
                List<KeyValuePair<char, int>> listDict = SortByValue(dict);

                //拷贝抽取权值最大的前Count项
                foreach (KeyValuePair<char, int> kvp in listDict.GetRange(0, Count))
                {
                    result.Add(kvp.Key);
                }
            }
            return result.ToArray();
        }
        #endregion

        #region Tools
        /// <summary>
        /// 排序集合
        /// </summary>
        /// <param name="dict"></param>
        /// <returns></returns>
        private List<KeyValuePair<char, int>> SortByValue(Dictionary<char, int> dict)
        {
            List<KeyValuePair<char, int>> list = new List<KeyValuePair<char, int>>();

            if (dict != null)
            {
                list.AddRange(dict);

                list.Sort(
                  delegate (KeyValuePair<char, int> kvp1, KeyValuePair<char, int> kvp2)
                  {
                      return kvp2.Value - kvp1.Value;
                  });
            }
            return list;
        }
        #endregion
    }


    public class PrizeMathRandom
    {

        Random rd = new Random(Guid.NewGuid().GetHashCode());
        public int GetPrizeIndex(List<Prize> prizes)
        {
            int random = -1;
            try
            {
                //计算总权重
                double sumWeight = prizes.Sum(x => x.prize_weight);

                //产生随机数
                double randomNumber;
                randomNumber = rd.NextDouble();

                //根据随机数在所有奖品分布的区域并确定所抽奖品
                double d1 = 0;
                double d2 = 0;
                for (int i = 0; i < prizes.Count; i  )
                {
                    d2  = Convert.ToDouble(prizes[i].prize_weight) / sumWeight;
                    if (i == 0)
                    {
                        d1 = 0;
                    }
                    else
                    {
                        d1  = Convert.ToDouble(prizes[i - 1].prize_weight) / sumWeight;
                    }
                    if (randomNumber >= d1 && randomNumber <= d2)
                    {
                        random = i;
                        break;
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("生成抽奖随机数出错,出错原因:"   e.Message);
            }
            return random;
        }


        public void prizeRandom()
        {
            int i = 0;
            PrizeMathRandom a = new PrizeMathRandom();

            List<Prize> prizes = new List<Prize>() {
               new Prize(){prize_name="奖1",prize_weight=1},
               new Prize(){prize_name="奖2",prize_weight=2},
               new Prize(){prize_name="奖3",prize_weight=4},
               new Prize(){prize_name="奖4",prize_weight=2},
               new Prize(){prize_name="奖5",prize_weight=1}
        };


            int[] result = new int[prizes.Count];
            Console.WriteLine("抽奖开始");
            int count = 50;
            for (i = 1; i <= count; i  )// 打印100个测试概率的准确性
            {
                int selected = GetPrizeIndex(prizes);
                // Console.WriteLine("第"   i   "次抽中的奖品为:"   prizes[selected].prize_name);
                result[selected]  ;
                // Console.WriteLine("--------------------------------");
            }
            Console.WriteLine("抽奖结束");
            Console.WriteLine("总数:"   count   ",每种奖品抽到的数量为:");
            for (int j = 0; j < prizes.Count; j  )
            {
                Console.WriteLine(prizes[j].prize_name   ":"   result[j]   ";权重数:"   prizes[j].prize_weight   "概率:"   result[j] * 1.0 / count);

            }
        }
    }

    public class Prize
    {
        public int id;//奖品id
        public String prize_name;//奖品名称
        public int prize_amount;//奖品(剩余)数量
        public int prize_weight;//奖品权重
                                //getter、setter
    }




}


标签: 随机 控制 权重

网友评论

发表评论

(您的评论需要经过审核才能显示)

查看所有0条评论>>

小贴士

感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。

  • 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
  • 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
  • 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
  • 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。

关于好例子网

本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明

;
报警