大家帮我看看,逻辑是否正确.
786人参选,要求选出203人,默认测试10000次,计算5连号出现的概率
checkBoxIncludeHigher默认是选中状态,也就是 出现两个五连号或者出现六连号\七连号等也包括在五连号中.
如果不选中,则计算仅出现一个五连号的概率.
测试次数10000次的话,计算是很快的,但10000次的结果稳定性差一些.如果是10万次的话,要数秒(小于10秒),但稳定性好.我根据概率公式计算应该是86.6%(公式参见天涯杂谈),可是模拟结果确是48.x%,疑惑中,故请教各位高手private void buttonBeginTest_Click(object sender, RoutedEventArgs e)
        {
            int Total=0,Draw=0,N=0,TestTime=0;            try
            {
                Total=int.Parse(txtTotal.Text); //786
                Draw=int.Parse(txtDraw.Text);   //203
                N=int.Parse(txtN.Text);         //5
                TestTime=int.Parse(txtTestTime.Text);  //10000
            }
            catch
            {
                MessageBox.Show("数据输入有错误,请检查");
                return;
            }            if (Draw > Total || N > Draw || N<=0)
            {
                MessageBox.Show("数据输入有错误,请检查");
                return;
            }                        //Now begin test
            int NOccurs = 0;//N连号出现的次数
            Random r = new Random();
            for (int i = 0; i < TestTime; i++)
            {
                //初始化被选数组
                int[] t = new int[Total];
                for (int j = 0; j < Total; j++)
                {
                    t[j] = j + 1;
                }
                int[] d = new int[Draw];
                
                
                //打乱原数组
                for (int j = 1; j < Total; j++)
                {
                    //swap
                    int temp = t[j];
                    int b = r.Next() % (j + 1);
                    t[j] = t[b];
                    t[b] = temp;
                }                //打乱次序后的原数组复制到d中,就是被选出的号
                for (int j = 0; j < Draw; j++)
                {
                    d[j] = t[j];
                }                //d中选出的数从小到大排序
                Array.Sort(d);                //连号测试
                int NTimes = 0;//N连号出现次数
                int NPlusTimes = 0;//N+1连号出现的次数                for (int j = 0; j < Draw - N + 1; j++)
                {
                    if (d[j + N -1] == d[j] + N -1)
                    {   
                        NTimes++;
                        if (NTimes>1)
                            break;
                    }
                }
                
                if(!(bool)checkBoxIncludeHigher.IsChecked)
                    for (int j = 0;j < Draw - N ; j++)
                    {
                        if (d[j + N] == d[j] + N)
                        {
                            NPlusTimes++;
                            break;
                        }
                    }
               
                if ((bool)checkBoxIncludeHigher.IsChecked)
                {
                    if (NTimes > 0) NOccurs++;
                }
                else
                {
                    if (NTimes == 1 && NPlusTimes == 0) NOccurs++;
                }
            }
            lblResult.Content = N.ToString() + "连号出现次数:" + NOccurs.ToString() +
                ",概率=" + (NOccurs / (double)TestTime).ToString("P2") ;
        }        

解决方案 »

  1.   

    应该是Random的原因吧。
    如果连续1万次执行buttonBeginTest_Click,那么产生的随机数很多是连续相同的。
    Random r的实例化最好是在方法体外。
      

  2.   

    IT自学网 http://www.zixueit.com/forum-29-1.html里面含有大量微软的.net视频教程,相信能够对.net爱好者有帮助!
      

  3.   

    原来是我原来想得太简单了,公式是错误的,所以概率没有86.6%那么高.
    实际应该就是48.x%的概率.
    具体计算方法在mathe论坛有一个14连号的计算帖子里有.2楼说的我连续一万次执行这个方法,没有仔细看我的程序,是在方法里for这个循环一万次之前初始化Random.不管怎么说,来我的帖子回复的都给分.