Random的观察

代码一

Imports System.IO
Public Class Form1
     Dim frequency() As Integer = New Integer(6) {}
    Sub DisplayPic(ByVal picdie As PictureBox)
        Dim randomobject As New Random()
        Dim face As Integer = randomobject.Next(1, 7)
        picdie.Image = Image.FromFile(Directory.GetCurrentDirectory & "/images/die" & face & ".png")
        frequency(face) += 1

    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

    End Sub

    Private Sub btnRoll_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRoll.Click
        txtBoxOutput.Text = Nothing
        Dim TOTAL As Double = 0
        txtBoxOutput.Text = "Face" & vbTab & vbTab & "frequency" & vbTab & "Percent" & vbCrLf
        DisplayPic(picBox1)
        DisplayPic(picBox2)
        DisplayPic(picBox3)
        DisplayPic(picBox4)
        DisplayPic(picBox5)
        DisplayPic(picBox6)
        DisplayPic(picBox7)
        DisplayPic(picBox8)
        DisplayPic(picBox9)
        DisplayPic(picBox10)
        DisplayPic(picBox11)
        DisplayPic(picBox12)
        For i As Integer = 1 To frequency.GetUpperBound(0)
            TOTAL = TOTAL + frequency(i)
        Next
        For x As Integer = 1 To 6 Step 1
            txtBoxOutput.Text &= x & vbTab & vbTab & frequency(x) & vbTab & vbTab & String.Format("{0:n}", frequency(x) / TOTAL * 100) & "%" & vbCrLf
        Next
    End Sub
End Class

图8.7gui(1)

代码二

Imports System.IO
Public Class Form1
    Dim randomobject As New Random()
    Dim frequency() As Integer = New Integer(6) {}
    Sub DisplayPic(ByVal picdie As PictureBox)
        Dim face As Integer = randomobject.Next(1, 7)
        picdie.Image = Image.FromFile(Directory.GetCurrentDirectory & "/images/die" & face & ".png")
        frequency(face) += 1

    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

    End Sub

    Private Sub btnRoll_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRoll.Click
        txtBoxOutput.Text = Nothing
        Dim TOTAL As Double = 0
        txtBoxOutput.Text = "Face" & vbTab & vbTab & "frequency" & vbTab & "Percent" & vbCrLf
        DisplayPic(picBox1)
        DisplayPic(picBox2)
        DisplayPic(picBox3)
        DisplayPic(picBox4)
        DisplayPic(picBox5)
        DisplayPic(picBox6)
        DisplayPic(picBox7)
        DisplayPic(picBox8)
        DisplayPic(picBox9)
        DisplayPic(picBox10)
        DisplayPic(picBox11)
        DisplayPic(picBox12)
        For i As Integer = 1 To frequency.GetUpperBound(0)
            TOTAL = TOTAL + frequency(i)
        Next
        For x As Integer = 1 To 6 Step 1
            txtBoxOutput.Text &= x & vbTab & vbTab & frequency(x) & vbTab & vbTab & String.Format("{0:n}", frequency(x) / TOTAL * 100) & "%" & vbCrLf
        Next
    End Sub
End Class

图8.7gui(2)

思考:

比较上面两段代码,唯一的区别就是“Dim randomobject As New Random()”处的位置,代码一位于DisplayPic()方法体内,在代码二中在类中,换句话在代码一种randomobject是局部变量,代码二中是全局变量,从结果中很明确的看出,代码一会导致random(seed)中的seed趋向一致从而产生同样的随机数,代码二则不会导致seed一致,随机数的分布是均匀的。

MSDN上的备注:

伪随机数是以相同的概率从一组有限的数字中选取的。所选数字并不具有完全的随机性,因为它们是用一种确定的数学算法选择的,但是从实用的角度而言,其随机程度已足够了。Random 类的当前实现是基于 Donald E. Knuth 的减随机数生成器算法的。有关更多信息,请参见 D. E. Knuth.“The Art of Computer Programming, volume 2: Seminumerical Algorithms”。Addison-Wesley,Reading,MA,second edition,1981。

随机数的生成是从种子值开始。如果反复使用同一个种子,就会生成相同的数字系列。产生不同序列的一种方法是使种子值与时间相关,从而对于 Random 的每个新实例,都会产生不同的系列。默认情况下,Random 类的无参数构造函数使用系统时钟生成其种子值,而参数化构造函数可根据当前时间的刻度数采用 Int32 值。

但由于时钟分辨率有限,频繁地创建不同的 Random 对象会创建出产生相同随机数序列的随机数生成器。通过创建单个而不是多个 Random 对象可以避免此问题。

要提高性能,请创建一个 Random,以便随着时间的推移可以生成很多随机数,而不要重复新建 Random 来生成一个随机数。

例如,要生成适合于创建随机密码的加密安全随机数,请使用从 System.Security.Cryptography..::.RandomNumberGenerator 派生的类,如 System.Security.Cryptography..::.RNGCryptoServiceProvider

解释:

MSDN备注的红字部分很清楚的说明了代码一为何会产生相同的随机数,代码一在方法体内,每一个方法都会创建一个random对象,从而产生相同随机数。而代码二则在方法外面,只创建一个random对象从而避免了相同随机数的尴尬。所以当创建random对象是一定要把它放在方法体外,也就是使它成为全局变量,只创建一次,这样同时显示的不同方法产生的随机数才是真正的“随机”。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值