2011-09-17 9 views
4

このプログラムでは、ファイルからファーストネームとラストネームを生成しています。このプログラムを実行すると、3つのテキストボックスに情報を入力します。最初の2つはsalary lowとhigh(salary1.text、salary2.text)で、最後のものは私が望む "copies"(copies.text)の数です。テキストに10などの数字を入れると同じ名前のいくつかを出力します。Vb.net同じ番号を何度も生成する乱数ジェネレータ

firstnameのファイルは約100レコード があり、姓ファイルは、約1000の記録

を持って

なぜそれが同じ名前私は1000枚のような何かをした場合、問題はさらに悪くなる

...それを生成しています10枚のレコードと同じことを8回出力し、別の何かを別の8回

Public Class Form1 

    Dim sex As String 

Function randomfirstname() 
    Dim infile As IO.StreamReader 
    Dim infile1 As IO.StreamReader 
    Dim male() As String 
    Dim female() As String 
    Dim name As String 
    Dim n As Integer = 0 
    Dim fun As New System.Random 
    Dim maleorfemale As New Random() 
    Dim RandomNumber As Integer 
    Dim index As Integer 
    RandomNumber = maleorfemale.Next(0, 55984) 
    infile = IO.File.OpenText("boysnames.txt") 
    infile1 = IO.File.OpenText("girlsnames.txt") 

    If RandomNumber Mod 2 = 0 Then 
     While infile.Peek <> -1 
      ReDim Preserve male(n) 
      male(n) = infile.ReadLine 
      n = n + 1 
     End While 
     n = n - 1 
     index = fun.Next(0, n) 
     name = male(index) 
     sex = "M" 
     n = 0 
     Return name 


    Else 
     While infile1.Peek <> -1 
      ReDim Preserve female(n) 
      female(n) = infile1.ReadLine 
      n = n + 1 
     End While 
     n = n - 1 
     index = fun.Next(0, n) 
     name = female(index) 
     sex = "F" 
     Return name 
     n = 0 
    End If 
End Function 
Function randomlastname() 
    Dim infile2 As IO.StreamReader 
    Dim lname() As String 
    Dim lastname As String 
    Dim n As Integer = 0 
    Dim index As Integer 
    Dim fun As New System.Random 
    infile2 = IO.File.OpenText("lastname.txt") 
    While infile2.Peek <> -1 
     ReDim Preserve lname(n) 
     lname(n) = infile2.ReadLine 
     n = n + 1 
    End While 
    n = n - 1 
    index = fun.Next(0, n) 
    lastname = lname(index) 
    Return lastname 
End Function 
Function salary() 
    Dim salary01 As Double 
    Dim salary02 As Double 
    Dim salary03 As Double 
    salary01 = CDbl(salary1.Text) 
    salary02 = CDbl(salary2.Text) 
    Dim sal As New System.Random 


    salary03 = System.Math.Round(sal.NextDouble() * (salary02 - salary01) + salary01, 2) 
    Return salary03 
End Function 

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 
    'ListBox1.Items.Add(randomfirstname() & vbTab & randomlastname() & vbTab & sex & vbTab & salary()) 
    Dim outfile As New System.IO.StreamWriter("C:\Users\Johnathon\Desktop\486assign1.txt") 
    Dim i As Integer = 0 
    outfile.Write("Firstname" & vbTab & "LastName" & vbTab & "Sex" & vbTab & "Salary" & vbCrLf) 
    outfile.Write("-----------------------------------------------------------------------------" & vbCrLf) 

    For i = 1 To CInt(copies.Text) 
     outfile.Write(randomfirstname() & vbTab & randomlastname() & vbTab & sex & vbTab & salary() & vbCrLf) 
     ListBox1.Items.Add(randomfirstname() & vbTab & randomlastname() & vbTab & sex & vbTab & salary()) 
    Next 
    outfile.Close() 

End Sub 
End Class 

サンプル出力

Firstname LastName Sex Salary 
----------------------------------------------------------------------------- 
Carson Gillespie M 8.46  
Carson Gillespie M 8.46 
Carson Gillespie M 8.46 
Samantha Daniels F 5.84 
Samantha Daniels F 5.84 
Samantha Daniels F 5.84 
Natalia Guthrie F 9.26 
Natalia Guthrie F 9.26 
Natalia Guthrie F 9.26 
Natalia Guthrie F 6.64 
+1

、試験 'IF乱数のMod 2 = 0 'の下位ビットが少ないように擬似乱数生成器のこのタイプで使用する非常に悪いテストでありますより高いビットよりもランダムである。 "' mod 2 = 0' "は最下位ビットをテストし、したがってランダムな結果は最小です。コインフリップ(50%)テストを行うには、「RandomNumber> maxLimit/2」が最適です。 – RBarryYoung

+0

[このNuGetパッケージ](https://github.com/madelson/MedallionUtilities/tree/master/MedallionRandom#medallionrandom)が役立つことがあります。これにより、新しい 'Random'を毎回作成するのではなく、' Random'インスタンスを管理して渡す必要がなく、静的 'Rand.Current'インスタンスを使用することができます。 – ChaseMedallion

答えて

19

あなたは毎回System.Randomの新しいインスタンスを使用しています。 Randomには現在時刻が設定されます。

あなたは非常に立て続けに新しいインスタンスを作成しているので

Reference

時間に依存するデフォルトのシード値を使用すると、彼らは同じシードを取得し、ランダムクラスの新しいインスタンスを初期化します。

代わりに、Randomという同じインスタンスを使用する必要があります。フィールドをフィールド初期化子またはコンストラクタとして初期化することで可能です。例えば:誰かが既に述べシード/タイミングの問題に加え

Public Class Form1 
    Private _random As New System.Random() 

    'Use _random in other methods. 
End Class 
+0

RandomクラスのMSDN記事は、同じシーケンスの数値を返すRandomの2つのインスタンスを示す良い例です。https://msdn.microsoft.com/en-us/library/system.random(v=vs.110) ).aspx?cs-save-lang = 1&cs-lang = vb#code-snippet-2 – ACR

関連する問題