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;
                //}
            }
        }
    }
  • 相关阅读:
    Windows性能计数器应用
    Azure Oracle Linux VNC 配置
    Azure 配置管理系列 Oracle Linux (PART6)
    Azure 配置管理系列 Oracle Linux (PART5)
    Azure 配置管理系列 Oracle Linux (PART4)
    Azure 配置管理系列 Oracle Linux (PART3)
    Azure 配置管理系列 Oracle Linux (PART2)
    vagrant多节点配置
    docker基本操作
    LINUX开启允许对外访问的网络端口命令
  • 原文地址:https://www.cnblogs.com/iammackong/p/3528206.html
Copyright © 2011-2022 走看看