vendredi 15 juin 2018

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




Aucun commentaire:

Enregistrer un commentaire