【发布时间】:2018-06-15 14:58:02
【问题描述】:
我遇到了一个问题,即在我正在编写的模拟中遇到重复的随机数。这是因为创建Random 的新实例足够快,以至于它们使用相同的种子。据我所知,执行此操作的正确方法是使用 Random 的单个实例,但我不太确定如何执行此操作。
问题是我想在模拟过程中创建许多具有随机初始属性的对象,让它们从不同的分布中随机抽样,并为模拟的每次复制重置对象。根据我使用 VBA 的经验,我只会调用 Rnd() 或引用全局/公共对象;但是,这些选项在这里似乎不可行或不合适。我不确定如何让多个不同类的许多实例都引用Random 的单个实例。
我的代码看起来大多是这样的(虽然如果真的有必要我可以发布一些更完整的东西):
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
我还在 RunSim() 的其他地方使用Random。有没有一种简单的方法可以在整个模拟过程中插入非重复随机数?我见过一些类似的问题,但大多数似乎都专注于洗牌数组或不在 VB.NET 中
【问题讨论】:
-
第一件事,把 Shared 放在那个随机变量上,这样每次创建类时它就不会被实例化
-
@Fredou 谢谢!我在我的变量类中添加了
Shared,现在我返回了不同的结果。但是,我有点担心我在 Variate 之外对Random的其他用途可能不是唯一的。有没有一种方法可以在同一个类之外使用Random的相同实例? -
将我的评论移到一个答案中,同时回答了你的第二个问题