zoukankan      html  css  js  c++  java
  • 获取相同概率随机数的算法

    各位,引用请指明出处,尊重劳动成果!!!

    这几天在做公司年会的一个抽奖软件,开始做的的时候,认为算法是很简单的,把员工的数据放进list里,把list的标号作为需要获取的随机数,根据得到的随机数就确定是谁中奖。后来测试发现,随机数的分布是非常不均匀的。后来才知道,原来计算机获取的随机数都是伪随机数,当抽奖的速度非常快的时候,获取的随机数是非常不均匀的,所以在每次抽奖的时候要添加延时。后来重新设计算法,最终实现了。

    算法原理跟二分查找的过程有点像。一枚硬币抽中正、反面的概率是一样,当抽样的次数无限增多,抽中的概率是50%。

    代码如下:

    public partial class MainWindow : Window
        {
            string s;
            int number;
            public MainWindow()
            {
                InitializeComponent();
            }
            public int getRandom()
            {
                //string[] arr = new string[5] { "我们", "是", "一", "个","团队" };
    
                Random r = new Random();
                int num = 2;
                int choose = r.Next(num);
                return choose;
                //MessageBox.Show(arr[choose].ToString());
            }
            public string GRandom(int n)
            {
                //if()
                if (n == 0)
                {
                    //s = getRandom() + s;
                    //System.Threading.Thread.Sleep(1);
                    return s;
                }
                if (n % 2 == 0)
                {
                    n = n / 2;
    
                }
                else
                {
                    n = (n - 1) / 2;
                    //s = getRandom() + s;
                }
                s = getRandom() + s;
                System.Threading.Thread.Sleep(20);
                GRandom(n);
                //System.Threading.Thread.Sleep(1);
                return s;
            }
            public Int32 Estimate(int n)
            {
                string num = GRandom(n);
                number = Convert.ToInt32(num, 2);
                if (number > n - 1)
                {
                    //num = "";
                    s = "";
                    Estimate(n);
                }
                //else
                return number;
            }
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                for (int i = 0; i < 100; i++)
                {
                    label1.Content += Estimate(200) + ";";
                    s = "";
                }
            }
        }

    以上算法不是非常好,取消延时,将random对象设置为全局变量。修改版代码如下: 

            string s;
            int number;
            Random r = new Random();
            
            public int getRandom()
            {
                //string[] arr = new string[5] { "我们", "是", "一", "个","团队" };
    
                //Random r = new Random();
                int num = 2;
                int choose = r.Next(num);
                return choose;
                //MessageBox.Show(arr[choose].ToString());
            }
            public string GRandom(int n)
            {
                //if()
                if (n == 0)
                {
                    //s = getRandom() + s;
                    //System.Threading.Thread.Sleep(1);
                    return s;
                }
                if (n % 2 == 0)
                {
                    n = n / 2;
    
                }
                else
                {
                    n = (n - 1) / 2;
                    //s = getRandom() + s;
                }
                s = getRandom() + s;
                GRandom(n);
                
                return s;
            }
            public Int32 Estimate(int n)
            {
                string num = GRandom(n);
                number = Convert.ToInt32(num, 2);
                if (number > n - 1)
                {
                    //num = "";
                    s = "";
                    Estimate(n);
                }
                //else
                return number;
            }
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                for (int i = 0; i < 1000; i++)
                {
                    label1.Content = Estimate(200);
                    s = "";
                }
                
            //以下为测试
                //int a = 0, b = 0, c = 0, d = 0, f = 0;
                //for (int i = 0; i < 1000; i++)
                //{
                //    //label1.Content = Estimate(2);
                //    int content = Estimate(5);
                //    s = "";
                    
                //    switch (content)
                //    {
                //        case 0:
                //            a ++;
                //            break;
                //        case 1:
                //            b ++; 
                //            break;
                //        case 2:
                //            c ++;
                //            break;
                //        case 3:
                //            d ++;
                //            break;
                //        case 4:
                //            f ++;
                //            break;
    
                //    }
                //    label1.Content = a;
                //    label2.Content = b;
                //    label3.Content = c;
                //    label4.Content = d;
                //    label5.Content = f;
                //}
            }
        }
    }
  • 相关阅读:
    .net 自带的两个内置委托
    Socket
    SQL EXISTS与IN的区别(2)
    一个选择题,写了一个类
    SQL Server- 存储过程(2)
    VS插件-JSEnhancements
    SQL Server- 存储过程(1)
    MVC-工作原理
    C#-属性
    SQL Server 中游标的使用
  • 原文地址:https://www.cnblogs.com/iammackong/p/3528206.html
Copyright © 2011-2022 走看看