Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
194 views
in Technique[技术] by (71.8m points)

vb.net - How do I ensure unique random numbers are used in a simulation?

I'm having an issue where I'm encountering repeated random numbers in a simulation I'm writing. This is due to creating new instances of Random quickly enough that they use the same seed. From what I can find, the proper way to do this is to use a single instance of Random, but I'm not quite sure how to do this.

The issue is that I want to create many objects with random initial attributes during the simulation, have them sample randomly from different distributions, and reset the objects for each replication of the simulation. From my experience with VBA I would just call Rnd() or refer to a global/public object; however, those options don't seem feasible or appropriate here. I'm not sure how I would go about getting many instances of multiple different classes to all refer to a single instance of Random.

My code looks mostly like this (though I can post something more complete if really necessary):

Sub RunSim()

    Dim Unit() as SimClass
    Redim Unit(NumberOfObjects)

    For n = 1 To Replications

        For i = 0 To NumberOfObjects
            Unit(i) = New SimClass
        Next

        For j = 1 to ProcessSteps
            For i = 0 To NumberOfObjects
                Unit(i).Process(Dist(j),P1(j),P2(j)) 'These are dist/parameter arrays
            Next
        Next

        Combine(Unit(i), NumberOfObjects)   'This condenses my objects to unit(0), part of my simulated system

        File.Write(Unit(0).GetAtts)     'This combines/returns Unit(0)'s attributes

    Next

End Sub

Public Class SimClass

    Private x, y, z, Parameter1, Parameter2 As Double
    Private avg As Double = 50
    Private std As Double = 5
    Private Dist As String

    Public Sub New
        SetX()
        SetY()
        SetZ()
        SetDist()
    End Sub

    Public Sub SetX()
        Dim Var as new Variate(Dist, avg, std)
        Me.x = Var.Draw
    End Sub

    'y, z, setters are similar

    Public Sub Process(Name, P1, P2)

        Dim Var as New Variate(Dist, Parameter1, Parameter2)

        Me.x = Me.x * Var.Draw
        'etc. y and z

    End Sub

End Class

Public Class Variate

    Private P1,P2 As Double
    Private Dist As String
    Private Rnd As New Random

    Public Sub New(Name As String, Par1 as Double, Par2 As Double)

        Dist = Name
        P1 = Par1
        P2 = Par2

    End Sub

    Public Function Draw

        Select Case Me.Dist.ToUppeer
            Case "NORM"
                Draw = NormalRV(P1, P2)
            Case Else
                'etc
            End Select

    End Function

    Private Function NormalRV()

        'Return random sample from a normal distribution with given parameters
        'Relies on Rnd.NextDouble()

    End Function

I also use Random elsewhere in RunSim(). Is there a simple way to insert non-repeating random numbers throughout my simulation? I've seen somewhat similar questions, but most seem focused on shuffling arrays or aren't in VB.NET

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

First thing, put Shared on that random variable so it wont be instantiated every time you create a class.

if you want to reuse it in other place, you should create a module that contain a public propriety returning the random object and/or values (google the term: singleton)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...