使用 System.DateTime.Now.Ticks 作为种子值

本文关键字:种子 Ticks System DateTime Now 使用 | 更新日期: 2023-09-27 18:31:37

>我已经启动了一个无线传感器网络模拟代码,但我不明白seed的含义以及以下方法中System.DateTime.Now.Ticks的返回值是什么。

public void Reset(bool bNewSeed) {
    // this function resets the network so that a new simulation can be run - can either be reset with a new seed, or with the previous seed (for replay.)
    this.iProcessTime = 0;
    this.iPacketsDelivered = 0;
    foreach (WirelessSensor sensor in aSensors) {
        sensor.iResidualEnergy = sensor.iInitialEnergy;
        sensor.aPackets = new ArrayList();
        sensor.iSensorRadius = iSensorRadius;
        sensor.iSensorDelay = 0;
        foreach (WirelessSensorConnection connection in sensor.aConnections) {
            connection.iTransmitting = 0;
            connection.packet = null;
        }
    }
    aRadar = new ArrayList();
    if (bDirectedRouting == true)
        SetRoutingInformation();
    iLastUpdated = iUpdateDelay;
    if (bNewSeed == true)
        this.iSeed = (int) System.DateTime.Now.Ticks;
    r = new Random(iSeed);
}

使用 System.DateTime.Now.Ticks 作为种子值

DateTime.Now.Ticks返回一个long,表示该实例中的刻度数。

通过向Random实例提供种子值,可以指定用于计算伪随机数规则起始值的数字。

因此,如果您有 2 个具有相同种子的 Random 实例,它们将生成相同的值,例如:

var randomOne = new Random(1);
var randomTwo = new Random(1);
var valOne = randomOne.Next(1, 1000);
var valTwo = randomTwo.Next(1, 1000);
valOne.Equals(valTwo); // True

因此,为了使随机实例more random可以使用一个不太可能可预测的值,在您的情况下,DateTime实例上的即时报价数量,例如

var random = new Random((int)DateTime.UtcNow.Ticks);

或者更好的方法是:

var random = new Random(Guid.NewGuid().GetHashCode());

Random类是一个伪随机数生成器

[which] 是一种用于生成数字序列的算法,其属性近似于随机数序列的属性。PRNG生成的序列并不是真正随机的,因为它完全由一组相对较小的初始值决定,称为PRNG的种子

如果使用接受种子的构造函数创建 Random 实例,则始终会获得相同的随机数序列。这可能非常有用,因为它允许您对需要随机数的计算进行确定性模拟。

但是,您通常需要每次执行代码时都不同的随机数。这就是代码使用依赖于当前时间的种子的原因。bNewSeed 变量的目的是保持 Random 实例可能使用已知种子进行种子设定,允许使用相同的数字序列重新运行模拟,或者使用"随机"种子创建新的Random实例。结果将是一个新的模拟。

但是,您不必提供自己的"随机"种子。如果使用默认构造函数构造Random实例,则算法将使用Environment.TickCount设定

种子,这些每次执行时很可能不同。

此外,DateTime.Now是一项相对昂贵的操作,必须考虑本地时区来计算当前本地时间。这在您的代码中可能无关紧要,但总的来说,我强烈建议使用 DateTime.UtcNow 并且只在需要时进行任何时区转换。在您的情况下,您根本不关心时区。

创建一个简单的控制台应用,该应用使用 Random 对象在控制台上打印一些数字。创建没有种子值的随机对象。现在启动程序 10 次并观察正在生成哪些数字;)然后给它一个常量种子值,如 123 并再次观察。然后给它一个DateTime.Now.Ticks的种子。

即时报价是不断变化的东西,因此您可以最大限度地减少再次生成相同"随机"数字序列的机会。