微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c# – 如何设计Random.Next()限制?

假设我有一个具有10个属性的对象,所有属性都是从基于System.Random的算法中随机生成的,使用预先确定的种子,例如:

System.Random randomNumber = new System.Random(seed);
int prop0 = randomNumber.Next(x0, y0);
int prop1 = randomNumber.Next(x1, y1);
//...
int prop9 = randomNumber.Next(x9, y9);

这一切都很好,直到我决定删除1个属性.假设它是我调用Next()的第一个属性,现在所有结果都因调用序列的移位而发生变化.

>如果我想维护其他属性的结果怎么办?
>我只生成一个属性并丢弃它吗?
>我今后如何才能最好地解决这个问题,以便更新我的属性列表更容易?

解决方法:

最明显的解决方案是生成随机值,但忽略它的结果.

另一种选择是完全摆脱Random并使用不同的随机生成算法.我想象的是具有函数f(种子,值),它返回基于种子和值的“伪随机”值,但是它是可重复的.

这样,每个属性都将具有与之关联的值,并且它的随机等价物将独立于其他值的随机等价物.

我在here之后做出的算法可以用作这样的函数.如果您只使用x值,并将最后一行更改为from和to而不是0到3,则可以使用它:

int prop0 = RandomX.Generate(seed, 0x45F6C854, x0, y0);
int prop1 = RandomX.Generate(seed, 0x96F4DC41, x1, y1);
//...
int prop9 = RandomX.Generate(seed, 0xFE840301, x9, y9);

因此,如果您删除添加属性,它将不会影响其他人.如果您在整个代码生成数字,这也有效,因此您不必密切关注每个值的生成.

或者你可以使用类似的东西

int prop0 = RandomX.Generate(globalSeed, objectSeed, propertySeed, from, to);

3种子的组合将产生从…到…的“伪随机”值

Generate算法可能看起来像:

public static uint bitRotate(uint x)
{
    const int bits = 16;
    return (x << bits) | (x >> (32 - bits));
}

public static UInt32 Generate(int seed1, int seed2, int seed3)
{
    // simple "hashing" algorithm
    UInt32 num = 1;
    for (uint i = 0; i < 16; i++)
    {
        // multiply by prime numbers
        num = num * 119 + (uint)seed1;
        num = bitRotate(num);
        num = num * 541 + (uint)seed2;
        num = bitRotate(num);
        num = num * 809 + (uint)seed3;
        num = bitRotate(num);
        num = num * 673 + (uint)i; // not sure if necessary
        num = bitRotate(num);
    }
    return num;
}

只需将完整uint范围编号的转换添加到..到范围.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐