我目前正在研究Java中的遗传编程算法。 对于我的实验,我正在尝试几种设置组合,并了解所需的时间,我多次运行每个设置组合,以便我可以取平均值等。
然而,即使我只是有一个带有常量值的随机rng实例作为种子(有时候并不总是不幸),但对于具有相同设置的运行,我会得到不同的结果。
所以,我的问题是,除了在我自己的代码中显式创建新的随机数生成器之外,其他随机源可能是什么呢?
它可能在集合,散列等方式等工作吗?我怎么能让这些工作可预测?
我已经检查了对Collections.shuffle的调用,并使用我的单个Random实例使它们成为种子...
非常感谢任何建议。
有些评论建议发布代码。但是,我并不是在寻求具体的反馈,但我更想知道一般(不受欢迎的)随机性来源。我忘了提到的当然是使用多个线程。
当然,我强行让我的代码运行单线程以防止来自该源的任何随机性
答案 0 :(得分:2)
一旦消除了随机和多线程作为非确定性的来源,接下来要看的是忘记在集合中使用的某个对象上实现hashCode()和equals()。我从来没有使用Random作为任何东西,但我有许多非确定性程序,其恶意行为可以追溯到Object.hashCode()。
答案 1 :(得分:1)
使用java.util.Random生成的随机数序列保证与用于初始化它的任何特定种子相同。来自the API docs:
如果使用相同的种子创建了两个Random实例,那么 为每个方法调用相同的方法调用,它们将生成和 返回相同的数字序列。
所以简短的回答是,只有在改变针对RNG的方法调用的数量或顺序时才会发生这种情况。正如评论中提到的,最可能的解释是您使用RNG有多个线程。在这种情况下,非确定性OS调度显然可能导致调用序列与运行不同。
即使在单线程应用程序中,如果您的应用程序直接或间接地使用任何非严格排序的事件处理程序,也可能发生这种情况。例如,如果您(或您使用的库)使用来自事件处理程序的Random
来处理鼠标,键盘或网络事件,则处理这些事件的非确定性排序可能会改变您生成的数字序列。主线代码。