如题,我现在需要一个抽奖,必须控制概率为1/2,当然,有前置条件的,所以不要问为什么要1/2这么高的概率了~~~我使用的方法是使用随机函数Random的Next(2),并且使用RNGCryptoServiceProvider的GetBytes方法获得种子值,但是BOSS还是说概率有问题,感觉出现较小值的概率高,有没有更完美的方法~~~        /// <summary>
        /// 根据获取抽到的奖品
        /// </summary>
        /// <param name="lotteryRules"></param>
        /// <returns></returns>
        public int GetLotteryPoints(int oldPoints)
        {
            Random random = new Random(GetRandomSeed());            int m = random.Next(2);            if (m == 1)
            {
                return this.MinAward;
            }
            else
            {
                return this.MaxAward;
            }
        }        /// <summary>
        /// 获取随机种子值,防止连续快速取随机数重复问题
        /// </summary>
        /// <returns></returns>
        public static int GetRandomSeed()
        {
            byte[] bytes = new byte[4];
            System.Security.Cryptography.RNGCryptoServiceProvider rng = new System.Security.Cryptography.RNGCryptoServiceProvider();
            rng.GetBytes(bytes);
            return BitConverter.ToInt32(bytes, 0);
        } random概率 抽奖

解决方案 »

  1.   

    不设种子值,直接.Next(2)试试
      

  2.   

    如果不设置种子值,那么Random默认种子和系统时间相关的,连续快速的产生随机数是产生的值就会是同一个~~~
      

  3.   

    如果不设置种子值,那么Random默认种子和系统时间相关的,连续快速的产生随机数是产生的值就会是同一个~~~
    明显不会,除非你每次都new个新的Random
      

  4.   

    什么叫精确1/2的概率,抛硬币算吗?
    先拿出一个实际的模型然后再说怎么解决。根本就没有绝对精确这一说,如果想绝对精确就必须两种结果交替出现,不然都不能叫做绝对精确。
    比如
    1,1,2,1,1,2,1,2,2,2,2,1
    这种结果能叫平均吗?这取决于你在哪一点进行观察,我们取2n(n>0)次的结果观察。
    结果是在2,4,6,8,10,12次的结果分别是,N,N,N,N,F,F。
    你觉得什么叫做精确1/2的概率?
      

  5.   

    如果不设置种子值,那么Random默认种子和系统时间相关的,连续快速的产生随机数是产生的值就会是同一个~~~
    明显不会,除非你每次都new个新的Random呃,是的,抽奖是设置为一个工具类被调用的~~~
      

  6.   

         Private  Random random = new Random(); public int GetLotteryPoints(int oldPoints)
            {
                int m = random.Next(2);
     
                if (m == 1)
                {
                    return this.MinAward;
                }
                else
                {
                    return this.MaxAward;
                }
            }
      

  7.   

    这样试试:
    Random rnd = new Random(BitConverter.ToInt32(Guid.NewGuid().ToByteArray(), 0));
      

  8.   

    和初始化没关系。。to 楼猪
    system.random是一个白噪声的随机发生器,你可以加大随机数区间,比如random.next(0,100),然后以0~50为真,51~100为假,类似这样。。
    至于你boss说的出现小的概率较大,那很显然是你们用的样本不够。。
    我原来刚好试过random,你可以参考一下:System.Random类在极限运算环境下重复生成随机数的对比实验
      

  9.   

    你也没有给出你的 GetRandomSeed 方法的测试!随便写一个最简单的方法的测试好了。using System;
    using System.Linq;namespace ConsoleApplication1
    {    class Program
        {
            static void Main(string[] args)
            {
                for (var i = 1; i < 20; i++)
                    test();
                Console.ReadKey();
            }        static void test()
            {
                var a = Enumerable.Range(0, 1000).Where(x => GetRandom()).Count();
                Console.WriteLine("1000次中有 {0} 次为true,{1}次为false。", a, 1000 - a);
            }        static Random Rnd = new Random();        static bool GetRandom()
            {
                return Rnd.Next(2) != 0;
            }    }}
      

  10.   

    我猜,作为你的BOSS,他可能最为不满的是你整出了GetRandomSeed这种又慢又(看起来)乱的东西,他必须写出测试才能知道“出现较小值的概率高”。你为什么不写一个比较普通的傻瓜化程序呢?为什么要 RNGCryptoServiceProvider 这类东西呢?
      

  11.   

    既然你要精准的1/2,干嘛一定要random呢?可以在random之后,根据目标概率强制他中或不中。 
      

  12.   

    random随机的哪里可能要它概率等于2分之一,只会在这上下浮动吧!
      

  13.   

    建议你自己动手写一个测试,看看 Next(2) 跟 Next(100) 有差别么?
      

  14.   

    static  Random random = new Random(); <-这个要放在外边不能每次调用时都实列化。要不然值一直重复
      public int GetLotteryPoints(int oldPoints)
      {
               int m = random.Next(1,10000);        
                return  m%2==0? this.MinAward:this.MaxAward; 这样就可以了
               
      }
      

  15.   

    一个数组,1000个元素,500个填0,500个填1,然后shuffle。
      

  16.   

    概率这个次,本事就包含不确定性.如果实在想确定那么亲可以这么弄:public string TestRandom(int allNum)
            {
                if (allNum % 2 != 0)
                {
                    throw new ArgumentException("参数allNum必须为偶数!");
                }
                Random random = new Random();
                int numZero = 0;
                int numOne = 0;
                int avgNum = allNum / 2;            for (int i = 0; i < allNum; i++)
                {
                    int num = random.Next(2);
                    if (num == 0)
                    {
                        if (numZero >= avgNum)
                        {
                            ++numOne;
                        }
                        else
                        {
                            ++numZero;
                        }
                    }
                    else
                    {
                        if (numOne >= avgNum)
                        {
                            ++numZero;
                        }
                        else
                        {
                            ++numOne;
                        }
                    }
                }
                return "0:" + numZero + "|1:" + numOne;
            }