[VB.net][VB6][VBA]如何確保「亂數序列」的一致性或不一致性
假設我們需要產生n個亂數,通常會寫成函式或類別,然後把n用參數或屬性傳進去。
例如:
Public Class Form1 Private Sub Button1_Click() Handles Button1.Click ListBox1.DataSource = 產生亂數(ComboBox1.Text) MsgBox("ok") ListBox2.DataSource = 產生亂數(ComboBox1.Text) End Sub Function 產生亂數(ByVal n As Integer) As Array Dim tmp(n - 1) As Double Dim ran As New Random For i = 0 To n - 1 tmp(i) = (ran.NextDouble) Next Return tmp End Function
執行起來好像沒什麼問題:
可是如果把程式碼中的 MsgBox() 拿掉就怪怪了...變成兩組順序一樣(雖然在同一個 Group 裡面看它們還都有夠亂)
Public Class Form1 Private Sub Button1_Click() Handles Button1.Click ListBox1.DataSource = 產生亂數(ComboBox1.Text) MsgBox("ok") '----->拿掉這個 ListBox2.DataSource = 產生亂數(ComboBox1.Text) End Sub Function 產生亂數(ByVal n As Integer) As Array Dim tmp(n - 1) As Double Dim ran As New Random For i = 0 To n - 1 tmp(i) = (ran.NextDouble) Next Return tmp End Function End Class
這是因為 Random 的種子無法在極短的時內就發生變異所致(MSDN 的說明 ) 解決方法可用:
- 在兩次初始化 Random 之間插入足以延遲時間的指令,如 Thread.Sleep 或是強制回應的對話框。
- 把 New Random 放到函式外部確保它只被初化一次,例如:
Public Class Form1 Dim ran As New Random '---放到這裡 Private Sub Button1_Click() Handles Button1.Click ListBox1.DataSource = 產生亂數(ComboBox1.Text) ListBox2.DataSource = 產生亂數(ComboBox1.Text) End Sub Function 產生亂數(ByVal n As Integer) As Array Dim tmp(n - 1) As Double For i = 0 To n - 1 tmp(i) = (ran.NextDouble) Next Return tmp End Function End Class
那如果我就是要它們每回都產生一定數量的「固定順序」的亂數集合要怎麼做到?(例如前篇文章的演算法用到的)
- 使用 Micorsoft.VisualBasic 的 Rnd(-1),再配合 Randomize 即可,不過 Rnd 的型別是 Single。
Public Class Form1 Private Sub Button1_Click() Handles Button1.Click ListBox1.DataSource = 產生亂數(ComboBox1.Text) ListBox2.DataSource = 產生亂數(ComboBox1.Text) End Sub Function 產生亂數(ByVal n As Integer) As Array Rnd(-1) : Randomize(1.234) Dim tmp(n - 1) As Double For i = 0 To n - 1 tmp(i) = Rnd() Next Return tmp End Function End Class